from sklearn.pipeline import make_pipeline
from category_encoders import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipe = make_pipeline(
OneHotEncoder(),
SimpleImputer(),
StandardScaler(),
LogisticRegression(n_jobs=-1)
)
pipe.fit(X_train, y_train)
pipe.named_steps
속성을 사용하면 유사 딕셔너리 객체로 파이프라인 내 과정에 접근 가능
장점
단점
결정트리 학습 알고리즘
결정트리를 학습하는 것은 노드를 어떻게 분할하는가에 대한 문제로 결정트리의 비용함수를 정의하고 그것을 최소화 하도록 분할하는 것이 트리모델 학습 알고리즘
과적합 해결
선형모델에서는 특성과 타겟의 관계를 파악하기 위해 회귀 계수를 사용, 트리모델에서는 특성 중요도를 사용
warm up
Random forest made out Decision tree
Decision tree is not flexible when it comes to classifying new samples -> Overfitting problem
Random forest can fix this problem easily
Bagging : Bootstarpping the data(ramdomly selecting data while allowing duplicate) plus using the aggregate to make decision
Out-Of-Bag dataset : it didn't make it into the bootstrap dataset
Out-Of-Bag error : the proportion of Out-Of-Bag samples that were incorrectly classified
- we can measure how accurate our random forest is by the proportion of Out-Of-Bag samples that were correctly classified by the random forest
앙상블 방법은 한 종류의 데이터로 여러 머신러닝 학습모델(weak base learner, 기본모델)을 만들어 그 모델들의 예측결과를 다수결이나 평균을 내어 예측하는 방법을 의미
이론적으로 기본모델 몇가지 조건을 충족하는 여러 종류의 모델을 사용할 수 있음
랜덤포레스트는 결정트리를 기본모델로 사용하는 앙상블 방법이라 할 수 있음
결정트리들은 독립적(= 병렬)으로 만들어지며 각각 랜덤으로 예측하는 성능보다 좋을 경우 랜덤포레스트는 결정트리보다 성능이 좋음
앙상블 모델에는 bagging, boosting, stacking 모델이 있고, 랜덤포레스트는 bagging 모델에 해당
왜 하나의 좋은 모델을 만들지 않고 기본모델을 만들까?
-> 안정성, 오류를 줄이기 위해, 과적합을 방지하려고 ...
-> 전문가 한명이 모든 문제를 해결하는 것보다 일반인 여러명이 모여 문제를 해결하면 더 좋은 결과를 도출할 수 있기 때문
배깅(Bagging, B
ootstrap Agg
regating
)
부트스트랩 방식으로 샘플들을 복원추출해서 트리를 만들고 결과를 도출
데이터에서 샘플 추출 : 부트스트랩 -> 기본모델(결정트리) 만듦 -> 종합 : 평균, 최빈값
부트스트랩(Bootstarp) 샘플링
앙상블에 사용하는 작은 모델들은 부트스트래핑(bootstraping)이라는 샘플링과정으로 얻은 부트스트랩세트를 사용해 학습
부트스트랩세트의 크기가 n이라 할 때 한 번의 추출과정에서 어떤 한 샘플이 추출 되지 않을 확률은
n회 복원추출을 진행했을 때 그 샘플이 추출되지 않았을 확률은
n을 무한히 크게 했을 때 (참고: )
데이터가 충분히 크다고 가정했을 때 한 부트스트랩세트는 표본의 63.2% 에 해당하는 샘플을 가짐
추출되지 않은 36.8% 의 샘플이 Out-Of-Bag 샘플
pipe.named_steps['randomforestclassifier'].oob_score_
Agrregation
랜덤포레스트는 기본모델의 트리를 만들 때 무작위로 선택한 특성세트 사용
- 명목형 변수에도 ordinal encoding 사용해도 되는 이유
-> 숫자의 크기가 의미가 없어서, 분할을 기준에 순서의 개념이 들어간다 해서 집단이 나뉘는 그룹이 달라지지 않음, 거리나 위치가 중요한 모델이 아니기 때문- ordinal encoding 을 one-hot encoding 보다 권장하는 이유
-> 피쳐 수 늘어나지 않아 특성 중요도를 정확하게 파악할 수 있기 때문
랜덤포레스트 모델이 과적합에 결정트리에 비해 더 강한 이유?
- 여러 모델을 종합한 것이기 때문에 에러를 발견하고 보완할 확률이 더 높음
- 전체 데이터를 모두 사용하지 않기 때문
- 편향이 높은 약한 기준모델 여러 개를 종합하기 때문
warm up
Performance measure
1. Classification : simple accuracy, precision, recall, F-beta measure, ROC(& AUC)
2. Regression : sum of squares error, mean absolute error, RMS error
다루는 문제에 따라 정밀도와 재현율 중 어느 평가지표를 우선시 해야하는지 판단해야 함
- 병원에서 초기 암진단을 하는 경우?
- recall -> 초기 발견이 사망률을 크게 낮추기 때문에(실제 암일때 암이 아니라고 진단하면 리스크가 크기 때문에)
- 넷플릭스에서 영화추천을 해주는 경우?
- precision -> 선호하지 않은 영화를 추천하는 경우 소비자가 탈퇴할 가능성이 높기 때문
임계값(Threholds)
이분법으로 확실히 분류를 할 기준, Randomforestclassifier 기본 임계값은 0.5
이진분류 문제에서 사용 가능(다중분류 문제에서는 각 클래스를 이진클래스 분류 문제로 변환하여 구할 수 있음)
ROC curve는 여러 임계값에 대해 TPR(True Positive Rate) 과 FPR(False Positive Rate) 그래프 보여줌
Recall(재현율) = Sensitivity =
Fall-out(위양성률) =
재현율을 높이기 위해서는 Positive로 판단하는 임계값을 계속 낮추어 모두 Positive로 판단하게 만들면 됨
재현율은 최대화 하고 위양성률은 최소화 하는 임계값이 최적의 임계값
#threshold 최대값의 인덱스,np.argmax()
optimal_idx = np.argmax(tpr - fpr)
optimal_threshold = thresholds[optimal_idx]
ML 모델 flow
1. 전처리, eda
2. 모델: 평가지표-정밀도, roc,auc
3. val_set 검증 - 정밀도 (:과적합 성능 낮음 등등 문제)
4. 모델 수정, 발전 : 피쳐엔지니어링, 하이퍼파라미터조정, 로지스틱, 부스팅 등
5. (3, 4번) 반복
6. 최종모델
7. 임계값 조정 roc cuve(임계값 조정 위해서) : 최최종모델
8. 테스트 : 결과(정밀도)
9. 모델 해석
warm up
Cross-validtion allows us to compare different machine learning methods and get a sense of how well they wll work in practice
A : K개로 데이터를 나눈 후, 그 중 하나는 검증데이터로 나머지는 훈련데이터로 사용
B : 하이퍼파라미터를 설정해 학습을 시켜 모델 생성
C : 여기서 학습된 모델과 검증 데이터를 사용해 데이터 예측
-> 이런 퍼포먼스들을 모두 함쳐서 평균을 냄 = 종합적인 검증 스코어
모델선택(Model selection) : 문제를 풀기 위해 어떤 학습 모델을 사용할 것인지, 어떤 하이퍼파라미터를 사용할 것인지
TargetEncoder : 범주형 변수 인코더로 타겟값을 특성의 범주별로 평균을 내어 그 값으로 인코딩
머신러닝 모델을 만들 때 중요한 이슈는 최적화와 일반화
이상적인 모델은 과소적합과 과적합 사이에 존재
검증곡선 : 훈련/검증데이터에 대해 y축: 스코어 ,x축: 하이퍼파라미터로 그린 그래프
훈련곡선(learning curve): x축이 훈련데이터 수(# of training samples)에 대해 그린 것
Scikit-learn,validation curves 를 사용하면 다양한 하이퍼파라미터 값에 대해 훈련/검증 스코어 값의 변화를 확인할 수 있음
여러 하이퍼파라미터의 최적값 찾기 (모델 훈련 중에 학습이 되지 않는 파라미터)
사이킷런 하이퍼파라미터 튜닝 툴
RandomizedSearchCV(모델명, param_distributions=하이퍼파라미터 조정범위
,n_iter = "탐색횟수", cv = "폴드 수", scorig = "평가방법"
,verbose = "진행 상황 표시", random_state = "시드")
#Ridge 회귀모델의 하이퍼파라미터 튜닝 예시
from sklearn.model_selection import RandomizedSearchCV
from category_encoders import OneHotEncoder
from sklearn.feature_selection import f_regression, SelectKBest
from sklearn.impute import SimpleImputer
from sklearn.linear_model import Ridge
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
pipe = make_pipeline(
OneHotEncoder(use_cat_names=True)
, SimpleImputer()
, StandardScaler()
, SelectKBest(f_regression)
, Ridge()
)
# 튜닝할 하이퍼파라미터의 범위를 지정해 주는 부분
dists = {
'simpleimputer__strategy': ['mean', 'median'],
'selectkbest__k': range(1, len(X_train.columns)+1),
'ridge__alpha': [0.1, 1, 10],
}
clf = RandomizedSearchCV(
pipe,
param_distributions=dists,
n_iter=50,
cv=3,
scoring='neg_mean_absolute_error',
verbose=1,
n_jobs=-1
)
clf.fit(X_train, y_train);
print('최적 하이퍼파라미터: ', clf.best_params_)
print('MAE: ', -clf.best_score_)
# n_iter * cv = tasks 수행 수
# 랜덤포레스트 회귀문제 적용 예시
from scipy.stats import randint, uniform
pipe = make_pipeline(
TargetEncoder(),
SimpleImputer(),
RandomForestRegressor(random_state=2)
)
dists = {
'targetencoder__smoothing': [2.,20.,50.,60.,100.,500.,1000.], # int로 넣으면 error(bug)
'targetencoder__min_samples_leaf': randint(1, 10),
'simpleimputer__strategy': ['mean', 'median'],
'randomforestregressor__n_estimators': randint(50, 500),
'randomforestregressor__max_depth': [5, 10, 15, 20, None],
'randomforestregressor__max_features': uniform(0, 1) # max_features
}
clf = RandomizedSearchCV(
pipe,
param_distributions=dists,
n_iter=50,
cv=3,
scoring='neg_mean_absolute_error',
verbose=1,
n_jobs=-1
)
clf.fit(X_train, y_train);
print('최적 하이퍼파라미터: ', clf.best_params_)
print('MAE: ', -clf.best_score_)
negative MAE 사용 이유
사이킷런의 모델들은 성능을 평가하는 수치가 크면 좋다고 인식
하지만 mae같은 지표들(비용함수)은 작으면 작을수록 좋다. 0.3이 10보다 좋은 거지만 모델은 10이 더 좋다고 인식할수도 있는 것
그래서 성능 평가 지표에 -를 취해준 negative mae같은 것을 지표로 사용
그렇게 되면 -0.3이 -10보다 큰 거라 0.3이 더 좋다고 인식하고 실제로도 그게 맞기 때문!
예측결과 : best_estimator _
best_estimator _ : CV가 끝난 후 찾은 best parameter를 사용해 모든 학습데이터(all the training data)를 가지고 다시 학습(refit)한 상태
만약 hold-out 교차검증(훈련/검증/테스트 세트로 한 번만 나누어 실험)을 수행한 경우에는, (훈련 + 검증) 데이터셋에서 최적화된 하이퍼파라미터로 최종 모델을 재학습(refit) 해야함
선형회귀, 랜덤포레스트 모델들의 튜닝 추천 하이퍼파라미터
Random Forest
Logistic Regression
Ridge / Lasso Regression