모듈 및 함수 불러오기
- 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
- μ의 표본평균은?(소수 둘째자리까지 반올림)
- 검정통계량 값은?(소수 넷째자리까지 반올림)
- p-값은?(소수 넷째자리까지 반올림)
- 가설검정의 결과는? (유의수준 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
'사이언스' 카테고리의 다른 글
| [빅분기] 데이터 전처리 정리 (0) | 2024.12.26 |
|---|---|
| [빅분기] 빅데이터 분석기사 2유형 템플릿 (1) | 2024.11.28 |
| [빅분기] 빅데이터 분석기사 실기 3유형 테스트 문제풀이 (0) | 2024.11.26 |
| Pandas axis=1 뜻 with df.drop 함수 (0) | 2024.11.23 |
| Pandas TypeError: agg function failed 해결 with select_dtypes (1) | 2024.11.23 |