생존 여부 예측 모델링
전처리 전에 EDA 필수
def check_fillna(df):
df.loc[:,"Age"].fillna(df.loc[:,"Age"].mean(), inplace=True )
#Age 컬럼의 결측치를 train 데이터 평균값으로 채우기
df.loc[:,"Cabin"].fillna( "N", inplace=True)
df.loc[:,"Embarked"].fillna( "N", inplace=True)
df.loc[:,"Fare"].fillna(0, inplace=True)
#Cabin, Embarked, Fare 컬럼의 결측치를 정보없음의 값(N, 0)으로 채우기
return df
def drop_feature(df):
# tree기반의 모델이 중요하다고 하는 변수 중심으로 남기고 나머지들을 제외를 하거나 수정해서 Feature를 변경
# pandas에서 drop : axis = 0/1
df.drop( ["PassengerId","Name","Ticket"], axis=1, inplace=True )
return df
def encode_feature(df):
# Cabin : 개별의 종류가 147개
# => EDA + 도메인 특성 이용해 앞글자 1개만 대표화
data.loc[:,"Cabin"]=data.loc[:,"Cabin"].apply(lambda x : str(x)[:1])
# 라벨인코딩
cols = ["Cabin", "Sex", "Embarked"]
for col in cols:
le = LabelEncoder()
le.fit(df.loc[:,col])
df.isetitem( df.columns.get_loc(col), le.transform(df.loc[:,col]))
return df
train/test 정확히 구별하기!!
train 데이터만 가지고 처리하고, test에서는 적용만 해야함
test 시 new/unseen 나타날 경우 train과 별개로 뒤에 새로운 룰 추가
def titanic_preproccessing( df ):
df = check_fillna(df)
df = drop_feature(df)
df = encode_feature(df)
# ........
return df
y_titanic = data.loc[:,"Survived"] #정답 분리
X_titanic = data.drop("Survived", axis=1)
train은 학습에 사용되고 valid 과 test는 평가에 사용
val은 정답을 알고 자체 평가, test은 정답을 모름
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(
X_titanic, # 처리가 된 문제지
y_titanic, # 처리가 된 정답지
test_size = 0.2, # train 중에서 얼마를 val으로 남길지
random_state=1234
stratify=y_titanic # 특정한 값의 비율을 유지하려고 할 때 추가
)
from sklearn.model_selection import KFoldkfold = KFold(n_splits = 5, random_state=1234, shuffle=True)from sklearn.model_selection import StratifiedKFoldstr_kfold = StratifiedKFold(n_splits = 5, random_state=1234, shuffle=True)cf) 데이터 수가 부족할 때 -> 데이터 펌핑한 후 진행
from sklearn.model_selection import RepeatedKFold
rkfold = RepeatedKFold(n_splits = 5, random_state=1234, n_repeats=10 )
from sklearn.model_selection import RepeatedStratifiedKFold
rskfold = RepeatedStratifiedKFold(n_splits = 5, random_state=1234, n_repeats=10)
from sklearn.model_selection import cross_val_scorefrom sklearn.metrics import accuracy_scoresklearn - RandomGridSearchCV, GridSearchCV +optuna 외부 pkg 활용까지 할 수도 있음from sklearn.model_selection import GridSearchCVknn = KNeighborsClassifier(n_jobs=-1) #깡통
scores = cross_val_score(knn, X_train, y_train, cv=kfold, scoring = 'accuracy')
테스트할 파라미터를 직접 지정
(KneighborsClassifier 메뉴얼에서 확인 필요)
parameters = {'n_neighbors' = [1,3,5,7,9,11,13,15],
argorithm = []}
RGS
# 사용할 모델 세팅
knn = KNeighborsClassifier(n_jobs=-1)
# 테스트 수가 파라미터 조합 수보다 작아야 함
n_iter = 10
# RSCV 세팅 : 모델 - 지정한 파라미터 dict 넣어주기
knn_kf_rgs = RandomizeSearchCV(knn, param_distributions=parameters,
cv=kfold, scoring = "accuracy", n_iter = n_iter, random_stats = 1234, # 재현성
n_jobs = -1)
knn_kf_rgs.fit(X_train, y_train)knn_kf_rgs.cv_results_최적의 조합 찾기
knn_kf_rgs.best_score_
knn_kf_rgs.best_params_
가장 좋은 성능의 모델을 val로 자체평가
knn_kf_rgs_best = knn_kf_rgs.best_estimator
knn_kf_rgs_ypred = knn_kf_rgs_best.predict(X_val)
knn_kf_rgs_acc = accuracy_score(y_val, knn_kf_rgs_ypred) #채점
print(knn_kf_rgs_acc)
-> 값이 떨어질 경우 overfit 의심.. 알고리즘 x 파라미터 조절
# 1.테스트할 파라미터들 세팅!!!
parameters ={
"n_neighbors" : [19,17,21], # 3
"algorithm":["auto","ball_tree","kd_tree"] # 3
# --> GS : 3*3=9가지 경우 모두다 실험!!!!
}
# 2. 사용할 모델
knn = KNeighborsClassifier(n_jobs=-1)
# 3. 직접 모든 파라미터들을 다 해주는 GridSearchCV ==> 하나의 모델
knn_kf_gs = GridSearchCV(
knn,
param_grid=parameters,
cv = kfold,
scoring="accuracy",
####
n_jobs= -1
)
# 4. 실제 데이터를 넣어서 학습
knn_kf_gs.fit(X_train, y_train)
knn_kf_gs.cv_results_ 로 아까 찾은 best model과 비교하여 선택
https://scikit-learn.org/1.5/modules/generated/sklearn.ensemble.RandomForestClassifier.html
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier( n_jobs=-1, random_state=1234)
scores = cross_val_score( rf,
X_train,y_train,
cv=kfold,scoring="accuracy")
로 대략 accuracy 구하기
-> 세부 parameter 조절
accuracy가 더 높게 나오도록 파라미터 조절하며 RF 최적화
rf = RandomForestClassifier( n_jobs=-1, random_state=1234)
# test할 parameter 선정
parameters ={
# RF : Bagging -> 여러 모델의 종합 => 몇 개의 모델을 활용할 것인가? ( 너무 많으면 오래 걸림 )
"n_estimators" : [10,30,50,70,100,200,300,500,1000,2000],
# ==> many(col 어떻게 구성할지) + Diversity
"max_features" : [3,4,5,6,7],
# 개별 decision tree의 overfit을 조절하는 parameter
"max_depth" : [2,3,4,5,6,7,8,10]
"min_samples_split": [1,3,5,7,9]
# Bias에서 좀 손해보더라도 Variance 확보 -> New 일반성
# RGS
n_iter = 20
rf_kf_rgs = RandomizeSearchCV(rf, param_distributions = parameters, cv = kfold, n_iter = n_iter, randomstate = 1234, scoring = "accuracy", n_jobs = -1)
rf_kf_rgs.fit(X_train, y_train)rf_kf_rgs.cv_results_ #전체결과rf_kf_rgs.best_score_ #가장높은성과rf_kf_rgs.best_params_ #그때의파라미터rf_kf_rgs_best = rf_kf_rgs.best_estimator_rf_kf_rgs_ypred = rf_kf_rgs_best.predict(X_val)rf_kf_rgs_acc = accuracy_score(y_val, rf_kf_rgs_ypred)rf = RandomForestClassifier(n_jobs=-1, random_state=1234)
parameters = {
"n_estimators": [70, 50, 100,500],
"max_features" :[7,6,5],
"max_depth" :[3,4,5],
#"min_samples_split":[4,5,6]
# ==> 4*3*3*3 = 27*4 = 1XX * cv5 = 5XX
}
rf_kf_gs = GridSearchCV(
rf, param_grid=parameters,
cv=kfold, scoring="accuracy",
n_jobs=-1
)
rf_kf_gs.fit(X_train,y_train)
마찬가지로 성능 평가
rf_kf_gs.best_score_
rf_kf_gs.best_params_
#val에 대해 평가
rf_kf_gs_best = rf_kf_gs.best_estimator_
rf_kf_gs_ypred = rf_kf_gs_best.predict(X_val)
rf_kf_gs_acc = accuracy_score(y_val, rf_kf_gs_ypred)
-> RGS와 GS중 score 비교하여 선택
import joblib
joblib.dump(rf_kf_best, "rf_kf_best.pkl") #저장
model_path = '/content/rf_kf_best.pkl' #열기
rf_backup = joblib.load(model_path)
*** OS가 다른 상황에서는 pickle 사용
import pickle
filename = "my_model.pkl" #저장
pickle.dump(rf_kf_gs_best, open(file_name,"wb")
model_path = '/content/my_model.pkl' #열기
* # 간단하게 불러온 게 동일한지 체크
(rf_kf_gs_best.predict(X_val) != rf_backup.predict(X_val)).sum()
* colab에 이미 설치되어있음
xgboost - scikit api
https://xgboost.readthedocs.io/en/stable/python/python_api.html#module-xgboost.sklearn
baseline
xgbc = XGBClassifier(n_jobs=-1, random_state=1234)
scores = cross_val_score( xgbc, X_train,y_train,
cv=kfold, scoring="accuracy")
** boosting 계열 알고리즘은 주된 파라미터를 제외하고는 튜닝에 의해 크게 차이가 나지 않음. 세부 파라미터까지 볼 필요 없음.
RGS
xgbc = XGBClassifier(n_jobs=-1, random_state=1234)
#test parameter 설정
parameters = {
"n_estimators" : [10,30,50,100,300,500],
"learning_rate" : [0.01, 0.1, 0.2, 0.3],
#개별 모델 조절
#인위적으로 트리 조절 - 깊이
"max_depth" : [2,3,4,5,6,10],
#더 분할할 지 - 너비
"gamma" : [0.1, 0.2, 0.3],
#OF risk 피하기 -> 샘플링 *가로*/세로 둘 다 사용 = RF 의 max_feature + max_sample
"subsample" : [ ] #가로 비율
"colsample_bytree" : [ ] #세로 비율
}
n_iter = 100
xgbc_kf_rgs = RandomizedSearchCV(
xgbc,
param_distributions=parameters,
cv = kfold,
scoring="accuracy",
n_iter= n_iter,
random_state=1234,
n_jobs=-1
)
xgbc_kf_rgs.fit(X_train, y_train)
xgbc_kf_rgs.best_score_xgbc_kf_best = xgbc_kf_rgs.best_estimator_xgbc_kf_ypred = xgbc_kf_best.predict(X_val)xgbc_kf_acc = accuracy_score(y_val,xgbc_kf_ypred )parameters= {
"subsample": [0.4, 0.3],
"n_estimators":[300,250,500],
"max_depth":[2,3],
"learning_rate":[0.01, 0.005, 0.02],
"gamma" : [0.2, 0.15, 0.25],
"colsample_bytree":[0.6, 0.5]
} # 2 * 3 * 2* 3* 3* 2
xgbc = XGBClassifier(n_jobs=-1, random_state=1234)
xgb_kf_gs = GridSearchCV(
xgbc,
param_grid=parameters,
cv=kfold,
scoring="accuracy",
n_jobs=-1 # verbose 파라미터를 사용하여 중간 결과 모니터링
)
xgb_kf_gs.fit(X_train,y_train)
GS 평가
xgb_kf_gs.best_score_
xgb_kf_gs_best = xgb_kf_gs.best_estimator_
xgb_kf_gs_ypred = xgb_kf_gs_best.predict(X_val)
xgb_kf_gs_acc = accuracy_score(y_val, xgb_kf_gs_ypred)
=> RGS 와 GS score 비교하여 선택
xgboost랑 비슷. 속도가 좀 더 빠름.
https://lightgbm.readthedocs.io/en/v4.5.0/pythonapi/lightgbm.LGBMClassifier.html#lightgbm.LGBMClassifier
from lightgbm import LGBMClassifier
lgmc = LGBMClassifier( n_jobs=-1, random_state=1234)
scores = cross_val_score(lgmc, X_train, y_train,
cv=kfold, scoring="accuracy")
lgmc = LGBMClassifier(n_jobs=-1, random_state=1234)
parameters ={
# 부스팅 관련된 주된 파라미터
# 1) 몇 개의 모델을 사용할지...
"n_estimators":[10,30,50,100,300,500],
# 2) 어느 정도의 비율로 반영할지 lr
"learning_rate":[0.01, 0.03, 0.05, 0.1, 0.3],
# 개별 모델 : tree --> overfit
"max_depth" : [2,3,4],
"min_split_gain":[0.1, 0.2], # --> xgboost에서 gamma와 유사한 기능
# 샘플링
"subsample":[0.3, 0.5, 0.7, 0.9],
"colsample_bytree":[0.3, 0.5, 0.7, 0.9]
# 기타 : 규약
n_iter = 10
lgmc_kf_rgs = RandomizedSearchCV(
lgmc,
param_distributions = parameters,
cv = kfold,
n_iter = n_iter,
scoring="accuracy",
n_jobs=-1,
random_state=1234
)
lgmc_kf_rgs.fit(X_train, y_train)
lgmc_kf_rgs.best_score_lgmc_kf_rgs.best_params_lgmc_kf_rgs_best = lgmc_kf_rgs.best_estimator_lgmc_kf_rgs_ypred = lgmc_kf_rgs_best.predict(X_val)lgmc_kf_rgs_acc = accuracy_score(y_val, lgmc_kf_rgs_ypred)혼자 해보기!
KNN, RF, XGBoost, lightGBM 의 성능을 비교하며 최종 모델 선택
hard_clf = VotingClassifier(
# 어떤 모델들을 가지고 다수결을 할지 : 튜플로 개별 모델 -> 리스트
estimators = [
("RF", rf_kf_gs_best),
("XGB",xgb_kf_gs_best),
("LGBM",lgmc_kf_rgs_best)
],
# 어떤 방식으로 의견을 종합할지
voting="hard",
n_jobs=-1
)
hard_clf.fit(X_train, y_train)
hard_clf_ypred = hard_clf.predict(X_val)
hard_clf_acc = accuracy_score(y_val, hard_clf_ypred)
```
- Soft Voting (1인 다표)
``` python
soft_clf = VotingClassifier(
# 어떤 모델들을 가지고 다수결 할지
estimators = [
("RF", rf_kf_gs_best),
("LGBM",lgmc_kf_rgs_best)
],
# 어떤 방식으로 의견 종합할지
voting="soft",
# 가중치 설정 !!!
weights = [1, 2],
n_jobs=-1
)
soft_clf.fit(X_train, y_train)
soft_clf_ypred = hard_clf.predict(X_val)
soft_clf_acc = accuracy_score(y_val, soft_clf_ypred)
```
=> 결과 acc 비교하여 모델 선정