2021. 6. 28. 23:26ㆍ머신러닝
머신러닝에서 일반적으로 bootstrap 방법은 Trianing dataset이 부족할 때, dataset의 규모를 늘릴 때 많이 활용되는 방법입니다. 통계학관점에서는, 평균과 같은 측정된 통계치에 대한 통계적 검증 및 신뢰성 확보를 위해 활용하곤 합니다.
Bootstrap을 수행하는 기본적인 방법은 복원추출을 활용하여 기존 Training data의 수와 똑같은 수의 dataset을 추출하는 것입니다.
만약 N개의 Bootstrap data set을 만든 후 data의 총 합과 같은 어떤 관측값을 도출해본다고 생각해보겠습니다. 원래 하나의 dataset만 있다면 해당 값의 분산을 구하는 것은 어렵지만 Bootstrap을 활용한다면 이러한 것이 가능하게 됩니다.
이와 마찬가지 생각을 모델 Error에도 적용해보겠습니다.
Bootstrap이 된 데이터마다 모델을 Fitting하여 Error를 확인해볼 수 있습니다. 다만, Bootstrap된 데이터도 기존 Training data set에 있는 값들이 나온 것이므로, Overfitting될 위험이 있습니다. 그렇기 때문에 Cross-validation 개념을 적용하는데, 특정 Sample을 제거하고 Bootstrap을 수행한 후 Error를 측정하는 것입니다. leave-one-out cross-validation과 유사하게 하나의 Sample을 제거하고 Bootstrap을 수행하는 leave-one-out bootstrap의 Error는 다음과 같습니다.
leave-one-out bootstrap은 Overfitting 문제를 다소 해결할 수 있으나, Training dataset의 size가 작을 때 outlier에 영향을 쉽게 받을 수 있으며, training dataset의 사이즈가 크면 계산에 들어가는 Resource가 커지게 됩니다.
Cross-validation 및 Bootstrap관련하여 간단한 Python Code를 정리해 보겠습니다. 아래 사이트를 참고하였습니다.
https://davinci-ai.tistory.com/18
https://dlearner.tistory.com/21?category=828987
https://machinelearningmastery.com/a-gentle-introduction-to-the-bootstrap-method/
Cross-Validation
import pandas as pd
import numpy as np
## K-Fold
from sklearn.model_selection import KFold
X = ["a", "b", "c", "d"]
kf = KFold(n_splits=2)
for train, test in kf.split(X):
print("%s %s" % (train, test)) ##
'''
index 반환
[2 3] [0 1]
[0 1] [2 3]
'''
## Repeated K-Fold
from sklearn.model_selection import RepeatedKFold
X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
rkf = RepeatedKFold(n_splits=2, n_repeats=2, random_state=123)
for train, test in rkf.split(X):
print("%s %s" % (train, test))
'''
index 반환
[1 2] [0 3]
[0 3] [1 2]
[0 2] [1 3]
[1 3] [0 2]
'''
## Leave One Out
from sklearn.model_selection import LeaveOneOut
X = [1, 2, 3, 4]
loo = LeaveOneOut()
for train, test in loo.split(X):
print("%s %s" % (train, test))
'''
index 반환
[1 2 3] [0]
[0 2 3] [1]
[0 1 3] [2]
[0 1 2] [3]
'''
## Leave P Out
from sklearn.model_selection import LeavePOut
X = np.ones(4)
lpo = LeavePOut(p=2)
for train, test in lpo.split(X):
print("%s %s" % (train, test))
'''
index 반환
[2 3] [0 1]
[1 3] [0 2]
[1 2] [0 3]
[0 3] [1 2]
[0 2] [1 3]
[0 1] [2 3]
'''
## Stratified K-Fold
from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=2)
iris= load_iris()
iris_df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
iris_df['label']=iris.target
iris_df['label'].value_counts()
for train_index, test_index in skf.split(iris_df, iris_df['label']):
label_train = iris_df['label'].iloc[train_index]
label_test = iris_df['label'].iloc[test_index]
print('학습 레이블 데이터 분포:\n', label_train.value_counts())
print('검증 레이블 데이터 분포:\n', label_test.value_counts())
'''
Label 비율 동일 여부 확인, 150개 데이터를 75개씩 2개 그룹으로 나눔(2-Fold)
학습 레이블 데이터 분포:
2 25
1 25
0 25
Name: label, dtype: int64
검증 레이블 데이터 분포:
2 25
1 25
0 25
Name: label, dtype: int64
학습 레이블 데이터 분포:
2 25
1 25
0 25
Name: label, dtype: int64
검증 레이블 데이터 분포:
2 25
1 25
0 25
Name: label, dtype: int64
'''
## Cross-validation 활용
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(iris.data, iris.target)
kfold5 = KFold(n_splits=5)
cross_val_score(logreg, iris.data, iris.target , cv= kfold5 ,scoring='accuracy')
logreg.predict(iris.data)
loo = LeaveOneOut()
cross_val_score(logreg, iris.data, iris.target , cv= loo,scoring='accuracy')
logreg.predict(iris.data)
Bootstrap
##Bootstraping
from sklearn.utils import resample
from sklearn.metrics import mean_squared_error
data = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
boot = resample(data, replace=True, n_samples=100, random_state=1)
print(boot)
'''
bootstrap 결과
[0.6, 0.4, 0.5, 0.1, 0.2, 0.4]
'''
## bootstrap 활용
target = iris.target.reshape(-1,1)
df = np.hstack((iris.data, target))
df = pd.DataFrame(df)
df.columns = ["f1","f2","f3","f4","target"]
df_index = [i for i in df.index]
mse_list = []
for k in range(5):
bootstrap = resample(df_index, replace = True, n_samples = 150)
x = df.iloc[bootstrap][["f1","f2","f3","f4"]]
y = df.iloc[bootstrap]["target"]
temp_y = logreg.predict(x)
mse_list.append(mean_squared_error(y, temp_y))
np.mean(mse_list)
'머신러닝' 카테고리의 다른 글
Tree-Based Model (0) | 2021.10.06 |
---|---|
Generalized Additive Models(GAM) (0) | 2021.08.15 |
모델 평가 및 선정 > Cross-Validation (0) | 2021.06.10 |
모델 평가 및 선정 > In-Sample Prediction(2/2) (0) | 2021.05.30 |
모델 평가 및 선정 > In-Sample Prediction (0) | 2021.05.13 |