빅데이터 분석 절차
데이터 수집 → EDA, 전처리 → Decision Tree 선정 → 학습 → 결과 확인
→ (정성적 분석) → (위험성 분석) → 시스템 적용 → 모델 활용 예측
▶ TAINGING, VALIDATION, AND TESTING
- Training Set : A data set of examples used during the learning process and is used to fit the parameters of a model.
- Validation Set : A data set of examples used to tune the hyperparameter of a model.
- Testing set : A data set that is independent of the training data set, but that follows the same probability distribution as the training data set.
예) 수능을 보기전 여러번 모의고사를 치르는것.
▶ 트레이닝 데이터, 테스트 데이터 분리
학습 데이터, 테스트 데이터 의 비율 7:3
* random_state : 수행마다 동일한 값을 얻기 위해 적용.
# 학습 데이터 70%, 테스트 데이터 30%
from sklearn.model_selection import train_test_split
X = df_t.drop('survived', axis=1)
y = df_t.survived
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=12)
# 직접구현
# X_train = df_t.iloc[:round(891 * 0.7), 1:]
# X_test = df_t.iloc[round(891 * 0.3), 1:]
# y_train = df_t.iloc[:round(891 * 0.7), 0]
# y_test = df_t.iloc[round(891 * 0.3), 0]
# np.random.shuffle
▶ 트레이닝 데이터, 테스트 데이터 확인
# 비율 확인
len(X_train.index) / (df_t.shape[0] + 1)
# 0.6984304932735426
# train 70%, validation 20%, test 10%
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=12)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.22, random_state=12)
# val데이터 셋은 고정된게 아니기 때문에 이 과정을 진행하지 않아도 된다.
len(X_val.index) / (df_t.shape[0] + 1)
# 0.1547085201793722
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
# (801, 4)
# (90, 4)
# (801,)
# (90,)
▶ DecisionTree 생성.
dt_clf = DecisionTreeClassifier()
▶ DecisionTree에 Train Data를 훈련.
dt_clf.fit(X_train, y_train)
▶ DecisionTree에 Test Data를 넣어 결과 예측.
# predict이 필요한 이유 : 정답이 없는 경우가 있기 때문.
dt_pred = dt_clf.predict(X_test)
▶ DecisionTree Accuracy Score 확인.
from sklearn.metrics import accuracy_score
accuracy_score(y_test, dt_pred)
print('DecisionTree 정확도: %.2f' % accuracy_score(y_test, dt_pred))
# DecisionTree 정확도: 0.81
print('DecisionTree 정확도: %.2f' % dt_clf.score(X_test, y_test))
# DecisionTree 정확도: 0.81
교차 검증
- 데이터 편중을 막기 위해서 별도의 세트로 구성된 학습 데이터 세트와 검증 데이터 세트에서 학습과 평가를 수행 하는 것.
▶ KFOLD
- Model validation techniques or assessing how the results of a statistical analysis will generalize to an independent data set.
- 모델이 가진 예측 성능을 객관적인 지표로서 비교.
- 보편적으로 사용되는 교차 검증 기법.
- 먼저 K개의 데이터 폴드 세트를 만들어서 K번 만큼 각 폴드 세트에 학습고 검증 평가를 1반복적으로 수행하는 방법.
- 학습 데이터 세트와 검증 데이터 세트를 점진적으로 변경하면서 마지막 5번째까지 학습과 검증을 수행하는 것.
- 높은 시험 점수를 위해 많은 문제 영역을 학습하는 것과 비슷.
- 여러 모델을 시험하고 제일 높은 적중률의 모델을 검증.인덱스 셔플
▶ KFLOD 학습 실행
▶ 5개의 폴드 세트를 가진 KFOLD 객체를 생성하여 교차 검증 수행 후 정확도 계산.
# KFold 학습 실행
from sklearn.model_selection import KFold
# 폴드 세트를 5개인 KFold 객체를 생성, 폴드 수 만큼 예측 결과를 저장을 위한 리스트 객체 생성.
def exe_kfold(clf, folds=5) :
kFold = KFold(n_splits=folds)
scores=[]
# KFold 교차 검증 수행
for i, (train_idx, val_idx) in enumerate(kFold.split(X_train)) :
# X_train 데이터에서 교차 검증별로 학습과 검증 데이터를 가리키는 index 생성
X_train_k = X_train.iloc[train_idx]
y_train_k = y_train.iloc[train_idx]
X_val_k = X_train.iloc[val_idx]
y_val_k = y_train.iloc[val_idx]
# Classfier 학습, 예측, 정확도 계산
dt_clf.fit(X_train_k, y_train_k)
scores.append(dt_clf.score(X_val_k, y_val_k))
# 5개 fold에서 평균 정확도 계산
print(f"{clf} 개별 학습 결과 : ", scores)
print(f"{clf} 평균 학습 결과 : %.2f" %np.mean(scores))
# DecisionTreeClassifier() 개별 학습 결과 : [0.7577639751552795, 0.79375, 0.9, 0.8625, 0.84375]
# DecisionTreeClassifier() 평균 학습 결과 : 0.83
# 전체 학습
scores=[]
for i, (train_idx, val_idx) in enumerate(kFold.split(X)) :
X_train_k = X.iloc[train_idx]
y_train_k = y.iloc[train_idx]
X_val_k = X.iloc[val_idx]
y_val_k = y.iloc[val_idx]
dt_clf.fit(X_train_k, y_train_k)
scores.append(dt_clf.score(X_val_k, y_val_k))
print(scores)
print(np.mean(scores))
# [0.7821229050279329, 0.7752808988764045, 0.8370786516853933, 0.8370786516853933, 0.8595505617977528]
# 0.8182223338145753
▶ STRATIFIED KFOLD
Stratified K-fold Cross Validation : K-fold-cross-validation with same population distribution.
- 데이터의 결과가 0(음성)과 1(양성)이 있을 때 nagative(음성), positive(양성)의 비율을 최소 2:8로 테스팅.
- 타이타닉 같은 경우 0과 1의 데이터 비율이 최소 2:8의 비율을 가지나 그렇지 않은 데이터도 많다.
▶ StratifiedKFold 학습 실행
# StratifiedKFold 학습 실행
from sklearn.model_selection import StratifiedKFold
def exe_skfold(clf, folds=5) :
skFold = StratifiedKFold(n_splits=folds)
scores=[]
for i, (train_idx, val_idx) in enumerate(skFold.split(X_train, y_train)) :
X_train_k = X_train.iloc[train_idx]
y_train_k = y_train.iloc[train_idx]
X_val_k = X_train.iloc[val_idx]
y_val_k = y_train.iloc[val_idx]
dt_clf.fit(X_train_k, y_train_k)
scores.append(dt_clf.score(X_val_k, y_val_k))
print(f"{clf} 개별 학습 결과 : ", scores)
print(f"{clf} 평균 학습 결과 : %.2f" %np.mean(scores))
# DecisionTreeClassifier() 개별 학습 결과 : [0.7577639751552795, 0.7875, 0.875, 0.84375, 0.85625]
# DecisionTreeClassifier() 평균 학습 결과 : 0.82
▶ KFold와 StratifiedKFold의 성능 비교
- KFold
- 회귀문제 (회귀의 결정값은 이산값 형태의 레이블이 아니라 연속된 숫자값이기 때문에 결정값 별로 분포를 정하는 의미가 없기 때문)
- StratifiedKFold
- 레이블 데이터가 외곡됐을 때.
- 분류시 활용.
- StratifiedKFold가 더 정비례적인 nagative와 positive의 비율로 검증하는것을 볼 수 있다.
- 성능의 차이보다는 검증의 방식의 차이가 있다.
# kFold, StratifiedKFold 성능 비교
skFold = StratifiedKFold(n_splits=5)
kFold = KFold(n_splits=5)
for i, (train_idx, val_idx) in enumerate(skFold.split(X_train, y_train)):
test = y_train.iloc[val_idx]
print(test.value_counts())
# 0 99
# 1 62
# Name: survived, dtype: int64
# 0 99
# 1 61
# Name: survived, dtype: int64
# 0 99
# 1 61
# Name: survived, dtype: int64
# 0 99
# 1 61
# Name: survived, dtype: int64
# 0 98
# 1 62
# Name: survived, dtype: int64
for i, (train_idx, val_idx) in enumerate(kFold.split(X_train, y_train)):
test = y_train.iloc[val_idx]
print(test.value_counts())
# Name: survived, dtype: int64
# 0 95
# 1 66
# Name: survived, dtype: int64
# 0 100
# 1 60
# Name: survived, dtype: int64
# 0 106
# 1 54
# Name: survived, dtype: int64
# 0 100
# 1 60
# Name: survived, dtype: int64
# 0 93
# 1 67
# Name: survived, dtype: int64
▶ cross_val_score()
StratifiedKFold를 간단하게 사용할 수 있는 함수
from sklearn.model_selection import cross_val_score
cross_val_score(estimator=dt_clf, X=X_train, y=y_train, cv=5)
# array([0.75776398, 0.7875 , 0.875 , 0.84375 , 0.85625 ])
# n_jobs : cpu 코어당 병렬로 작업을 가능하게 하는 옵션, 코어당 2개이상도 작업이 가능하다.
# cv : 폴드 개수, 몇개를 분활 할지 설정, 5개면 1/5로 분할
np.mean(cross_val_score(estimator=dt_clf, X=X_train, y=y_train, cv=5))
# 0.8253027950310559
▶ LOOCV
- LEAVE ONE OUT CROSS VALIDATION.
- 행의 갯수만큼 학습.
- 행이 많다면 학습량도 많다.
- 학습량과 성능이 꼭 비례하지는 않는다.
- 굉장히 오래 걸린다.
▶ LOOCV 학습 실행
from sklearn.model_selection import LeaveOneOut
scores= []
# 행의 갯수만큼, 행을 학습 시킴.
# columns length * columns length
loocv = LeaveOneOut()
for train_idx, val_idx in loocv.split(X_train) :
X_train_loo = X_train.iloc[train_idx]
X_val_loo = X_train.iloc[val_idx]
y_train_loo = y_train.iloc[train_idx]
y_val_loo = y_train.iloc[val_idx]
dt_clf.fit(X_train_loo, y_train_loo)
scores.append(dt_clf.score(X_val_loo, y_val_loo))
print("loocv 평균 학습 결과 : %.2f" %np.mean(scores))
# loocv 평균 학습 결과 : 0.83
▶ Leave-P-out cross validation
- 전체 데이터 중에서 p개의 샘플을 선택 → 모델 검증에 사용
- test set을 구성할 수 있는 경우의 수
- : 조합
- p개의 경우의수 만큼 검증
- 800개의 데이터인 경우 800^p
- 데이터 폴드 세트의 경우의 수가 매구 크기 때문에, 계산 시간에 대한 부담이 매우 큼
▶ REPEATED RANDOM SUB SAMPLING VALIDATION
- 데이터셋 인덱스를 무작위로 사전에 설정한 비율로 분할한다.
- Repeated random subsampling validation also referred to as monte carlo cress-validation splits the dataset randomly into training and validation. Unlikely k-ford cross-validation split of the dataset into not in groups or folds but splits in this case in random.
- The number of iterations is not fixed and decided by analysis. The results are then averaged over the splits.
# ShuffleSplit(REPEATED RANDOM SUB SAMPLING VALIDATION) 검증
from sklearn.model_selection import ShuffleSplit
ss = ShuffleSplit(test_size=0.2, n_splits=5, random_state=14)
for i, (train_idx, val_idx) in enumerate(ss.split(X_train)) :
X_train_ss = X_train.iloc[train_idx] # 학습지의 문제
X_val_ss = X_train.iloc[val_idx] # 시험지의 문제
y_train_ss = y_train.iloc[train_idx] # 학습지의 정답
y_val_ss = y_train.iloc[val_idx] # 시험지의 정답
dt_clf.fit(X_train_ss, y_train_ss) # 학습지의 문제와 정답을 보면서 학습
scores.append(dt_clf.score(X_val_ss, y_val_ss)) # 시험지의 문제로 시험을 치루고 정답값과 비교
print(len(train_idx), ":" , len(val_idx))
print("sft 평균 학습 결과 : %.2f" %np.mean(scores))
# 720 : 81
# sft 평균 학습 결과 : 0.88
▶ TIME SERIES CROSS-VALIDATION
- Labeling을 간소화 시켜준다.
- The order of the data is very important for time-series related problem. For time-related dataset random split or k-fold split of data in to train and validation may not yield good results. For the time-series dataset, the split of data into train and validation is according to the time also referred to as forward chaining method or rolling cross-validation. For a particular iteration, the next instance of train data can be treated as validation data.
▶ 최적 Hyper Parameter
하이퍼 파라미터 튜닝 : 머신러닝의 성능을 끌어올림.
▷ params 설정.
params = {"criterion":['gini', 'entropy'],
"splitter":['best', 'random'],
"max_depth":range(3, 17, 4),
"min_samples_split":range(2, 20, 4),
"min_samples_leaf":range(1, 20, 4),
"max_features" : [None, "auto", "sqrt", "log2"]}
▷ GridSearchCV로 설정한 params값과 모델을 파라미터에 설정하여 모델의 최적 성능을 설정.
from sklearn.model_selection import GridSearchCV
gs_dtclf = GridSearchCV(dt_clf, param_grid=params, scoring='accuracy',
n_jobs=-1, cv=5, verbose=1)
# verbose : 학습의과정 옵션
# n_jobs : 코어를 얼마나 사용할 것인가, -1을 하게되면 최대의 코어 사용
▷ 모델 학습과 %%time확인.
%%time
gs_dtclf.fit(X_train, y_train)
# Fitting 5 folds for each of 3360 candidates, totalling 16800 fits
# CPU times: user 6.55 s, sys: 397 ms, total: 6.95 s
# Wall time: 12.6 s
▷ best_params_로 최적화된 파라미터 확인.
best_params = gs_dtclf.best_params_
# {'criterion': 'gini',
# 'max_depth': 15,
# 'max_features': 'log2',
# 'min_samples_leaf': 1,
# 'min_samples_split': 8,
# 'splitter': 'random'}
▷ Accuracy scoer 확인.
gs_dtclf.best_score_
# 0.8402639751552796
# test데이터가 아님
▷ 최적화된 파라미터를 DecisionTree에 설정.
from sklearn.tree import DecisionTreeClassifier
dt_clf_best = DecisionTreeClassifier(**best_params)
▶ 교차 검증 정리
- Training-Testing vs Training-Validation-Testing
- 데이터의 수가 충분히 많을 때 Training-Validation-Testing 사용.
- CV = small sample size
- K-fold-CV = balanced distribution
- Stratified K-fold-CV = unbalanced distribution
- GridSearchCV = Hyperparameter optimization
- Random sub-sampling = Stable results
- Baysian Optimization = fast speed with stats
머신러닝 모델 평가 지표
- white box : 과정이 해석되는 모델
- black box : 과정이 해석되지 않는 모델
- ex) Deep learning
▶ 평가 지표
- TN(true negative) : 실제 부정 데이터를 부정으로 제대로 예측
- FP(false positive) : 실제 부정 데이터를 긍정으로 잘못 예측
- FN(false negative) : 실제 긍정 데이터를 부정으로 잘못 예측
- TP(true positive) : 실제 긍정 데이터를 긍정으로 제대로 예측
▶ 회귀 성능 평가 지표
▶ 분류 성능 평가 지표
- Accuracy(정확도)
- Confusion Matrix(오차행렬)
- Precision(정밀도) & Recall(재현율)
- F1 score
- ROC AUC
▷ Accuracy
Accuracy가 높을 수 록 model의 performance가 증가하는것은 아니다.
▷ Confusion Matrix(오차행렬)
- TN의 예측률은 큰 의미가 없으며 FP, FN, TP의 예측률이 의미를 가진다.
- FN의 예측에는 주의가 필요하다.
- 임산부에게 불임이라는 예측과 암환자에게 음성이라는 판정을 가져다주는것.
- 정확도는 TP의 정확도로 예측한다.
- 정확도 = 예측값과 실제값이 얼마나 동일한가
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, bag_clf_pred2)
pd.DataFrame(confusion_matrix(y_test, bag_clf_pred2), columns=['0', '1'])
▷ Precision(정밀도) & Recall(재현율)
- 정밀도
- 모델이 True로 판단한것에 대한 실제 True의 비율.
- 실제 음성인 데이터 예측을 양성으로 잘못 판단하여 업무상 큰 영향이 발생하는 경우.
- EX) 스펨 메일 차단 모델.
- 실제 음성인 데이터 예측을 양성으로 잘못 판단하여 업무상 큰 영향이 발생하는 경우.
- 모델이 True로 판단한것에 대한 실제 True의 비율.
- 재현율
- 실제 True인 것 중에서 모델이 True라고 예측한 것의 비율
- 실제 양성 데이터를 음성으로 잘못 판단하여 업무상 큰 영향이 발생하는 경우.
- EX ) 암 판단 모델, 금융 사기 예측 모델
- 실제 양성 데이터를 음성으로 잘못 판단하여 업무상 큰 영향이 발생하는 경우.
- 실제 True인 것 중에서 모델이 True라고 예측한 것의 비율
▷ F1 Score
- 데이터 불균형 문제를 해결하는 하나의 방법은 F1 Score를 사용하는 것이다.
- F1 Score는 예측 오류 개수만 관련되는 것이 아니라 발생한 오류의 종류도 관여하게 된다.
- Precision(정밀도)과 Recall(재현율)은 데이터가 불균형할 때 사용하는 가장 대표적인 2가지 메트릭이고 F1 score의 기초가 된다.
- 이상적으로, 좋은 모델은 positive한 것을 모두 제대로 분류하고, positive한 것만 제대로 분류하면 된다. 하지만 현실에서는 두 가지 모두 높이는 것은 힘들다.
- Precision과 Recall으로 F1 score가 구성되고 불균형한 데이터에서 잘 동작하는 평가지표가 된다. F1 score는 precision과 recall의 조화평균이 된다.
- 결론적으로 F1 score는 precision과 recall이 모두 높으면 높고 0.0 ~ 1.0 사이의 값을 가진다(e.g. 0.87, %아님 주의).
▷ ROC AUC
Receiver Operation Characteristic Curve, 수신자 판단 곡선.
2차 대전 당시 통시 장비 성능 평가를 위해 고안된 수치.
의학 분야에서 많이 사용된다.
머신러닝 이진 분류 모델의 예층 성능 판단에 중요한 평가 지표.
ROC curve는 FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)이 어떻게 변하는지를 나타내는 곡선이다.
▶ 오차행렬, 정확도, 정밀도, 재현율, F1 Score, AUR ROC를 출력해주는 함수 생성
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, roc_auc_score, f1_score
def get_clf_eval(y_test, pred) :
print("-" * 5)
print("오차 행렬\n",confusion_matrix(y_test, pred))
print("정확도(accuracy) : %.2f" %accuracy_score(y_test, pred))
print("정밀도(precision) : %.2f" %precision_score(y_test, pred))
print("재현율(recall) : %.2f" %recall_score(y_test, pred))
print("f1 Score : %.2f" %f1_score(y_test, pred))
print("AUC : %.2f" % roc_auc_score(y_test, pred))
print("-" * 5)
return accuracy_score(y_test, pred), precision_score(y_test, pred),recall_score(y_test, pred), f1_score(y_test, pred), roc_auc_score(y_test, pred)
▶ TRADE-OFF
학습이 끝난 머신러닝 모델을 상대로 Precision과 Recall을 Trade-off 할 수 있다.
▷ predict_proba
- 각 클래스에 대한 확률을 출력한다. decision_function의 출력보다 이해하기 더 쉽다.
- 50 : 50이 나올 확률은 사실상 매우 적고 복잡한 데이터셋에서는 더욱 적다. 그렇기에 확률이 더 높은 값으로 예측값이 선택된다.
- 과대적합, 과소적합에 따라서 그 정도가 과대적합이면 잘못된 예측에 대한 확신이 강하고, 과소적합이면 그래도 50/50에 가까운 값을 가지게 된다.
- 일반적으로 복잡도가 낮은 모델은 예측에 불확실성이 더 많으며 이런 불확실성과 모델의 정확도가 동등하면 이 모델을 보정(calibration) 되었다고 한다. 즉 보정된 모델에서 70% 확신을 가진 예측은 70%의 정확도를 낼 것이다.
'Python' 카테고리의 다른 글
[Python] Keras.initailizers(초기화 함수) (0) | 2022.10.31 |
---|---|
[Python] Functional API (0) | 2022.10.31 |
[Python] Coding Test (팩토리얼) (0) | 2022.10.13 |
[Python] Coding Test (이진수 변환) (0) | 2022.10.13 |
[Python] 빅데이터 분석 3 : 모델 선택(Model Selection) (0) | 2022.10.11 |