[빅분기] 빅데이터 분석기사 3유형 벼락치기 요약 정리

모듈 및 함수 불러오기

  • scipy.stats T-test(단일표본 ttest_1samp, 독립표본 ttest_ind, 대응표본 ttest_rel), 카이제곱검정(chi2_contingency 독립성검정, chisquare 적합도 검정), ANOVA(다원분산분석은 statsmodel이 더 좋음)비모수검정, 정규성검정, 등분산검정
  • statsmodels.api
  • numpy
import statmodels.api as sm
import numpy as np
from statmodels.api as Logit
from scipy.stats import chi2_contingency

 

생각이 안 날때는 help(), dir() 활용

 

⭐️ 로지스틱 회귀분석

import statmodels.api as sm
from statmodels.api import Logit
from statsmodels.api import Logit
from sklearn.preprocessing import LabelEncoder
import statmodels.api as sm
 
# 범주형 -> 수치형 변환
encoder = LabelEncoder()
df["Gender"] = encoder.fit_transform(df["Gender"])
 
# 독립변수, 종속변수 정의
X = df[["Gender", "SibSp", "Parch", "Fare"]] # 독립변수
X = sm.add_constant(X) # 독립변수에 상수항(절편) 추가
y = df["Survived"] # 종속변수

# 로지스틱 회귀모델 적합
model = Logit(Y, X).fit() # 종속변수, 독립변수 순으로

# 결과 출력
print(model.summary())

⭐️ 단순회귀/ 다중회귀 (선형)

 

다중회귀 예시 ↔ OLS를 Logit으로 바꾸면 로지스틱 회귀 분석 가능

단순/다중 회귀분석과 로지스틱 회귀의 차이점은 독립변수는 둘다 수치형이지만, 종속변수가 단순/다중 회귀분석은 수치형이고 로지스틱 회귀분석은 범주형이다.

from statsmodels.api import OLS
from sklearn.preprocessing import LabelEncoder
import statmodels.api as sm
 
# 범주형 -> 수치형 변환
encoder = LabelEncoder()
df["Gender"] = encoder.fit_transform(df["Gender"])
 
# 독립변수, 종속변수 정의
X = df[["Gender", "SibSp", "Parch", "Fare"]] # 독립변수
X = sm.add_constant(X) # 독립변수에 상수항(절편) 추가
y = df["Y"] # 종속변수

# OLS 회귀모델 적합
model = OLS(Y, X).fit() # 종속변수, 독립변수 순으로

# 결과 출력
print(model.summary())

# 새로운 데이터에 대한 예측
prediction = model.predict([1, 6, 7])
print("\n새로운 데이터에 대한 예측값", prediction)

 

formula 사용해서 적합★

from statmodels.api import OLS
 
formula = "Y ~ Gender + SibSp + Parch + Fare"
# 다중 회귀에서 독립변수(설명변수 길때)
# formula = "Y ~ " + "+".join([col for col in df.columns if col != "Y"]) 
model = OLS.from_formula(formula, df).fit()
print(model.summary())

summary 확인

  • p-value
  • 결정계수(R-squared)
  • 수정된결정계수(Adj.R-squared)
  • 회귀계수(coef)
  • 우도(Likelihood)
  • AIB, BIC 등등

잔차이탈도 -2 * model.llf

# Logit으로
residual_deviance = -2 * model.llf
print(residual_deviance)

# GLM으로
model2 = sm.GLM(y, x_train, family=sm.families.Binomial()).fit()
residual_deviance = model2.deviance
print(residual_deviance)

로지스틱 회귀, GLM에서 물어봄

GLM은 서머리에서 확인 가능

 

params

model.params["v2"] # 특정 컬럼의 회귀계수

model.pvalues.max() # pvalue값 중 최대

 

오즈비 구하기 (성공할확률/성공하지못할확률)

- 오즈의 변화량 (변화/기존)

import numpy as np
 
print(np.exp(model.params["SibSp"]))
# print(np.exp(-0.3539))


# 만약 age 변수가 5단위 증가하면 오즈비는 몇 배 증가? 
result = np.exp(5* model.params["age"])

 

t-검정

from scipy.stats import ttest_1samp, ttest_ind, ttest_rel

 

t- 검정은 단일, 독립, 대응 3가지 유형이 있다.

  • 단일 표본 t-검정은 한 그룹의 평균을 특정 값과 비교 stats.ttest_1samp(집단, 특정값, alternative="greater")
  • 독립 표본 t-검정은 두 독립적 그룹의 평균을 서로 비교 stats.ttest_ind(B, A)
  • 대응 표본 t-검정은 두 관련된 그룹의 평균을 서로 비교 stats.ttest_rel(B, A, alternative="greater")

t-검정 모집단 그룹 크기가 30이하 일때, 

같은 개체에 대해서

한 그룹을 두 집단으로 나누어 비교 하는 경우 대응 표본,

다른 그룹끼리 비교하는 경우 독립 표본,

한 집단만 가지고 특정 값(평균 등)을 비교하는 경우 단일 표본

 

단일 표본 t-검정 ttest-1samp 문제 예시

22명의 학생들이 국어 시험에서 받은 점수이다. 학생들의 평균이 75보다 크다고 할 수 있는가?

검정통계량, p-value, 검정결과를 출력하시오.

  • 귀무가설(H0): 모평균은 mu와 같다. (μ = mu), 학생들의 평균은 75이다
  • 대립가설(H1): 모평균은 mu보다 크다. (μ > mu), 학생들의 평균은 75보다 크다
# 단일표본 한 집단 특정 값 기준비교, ttest_1samp
# 독립표본 같은 집단 다른 조건 2, ttest_ind
# 대응표본 다른 집단 2, ttest_rel

from scipy.stats import ttest_1samp

# 귀무가설 H0 학생들의 평균은 75이다
# 대립가설 H1 학생들의 평균은 75보다 크다 (내가 알고싶은 가설)

# 데이터
scores = [75, 80, 68, 72, 77, 82, 81, 79, 70, 74, 76, 78, 81, 73, 81, 78, 75, 72, 74, 79, 78, 79]

# 모평균 가설검정
popmn = 75 # 검정할 모평균
alpha = 0.05 # 유의수준

# t-test 가설 검정
print(ttest_1samp(scores, popmn, alternative ="greater"))

  • 검정통계량(statistic) t = 1.7659, p-value = 0.04598로 P-값은 유의수준(alpha) 0.05보다 작다.  귀무가설 기각
  • 학생들의 평균은 75보다 크다

출처 https://www.kaggle.com/code/agileteam/t3-ttest-1samp/notebook

 

독립 표본 t-검정 ttest-ind 문제 예시

어떤 특정 약물을 복용한 사람들의 평균체온이 복용하지 않은 사람들의 평균 체온과 유의미하게 다른지 검정해보기.

  • 귀무가설(HO): 약물을 복용한 그룹과 복용하지 않은 그룹의 평균 체온은 유의미한 차이가 없다.
  • 대립가설(H1): 약물을 복용한 그룹과 복용하지 않은 그룹의 평균 체온은 유의미한 차이가 있다.

검정통계량, p-value, 검정결과를 출력하시오.

from scipy.stats import ttest_ind

# 데이터 수집
group1 = [36.8, 36.7, 37.1, 36.9, 37.2, 36.8, 36.9, 37.1, 36.7, 37.1]
group2 = [36.5, 36.6, 36.3, 36.6, 36.9, 36.7, 36.7, 36.8, 36.5, 36.7]

# 가설검정
print(ttest_ind(group1, group2))
t_statistic, p_value = ttest_ind(group1, group2)

# 유의성 검정
alpha = 0.05 # 유의수준 설정

if p_value < alpha:
    print("귀무가설을 기각")
else:
    print("귀무가설을 채택")

  • 검정통계량(statistic) t = 3.7964, p-value = 0.001321로 P-값은 유의수준(alpha) 0.05보다 작다.  귀무가설 기각
  • 약물을 복용한 그룹과 복용하지 않은 그룹의 평균 체온은 유의미한 차이가 있다.

출처 https://www.kaggle.com/code/agileteam/t3-ttest-ind

 

대립 표본 t-검정 ttest-rel 문제 예시

데이터는 고혈압 환자 치료 전후의 혈압이다. 해당 치료가 효과가 있는지 대응표본 t-검정을 진행하시오.

  • 귀무가설(H0): μ >= 0
  • 대립가설(H1): μ < 0
  • μ = (치료 후 혈압 - 치료 전 혈압)의 평균
  • 유의수준: 0.05
  1. μ의 표본평균은?(소수 둘째자리까지 반올림)
  2. 검정통계량 값은?(소수 넷째자리까지 반올림)
  3. p-값은?(소수 넷째자리까지 반올림)
  4. 가설검정의 결과는? (유의수준 5%)
from scipy.stats import ttest_rel

# 1
df['diff'] = df['bp_post'] - df['bp_pre']
print(round(df['diff'].mean(),2))

# 가설검정
st, pv = stats.ttest_rel(df['bp_post'], df['bp_pre'], alternative="less")

# 2
print(round(st,4))

# 3
print(round(pv,4))

# 4 
# 유의수준 0.05보다 p-value값이 작으므로 귀무가설 기각, 대립가설 채택

 

출처 https://www.kaggle.com/code/agileteam/t3-example/notebook

 

분산분석 (ANOVA)

f_oneway

카이제곱검정

  • 독립성 검정 chi2_contingency -분류, 두 그룹이 같은지 다른지
  • 적합도 검정 두그룹 이상 chisquere(실제빈도값, 기대빈도값)

chi2_contigency 는 교차표가 필요(index, columns)

pd.crosstab을 이용해서 교차표를 가져와야 함.

from scipy.stats import chi2_contingency
table = pd.crosstab(df["Gender"], df["Survived"])
print(table) # 빈도수에 대한 교차표 생성

statistics, p, df, expected = chi2_contingency(table)
# 검정통계량, p-value값, 자유도, 예상빈도테이블
print(round(statistics,3))
import numpy as np
from scipy.stats import chi2_contingency # 독립성검정
data = np.array([[smoke_male, non_smoke_male], [smoke_female, non_smoke_female]])
chi2_stat, p_val, dof, expected = chi2_contingency(data)

from scipy.stats import chisquare # 적합도 분석

상관계수

문제 예시) 선형관계가 가장 큰 변수를 찾아 상관계수를 구해라

판다스 corr 사용

cond = df.corr().unstack()
print(cond[cond != 1])
cond = df.corr()["Target"].sort_values().index[-2]
print(cond)

정규성 검정

  • 샤피로 검정: 표본 크기 50이하 
  • anderson, kstest: 표본 크기 50 이하

크루스칼-왈리스 검정

  • 귀무가설: 세 그룹의 중앙값은 동일하다.
  • 대립가설: 세 그룹 중 적어도 하나의 중앙값이 다르다.
from scipy.stats import kruskal
a = df[df.ID =='A'].value.values
b = df[df.ID =='B'].value.values
c = df[df.ID =='C'].value.values

s,p = kruskal(a,b,c)
# s = 검정통계량, p = p-value

베르누이분포, 이항분포, 포아송분포

from scipy.stats import binom 이항분포

binom.cdf(k-1, n, p)

적어도 나오면 1 - binom.cdf(k-1, n, p)

from scipy.stats import binom

n = 21
p = 0.7
k = 16

# P(X < k) 계산
prob = binom.cdf(k-1, n, p)
print(round(prob, 3))

# 적어도
from scipy.stats import binom

n = 21
p = 0.7
k = 19

# P(X >= k) 계산
prob = 1 - binom.cdf(k-1, n, p)
print(round(prob, 3))

표준화 Z-Score

표준화 (X - 평균mean()) / 표준편차std(ddof=0) # ddof=0 모집단, ddof=1 표본

  • (p_hat - p): 샘플 비율과 모집단 비율의 차이.
  • np.sqrt(p * (1 - p) / n): 표본 비율의 표준 오차.
  • z값(검정통계량) = (p_hat - p) / np.sqrt(p * (1 - p) / n): 비율 차이를 표준 오차로 나누어서 z-값을 계산합니다
  • p-value = 1- norm.cdf(z)
import numpy as np

# 예시 데이터
p_hat = 0.55  # 표본 비율
p = 0.5  # 모집단 비율 (귀무가설)
n = 100  # 표본 크기

# z-검정 통계량 계산
z = round((p_hat - p) / np.sqrt(p * (1 - p) / n), 5)

print("검정 통계량 (z-value):", z)


# 검정통계량으로 p-value구하기

from scipy.stats import norm

print(round(1-norm.cdf(z),3)) # norm.cdf(z)는 z보다 작거나 같은 값이 나올 확률

t값, t분포(양측검정)

# t값, t분포 구하기

from scipy.stats import t

n = len(df["height"]) # 샘플크기
confidence_level = 0.95 # 신뢰구간
ddof = n-1 #자유도

# 양측검정
t.ppf((1+confidence_level)/2, ddof)
# 단측검정
t.ppf(1+confidence_level, ddof)
# 가장 큰 표준화 점수 구하기(Z-Score)
from scipy.stats import zscore
result = zscore(df[sub].dropna()).max()

95% 신뢰구간 산출

t값 표준오차와 표본평균 사이의 차이 비율

t_value = t.ppf((1+신뢰구간)/2, 자유도)  양측

t_value = t.ppf((1+신뢰구간), 자유도) 단측

 

신뢰구간

lower = mean - t_value* std  /np.sqrt(n)

upper = mean + t_value*std / np.sqrt(n)

 

# t 값 계산
confidence_level = 0.95 # 신뢰구간
n # 샘플크기
ddof = n-1 # 자유도

t_value = t.ppf((1 + confidence_level) /ddof, n) # 양측검정 t값

# 신뢰구간 계산
upper = round(mean + t_value * std / np.sqrt(n), 3)
lower = round(mean - t_value * std / np.sqrt(n), 3)
print(lower, upper)

 

참고

https://velog.io/@ksolar03/%EC%A0%9C-3%EC%9C%A0%ED%98%95-%EB%8C%80%EB%B9%84-%EC%A0%95%EB%A6%AC