실습 코드 :
7-1: https://colab.research.google.com/drive/1mQ3R_28n2teboJ3u9ON2JarYSlHEh7We?usp=sharing
7-2 : https://colab.research.google.com/drive/1JB55px7AMgm6sOjB9NqZh3BQu14su8QM?usp=sharing
분석하려는 전체 데이터의 수집이 어려울 때 '샘플(표본)'데이터 수집을 통해 모집단의 특성을 추론하고 검증 할 수 있다.
데이터가 정규분포를 따른다는 가정 하에 각 값이 평균에서 떨어진 정도를 표현.
- x: 정상화되는 원수치.
- σ: 모집단에서의 표준편차.
- μ: 모집단에서의 평균.
import numpy as np
x = [0, 3, 5, 7, 10]
s = np.std(x)
m = np.mean(x)
z = (7 - m) / s
print(z)
> 0.5872202195147035
from scipy import stats
stats.zscore(x)
> array([-1.46805055, -0.58722022, 0. , 0.58722022, 1.46805055])
stats.norm.cdf(0)
> 0.5
stats.norm.cdf(1.0) - stats.norm.cdf(-1.0)
> 0.6826894921370859
stats.norm.ppf(0.9)
> 1.2815515655446004
무작위로 샘플을 뽑아 만든 표본들의 평균은 정규분포에 가깝다
np.random.seed(42)
sample_means = []
for _ in range(1000):
m = ns_book7.대출건수.sample(30).mean()
sample_means.append(m)
plt.hist(sample_means, bins=30)
모집단의 평균 : 11.593438968070707
샘플 크기 30의 표본평균의 평균 : 11.539900000000001
샘플 크기 20의 표본평균의 평균 : 11.39945 (가장 불일치)
샘플 크기 40의 표본평균의 평균 : 11.5613 (가장 유사)
표본평균의 표준편차 (표준오차)
np.std(sample_means)
> 3.0355987564235165
모집단의 표준편차 / 샘플개수의 제곱근
np.std(ns_book7.대출건수) /np.sqrt(40)
3.048338251806833
표본의 속성이 속할 것이라 믿는 모집단의 속성 범위
표본 : 파이썬 도서들과 그 대출건수,
-> 수량 : 251개, 평균 : 14.71, 95%구간
모집단의 평균 = 표본평균 - z * (모집단 표준편차 / 표본갯수의 제곱근)
python_std = np.std(python_books.대출건수)
python_se = python_std / np.sqrt(len(python_books))
python_se
> 0.8041612072427442(평균의 표준편차와 유사)
stats.norm.ppf(0.975)
> 1.959963984540054
stats.norm.ppf(0.025)
> -1.9599639845400545
공식 다시보기
모집단의 평균 = 14.75 - z(+-1.959963984540054) * 0.8041612072427442
계산 결과
print(python_mean-1.96*python_se, python_mean+1.96*python_se)
> 13.172848017867965 16.325159950259522
표본에 대한 정보를 사용해 모집단의 파라미터에 대한 가정을 검정
표본1: 파이썬 도서들과 그 대출건수
-> 수량 : 251개, 평균 : 14.71, 95%구간
표본2 : C++ 도서들과 그 대출건수
-> 수량 : 89개, 평균 : 11.59, 95%구간
cplus_se = np.std(cplus_books.대출건수) / np.sqrt(len(cplus_books))
cplus_se
> 0.9748405650607009 (표준오차)
z = (14.75 - 11.59) / (0.8^2 + 0.97^2).제곱근
(python_mean - cplus_mean) / np.sqrt(python_se**2 + cplus_se**2)
> 2.495408195140708 (z점수)
stats.norm.cdf(2.50)
> 0.9937903346742238
-> 95%지점인 유의수준준을 벗어나므로 대립가설 지지
t, pvalue = stats.ttest_ind(python_books.대출건수, cplus_books.대출건수)
print(t, pvalue)
> 2.1390005694958574 0.03315179520224784(p값)
-> p- 값이 0.05보다 작으므로 대립가설 지지
모집단의 분포가 정규분포를 따르지 않거나 모집단의 분포를 알 수 없을 때 사용
def statistic(x, y):
return np.mean(x) - np.mean(y)
def permutation_test(x, y):
obs_diff = statistic(x, y)
all = np.append(x, y)
diffs = []
np.random.seed(42)
for _ in range(1000):
idx = np.random.permutation(len(all))
x_ = all[idx[:len(x)]]
y_ = all[idx[len(x):]]
diffs.append(statistic(x_, y_))
less_pvalue = np.sum(diffs < obs_diff) / 1000
greater_pvlaue = np.sum(diffs > obs_diff) /1000
return obs_diff, np.minimum(less_pvalue, greater_pvlaue) * 2
permutation_test(python_books.대출건수, cplus_books.대출건수)
> (3.1534983660862164, 0.022(p-값))
res = stats.permutation_test((python_books.대출건수, cplus_books.대출건수), statistic, random_state=42)
print(res.statistic, res.pvalue)
> 3.1534983660862164 0.0258
모델 훈련 후 새로운 데이터를 사용해 모델을 평가함.
훈련 세트 : 훈련에 사용되는 입력, 타깃.
테스트 세튼 : 테스트에 사용되는 입력, 타깃. 보통 훈련 세트의 20~25% 크기를 사용함.
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(ns_book7, random_state=42)
사이킷 런의 입력으로 2차원 배열과 1차열 배열을 받기 때문.
X_train = train_set[['도서권수']]
y_train = train_set['대출건수']
print(X_train.shape, y_train.shape)
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X_train, y_train)
모델의 점수를 평가한 것으로서 정확할수록 1에 가까워짐
앞서 제작한 테스트 세트를 이용해 훈련한 모델을 평가한다.
X_test = test_set[['도서권수']]
y_test = test_set['대출건수']
lr.score(X_test, y_test)
> 0.10025676249337057 (결정계수)
https://ko.wikipedia.org/wiki/%EC%84%A0%ED%98%95_%ED%9A%8C%EA%B7%80
회귀 : 타깃이 실수인 문제
범주 : 타깃이 어떤 종류의 카테고리(범주, class)인 문제. ex) 개<>고양이<>사람이진 분류 : 카테고리가 두 개인 경우(음성 클래스(0) <> 양성 클래스(1))
다중 분류 : 카테고리가 세 개 이상인 경우
borrow_mean = ns_book7.대출건수.mean()
y_train_c = y_train > borrow_mean
y_test_c = y_test > borrow_mean
y_test_c.value_counts()
from sklearn.linear_model import LogisticRegression
logr = LogisticRegression()
logr.fit(X_train, y_train_c)
logr.score(X_test, y_test_c)
> 0.7106154385145393
가장 많은 클래스로 무조건 예측을 수행함.
from sklearn.dummy import DummyClassifier
dc = DummyClassifier()
dc.fit(X_train, y_train_c)
dc.score(X_train, y_train_c)
> 0.6926182951903375
로지스틱 회귀의 정확도가 70% 정도이지만, 음성 클래스의 양도 70%정도이고 더미테스트의 결과도 69%를 기록하므로 의미없는 결과 도출됨.
지난 몇 주간 그래프 그리기 등의 가벼운 내용을 접하다가 통계나 머신러닝 기법의 새로운 용어들을 마주치니 학습에 시간이 많이 걸렸다. 흥미로웠던 것은 파이썬의 패키지들에서 머신러닝 수행부터 평가까지 많은 기능을 제공해주고 있어 활용만 제대로 하면 초보적인 수준의 머신러닝은 누구나 가능한 점이었다. 때문에 머신러닝에서 가장 중요한 것은 올바른 모델과 데이터를 선정하는 것임을 다시한번 느낄 수 있었다.