⚙️ Models
📌 Gradient Boosting
- 개념 : 잔차를 이용하여 모델의 잔차를 점점 줄여나가는 방식
📌 Xgboost
- 개념 : Gradient Boosting을 최대한 빠르게 구현한 것
- 주요 파라미터
- objective : linear, logistic, softmax, softprob중 어떤 것을 사용할지에 대한 파라미터
- eval_metric : rmse, mae, logloss, error, merror, mlogloss, auc중 무엇으로 계산할지에 대한 파라미터
- random_state : 재현성을 위한 파라미터
- booster : gbtree, gblinear중 어떤 종류의 부스트를 쓸건지에 대한 파라미터
- silent : 동작 메시지 출력에 관한 파라미터
- N_estimators : 트리 모델의 개수
- Early_stopping_rounds : 최대한 몇 개의 트리를 완성할 지 정해 valid loss에 더 진전이 없는 경우 멈추기
- Learning_rate : 학습 단계별로 이전 결과를 얼마나 반영할지에 대한 파라미터
- Min_child_weight : child에서 필요한 모든 관측치에 대한 가중치의 최소합
- max_depth : 트리의 최대 깊이
- gamma : 트리에서 추가적으로 가지를 나눌지 결정하는 최소 손실 감소 값
- Subsample : 각 트리마다 데이터의 샘플링 비율
- Colsample_bytree : 각 트리마다 feature의 샘플링 비율
- reg_lambda : L2 규제(Ridge)
- reg_alpha : L1 규제(Lasso)
- scale_pos_weight : 데이터가 불균형 할때 사용
📌 Hyperparameter Tunning
- 개념 : 주어진 데이터에서 최적의 파라미터를 찾는 일
- Grid Search : 내가 생각해본 값들을 모두 다 테스트하는 것
- Random Grid Search : 내가 생각한 값의 범위 내에서 분포를 가지는 테스트 셋을 결정해 테스트하는 것
⚙️ Skills
📌 Encoding
- 라벨 인코딩 : 항목의 종류에 따라 정수값을 부여
- 원핫 인코딩 : 선택한 하나의 항목에 1을 부여하고, 나머지는 0을 부여
⚙️ 실습
📝 라벨 인코딩
# 숫자가 아닌 컬럼의 값을 숫자로 인코딩하기
from sklearn.preprocessing import LabelEncoder
items = ["TV", "냉장고", "세탁기", "TV", "냉장고"]
label_enc = LabelEncoder()
label_enc.fit(items)
label_items = label_enc.transform(items)
test_items = ["TV", "세탁기", "세탁기", "에어컨"]
# 에러 발생 -> 위에서 학습하지 않은 에어컨이 튀어나왔기 때문에!
# label_enc.transform(test_items)
# 따라서 다시 학습을 진행해야 함
# 단, 아래 경우는 기존 학습 내용이 사라짐
# label_enc.fit_transform(test_items)
# label_enc.classes_
# 이를 해소하기 위한 방법!
# 1. 기존 변환 수행
label_enc = LabelEncoder()
label_enc.fit(items)
prev_classes = list(label_enc.classes_)
# 2. unseen data 발생시, 새로운 룰 추가
for label in np.unique( test_items):
if label not in prev_classes:
prev_classes.append(label)
# 3. 새롭게 추가된 룰을 적용
label_enc.classes_ = np.array(prev_classes)
# 4. 갱신된 룰 적용
label_enc.transform(test_items)
📝 라벨 인코딩
# scikit-learn에는 한 번에 변환이 불가능하여 라벨 인코딩을 진행한 다음에 진행함.
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
# 1. 라벨 인코딩 진행
label_enc = LabelEncoder()
label_enc.fit(items)
label_items = label_enc.transform(items)
# 2. 원핫 인코딩으로 변환
oh_enc = OneHotEncoder()
oh_enc_items = label_items.reshape(-1, 1)
oh_enc.fit_transform(oh_enc_items).toarray()
📝 전처리 과정의 함수화
- Step 1. 누락된 데이터를 처리하는 함수
- 컬럼 : age, cabin, embarked
- 입력 : df
- 할일 : 위 3개 컬럼에 대해 누락 데이터 채우기
- 출력 : 위 3개 컬럼에서 누락된 데이터가 채워진 df
def check_fillna(df):
df.loc[:, "Age"].fillna( df.loc[:,"Age"].mean(), inplace=True)
df.loc[:, "Cabin"].fillna( "N", inplace=True)
df.loc[:, "Embarked"].fillna("N", inplace=True)
df.loc[:, "Fare"].fillna(0, inplace=True)
return df
- Step 2. 불필요한 컬럼들을 제거하는 함수
- 입력 : df
- 할일 : 불필요한 컬럼 제거하기
- 출력 : 특정 컬럼이 제거가 된 df
def drop_features(df):
df.drop([ "PassengerId", "Name", "Ticket"], axis=1, inplace=True)
return df
- Step 3. 숫자가 아닌 컬럼의 값을 숫자로 변경하는 함수
def encode_features(df):
df.loc[:,"Cabin"] = df.loc[:,"Cabin"].apply(lambda x: str(x)[:1])
cols = ["Cabin", "Sex","Embarked"]
for col in cols:
le = LabelEncoder()
le.fit(df.loc[:, col])
df.loc[:, col] = le.transform(df.loc[:, col])
return df
- Step 4. 과정을 통합하여 진행해주는 함수
def titanic_preprocessing(df):
df = check_fillna(df)
df = drop_features(df)
df = encode_features(df)
return df
data = pd.read_csv(path)
y_titanic = data.loc[:, "Survived"]
X_titanic = data.drop( "Survived", axis= 1)
X_titanic = titanic_preprocessing(X_titanic)
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, # 비율
random_state = 1234, # 시드값
stratify = y_titanic # 나눌 때의 비율 유지
)
# k-fold
from sklearn.model_selection import KFold
kfold = KFold(n_splits = 5, random_state = 1234, shuffle = True)
# stratified k-fold
from sklearn.model_selection import StratifiedKFold
str_kfold = StratifiedKFold(n_splits = 5, random_state = 1234, shuffle = True)
# repeated k-fold
from sklearn.model_selection import RepeatedKFold
rkfold = RepeatedKFold(n_splits = 5, random_state = 1234, n_repeats = 10)
# repeated stratified k-fold
from sklearn.model_selection import RepeatedStratifiedKFold
rskfold = RepeatedStratifiedKFold(n_splits = 5, random_state = 1234, n_repeats = 10)
📝 모델 학습
# 1) 모델을 학습하는 과정에서 필요한 모듈
from sklearn.model_selection import cross_val_score
# 2) 평가에 필요한 모듈
from sklearn.metrics import accuracy_score
# 3) Hyper Parameter Tunning에 필요한 모듈
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_jobs = -1)
scores = cross_val_score(knn,
X_train, y_train,
cv = kfold,
scoring = "accuracy")
for iter_count, acc in enumerate(scores):
print("KNN의 {0}번째 검증 ACC: {1:4f}".format(iter_count, acc))
print("KNN 모델의 Accuracy Mean: ", scores.mean())
print("KNN 모델의 Accuracy std: ", scores.std())
📝 Hyper Parameter Tunning
# 파라미터 지정
parameters = {
"n_neighbors" : [1, 3, 5, 7, 9, 11, 13, 15, 19, 21, 33, 51],
"algorithm" : ["auto", "ball_tree", "kd_tree"]
}
# 최적의 파라미터를 찾기 (RGS)
knn = KNeighborsClassifier(n_jobs = -1)
n_iter = 10
knn_kf_rgs = RandomizedSearchCV(knn,
param_distributions = parameters,
cv = kfold,
scoring = "accuracy",
n_jobs = -1,
random_state = 1234,
n_iter = n_iter)
knn_kf_rgs.fit(X_train, y_train)
# 제일 최적의 파라미터
knn_kf_rgs.best_params_
# 그 때의 성능(CV 결과에 대한 평균값)
knn_kf_rgs.best_score_
# 검증 과정
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 K-Fold RGS Val Accuracy Score: ", knn_kf_rgs_acc)
# RGS 결과에서 조금 더 디테일하게 GS로 찾아보기
parameters = {
"n_neighbors" : [7,9,11]
}
knn= KNeighborsClassifier(n_jobs= -1)
knn_kf_gs = GridSearchCV(knn,
param_grid = parameters,
cv = kfold,
scoring = "accuracy",
n_jobs = -1
)
knn_kf_gs.fit(X_train, y_train)
knn_kf_gs.best_score_
knn_kf_gs.cv_results_