deflgb_roc_eval(num_leaves,colsample_bytree,subsample,max_depth,reg_alpha,reg_lambda,min_split_gain,min_child_weight,subsample_freq,max_bin):params={'learning_rate':0.01,'num_leaves':int(round(num_leaves)),# 호출 시 실수형 값이 들어오므로 정수형 하이퍼 파라미터는 정수형으로 변경 'colsample_bytree':colsample_bytree,'subsample':subsample,'max_depth':int(round(max_depth)),'reg_alpha':reg_alpha,'reg_lambda':reg_lambda,'min_split_gain':min_split_gain,'min_child_weight':min_child_weight,'subsample_freq':int(round(subsample_freq)),'max_bin':int(round(max_bin)),}lgb_model=LGBMClassifier(**params)lgb_model.fit(bayes_x,bayes_y,eval_set=[(bayes_x_test,bayes_y_test)],early_stopping_rounds=100,eval_metric="auc",verbose=False)valid_proba=lgb_model.predict_proba(bayes_x_test,num_iteration=10)[:,1]roc_preds=roc_auc_score(bayes_y_test,valid_proba)returnroc_preds
이 노트의 목적 그 전까지는 사이킷런으로 lightGBM, Catboost 모델링 한 것을 kaggle에 summit 했었다. 하지만 pycaret을 사용하여 lightGBM과 Catboost를 자동으로 하이퍼 파라미터 튜닝 하여 기존의 점수와 비교해보려 한다.
-결과 *사이킷런으로 스스로 하이퍼파라미터 튜닝한 것 보다, pycaret tune_model로 하이퍼 파라미터 튜닝한 것이 kaggle 점수가 높게 나왔다. *
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# This Python 3 environment comes with many helpful analytics libraries installed # It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python # For example, here's several helpful packages to load
import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
# Input data files are available in the read-only "../input/" directory # For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory
import os for dirname, _, filenames in os.walk('/kaggle/input'): for filename in filenames: print(os.path.join(dirname, filename))
# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" # You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
1
!pip install scikit-learn==0.23.2
Collecting scikit-learn==0.23.2
Downloading scikit_learn-0.23.2-cp37-cp37m-manylinux1_x86_64.whl (6.8 MB)
[K |████████████████████████████████| 6.8 MB 5.4 MB/s
[?25hRequirement already satisfied: scipy>=0.19.1 in /opt/conda/lib/python3.7/site-packages (from scikit-learn==0.23.2) (1.5.4)
Requirement already satisfied: threadpoolctl>=2.0.0 in /opt/conda/lib/python3.7/site-packages (from scikit-learn==0.23.2) (2.1.0)
Requirement already satisfied: joblib>=0.11 in /opt/conda/lib/python3.7/site-packages (from scikit-learn==0.23.2) (1.0.1)
Requirement already satisfied: numpy>=1.13.3 in /opt/conda/lib/python3.7/site-packages (from scikit-learn==0.23.2) (1.19.5)
Installing collected packages: scikit-learn
Attempting uninstall: scikit-learn
Found existing installation: scikit-learn 0.24.1
Uninstalling scikit-learn-0.24.1:
Successfully uninstalled scikit-learn-0.24.1
[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
pyldavis 3.3.1 requires numpy>=1.20.0, but you have numpy 1.19.5 which is incompatible.
pdpbox 0.2.1 requires matplotlib==3.1.1, but you have matplotlib 3.4.0 which is incompatible.
imbalanced-learn 0.8.0 requires scikit-learn>=0.24, but you have scikit-learn 0.23.2 which is incompatible.[0m
Successfully installed scikit-learn-0.23.2
import pandas as pd import numpy as np import random import os
from sklearn.metrics import accuracy_score from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.model_selection import train_test_split, KFold, StratifiedKFold
import lightgbm as lgb import catboost as ctb from sklearn.model_selection import GridSearchCV from sklearn.tree import DecisionTreeClassifier, export_graphviz
import graphviz import matplotlib.pyplot as plt import seaborn as sns
print('Rows and Columns in train dataset:', train_df.shape) print('Rows and Columns in test dataset:', test_df.shape)
Rows and Columns in train dataset: (100000, 12)
Rows and Columns in test dataset: (100000, 11)
결측치 갯수 출력
1 2 3 4 5 6 7 8 9
print('Missing values per columns in train dataset') for col in train_df.columns: temp_col = train_df[col].isnull().sum() print(f'{col}: {temp_col}') print() print('Missing values per columns in test dataset') for col in test_df.columns: temp_col = test_df[col].isnull().sum() print(f'{col}: {temp_col}')
#cabin은 문자열을 분할하고, 제일 첫번째 글자를 따와서 넣는다. 결측치엔 X를 넣는다. #strip() : 양쪽 공백을 지운다. 여기서느 x[0]외엔 다 지우는듯. all_df['Cabin'] = all_df['Cabin'].fillna('X').map(lambda x: x[0].strip())
#print(all_df['Ticket'].head(10)) #Ticket, fillna with 'X', split string and take first split #split() : 문자열 나누기. 디폴트는 ' '이고, 문자를 가진 데이터들이 전부 띄워쓰기로 구분되어있기때문에 가능. all_df['Ticket'] = all_df['Ticket'].fillna('X').map(lambda x:str(x).split()[0] iflen(str(x).split()) > 1else'X')
#pclass에 따른 Fare의 평균을 구해서 dictionary형태로 만든다. fare_map = all_df[['Fare', 'Pclass']].dropna().groupby('Pclass').median().to_dict() #fare의 결측치에 본인 행의 pclass 값을 넣고, 그 값을 fare 평균에 맵핑시킨다. all_df['Fare'] = all_df['Fare'].fillna(all_df['Pclass'].map(fare_map['Fare'])) #유독 높은 가격이나 낮은 가격이 있기때문에, 이상치의 영향을 줄이기 위해서 Fare에 log를 취해준다. all_df['Fare'] = np.log1p(all_df['Fare'])
# This Python 3 environment comes with many helpful analytics libraries installed # It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python # For example, here's several helpful packages to load
import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
# Input data files are available in the read-only "../input/" directory # For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory
import os for dirname, _, filenames in os.walk('/kaggle/input'): for filename in filenames: print(os.path.join(dirname, filename))
# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" # You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
import pandas as pd import numpy as np import random import os
from sklearn.metrics import accuracy_score from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.model_selection import train_test_split, KFold, StratifiedKFold
import lightgbm as lgb import catboost as ctb from sklearn.model_selection import GridSearchCV from sklearn.tree import DecisionTreeClassifier, export_graphviz
import graphviz import matplotlib.pyplot as plt import seaborn as sns
import warnings warnings.simplefilter('ignore')
1
!pip install kaggle
Requirement already satisfied: kaggle in /usr/local/lib/python3.7/dist-packages (1.5.12)
Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/dist-packages (from kaggle) (2.8.1)
Requirement already satisfied: urllib3 in /usr/local/lib/python3.7/dist-packages (from kaggle) (1.24.3)
Requirement already satisfied: requests in /usr/local/lib/python3.7/dist-packages (from kaggle) (2.23.0)
Requirement already satisfied: six>=1.10 in /usr/local/lib/python3.7/dist-packages (from kaggle) (1.15.0)
Requirement already satisfied: certifi in /usr/local/lib/python3.7/dist-packages (from kaggle) (2020.12.5)
Requirement already satisfied: python-slugify in /usr/local/lib/python3.7/dist-packages (from kaggle) (4.0.1)
Requirement already satisfied: tqdm in /usr/local/lib/python3.7/dist-packages (from kaggle) (4.41.1)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests->kaggle) (3.0.4)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests->kaggle) (2.10)
Requirement already satisfied: text-unidecode>=1.3 in /usr/local/lib/python3.7/dist-packages (from python-slugify->kaggle) (1.3)
print('Rows and Columns in train dataset:', train_df.shape) print('Rows and Columns in test dataset:', test_df.shape)
Rows and Columns in train dataset: (100000, 12)
Rows and Columns in test dataset: (100000, 11)
결측치 갯수 출력
1 2 3 4 5 6 7 8 9
print('Missing values per columns in train dataset') for col in train_df.columns: temp_col = train_df[col].isnull().sum() print(f'{col}: {temp_col}') print() print('Missing values per columns in test dataset') for col in test_df.columns: temp_col = test_df[col].isnull().sum() print(f'{col}: {temp_col}')
#cabin은 문자열을 분할하고, 제일 첫번째 글자를 따와서 넣는다. 결측치엔 X를 넣는다. #strip() : 양쪽 공백을 지운다. 여기서느 x[0]외엔 다 지우는듯. all_df['Cabin'] = all_df['Cabin'].fillna('X').map(lambda x: x[0].strip())
#print(all_df['Ticket'].head(10)) #Ticket, fillna with 'X', split string and take first split #split() : 문자열 나누기. 디폴트는 ' '이고, 문자를 가진 데이터들이 전부 띄워쓰기로 구분되어있기때문에 가능. all_df['Ticket'] = all_df['Ticket'].fillna('X').map(lambda x:str(x).split()[0] iflen(str(x).split()) > 1else'X')
#pclass에 따른 Fare의 평균을 구해서 dictionary형태로 만든다. fare_map = all_df[['Fare', 'Pclass']].dropna().groupby('Pclass').median().to_dict() #fare의 결측치에 본인 행의 pclass 값을 넣고, 그 값을 fare 평균에 맵핑시킨다. all_df['Fare'] = all_df['Fare'].fillna(all_df['Pclass'].map(fare_map['Fare'])) #유독 높은 가격이나 낮은 가격이 있기때문에, 이상치의 영향을 줄이기 위해서 Fare에 log를 취해준다. all_df['Fare'] = np.log1p(all_df['Fare'])
for train_idx, test_idx in kfold.split(train_kf_feature,train_kf_label):
X_train=train_kf_feature.iloc[train_idx] X_test=train_kf_feature.iloc[test_idx] y_train,y_test=train_kf_label.iloc[train_idx],train_kf_label.iloc[test_idx] #학습 진행 lgbm_model.fit(X_train,y_train) #예측 fold_pred=lgbm_model.predict(X_test) #정확도 n_iter+=1 fold_accuracy=metrics.accuracy_score(y_test,fold_pred) print("\n {}번째 교차 검증 정확도 : {} , 학습 데이터 크기:{}, 검증 데이터 크기 :{} ". format(n_iter,fold_accuracy,X_train.shape[0],X_test.shape[0])) cv_accuracy.append(fold_accuracy) #중요도 fi_tmp = pd.DataFrame() fi_tmp["feature"] = lgbm_temp.feature_name() fi_tmp["importance"] = lgbm_model.feature_importances_ feature_importances = feature_importances.append(fi_tmp)
print('\n 평균 검증 정확도 : ',np.mean(cv_accuracy))
1번째 교차 검증 정확도 : 0.78015 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
2번째 교차 검증 정확도 : 0.7824 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
3번째 교차 검증 정확도 : 0.78185 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
4번째 교차 검증 정확도 : 0.7816 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
5번째 교차 검증 정확도 : 0.7809 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
평균 검증 정확도 : 0.78138
for train_idx, test_idx in kfold.split(train_kf_feature,train_kf_label):
X_train=train_kf_feature.iloc[train_idx] X_test=train_kf_feature.iloc[test_idx] y_train,y_test=train_kf_label.iloc[train_idx],train_kf_label.iloc[test_idx] #학습 진행 cat_model.fit(X_train,y_train,verbose=500) #예측 fold_pred=cat_model.predict(X_test) #정확도 n_iter+=1 fold_accuracy=metrics.accuracy_score(y_test,fold_pred) print("\n {}번째 교차 검증 정확도 : {} , 학습 데이터 크기:{}, 검증 데이터 크기 :{} ". format(n_iter,fold_accuracy,X_train.shape[0],X_test.shape[0])) cv_accuracy.append(fold_accuracy) #중요도 . lgbm이랑 명령어가 다르다. fi_tmp = pd.DataFrame() fi_tmp["feature"] = X_test.columns.to_list() fi_tmp["importance"] = cat_model.get_feature_importance() feature_importances = feature_importances.append(fi_tmp)
print('\n 평균 검증 정확도 : ',np.mean(cv_accuracy))
0: learn: 0.6881430 total: 11.2ms remaining: 11.2s
500: learn: 0.4620724 total: 5.17s remaining: 5.15s
999: learn: 0.4513527 total: 10.2s remaining: 0us
6번째 교차 검증 정확도 : 0.77945 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
0: learn: 0.6881914 total: 12.4ms remaining: 12.3s
500: learn: 0.4635447 total: 5.02s remaining: 5s
999: learn: 0.4529141 total: 10.2s remaining: 0us
7번째 교차 검증 정확도 : 0.78335 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
0: learn: 0.6881970 total: 13.6ms remaining: 13.6s
500: learn: 0.4635994 total: 5.2s remaining: 5.18s
999: learn: 0.4529137 total: 10.3s remaining: 0us
8번째 교차 검증 정확도 : 0.78265 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
0: learn: 0.6882583 total: 11.2ms remaining: 11.2s
500: learn: 0.4622575 total: 5.08s remaining: 5.06s
999: learn: 0.4513804 total: 10.1s remaining: 0us
9번째 교차 검증 정확도 : 0.7821 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
0: learn: 0.6882789 total: 15.4ms remaining: 15.3s
500: learn: 0.4630108 total: 5.1s remaining: 5.08s
999: learn: 0.4522854 total: 10.1s remaining: 0us
10번째 교차 검증 정확도 : 0.7802 , 학습 데이터 크기:80000, 검증 데이터 크기 :20000
평균 검증 정확도 : 0.78155
1 2 3 4 5 6
# just to get ideas to improve order = list(feature_importances.groupby("feature").mean().sort_values("importance", ascending=False).index) plt.figure(figsize=(10, 10)) sns.barplot(x="importance", y="feature", data=feature_importances, order=order) plt.title("{} importance".format("CatBoostClassifier")) plt.tight_layout()
가독성, 코드도 중요하지만, 코드를 돌려 나온 결과들을 표로 정리해서 성능들을 비교하는게 좋다.
결론이 필요하다.
디테일한 내용이 필요. 한계는 뭔지
깔끔함 필요.
1. 가독성 보완을 위해 표를 작성
청자에게 전달을 잘 하기 위해서 뿐만이 아니라, 결과 발표를 잘 하기 위해서는 결과를 표로 정리하는 것이 필요하다고 느꼈다.
2. 결론 필요성
대체적인 결과에대한 분석은 있었지만, 나의 결론이 부족하다는 것을 깨달았다. 그래서 내린 결론은, 범주형 데이터를 할때에는 시간이 오래걸려도 CatBoost를 사용하는게 가장 좋을 것이라 생각하고, 다른 수치형 데이터들을 다룰때에는 속도 측면에서 압도적인 lightBGM이 좋을 것이라 느꼈다. 그리고 하이퍼 파라미터 튜닝을 할 때에는 하이퍼 파라미터가 다양하고 다이나믹하게 적용되는 XGBoost를 사용하는것이 좋을것이라는 생각이 들었다.
또한 Grid 서치와 Random 서치는 데이터마다 어떤 방식을 사용해야할지 다르게 판단해야한다고 생각했다.
3. 디테일한 내용과 한계
디테일한 내용은 실습파일에다가 추가 보완 기재를 하였고, 우리가 실습한 것의 한계는 우리들의 지식 수준과 Feature Engineering을 주체적으로 하지 못한것에 있다고 생각한다. 또한 하이퍼파라미터를 다양하게 구사하기에는 속도가 너무 오래걸릴 뿐더러, 경험적 지식이 부족하여 튜닝을 많이 해보아야 할 것같다는 생각이 들었다.
4. 깔끔함.
깔끔해 보이는것은 시각화와 연관되어있다고 생각한다. 1번에서 다루었듯, 표를 만들어 깔끔하게 정리를 했다면 발표가 좀 더 체계적으로 보였을 것이라 생각한다.
결론
강사님이 말씀하신 것을 피드백하여 다음부턴 시각화에 조금더 신경쓰고, 퀄리티 있는 자료를 만들어야겠다는 생각을 했다. 시각화가 된 자료로 잘 정제된 결론도 도출할 것이다.
라벨인코더 (LabelEncoder) 문자를 숫자(수치화), 숫자를 문자로 매핑 문자를 0부터 시작하는 정수형 숫자로 바꿔주는 기능을 제공한다.
sklearn.model_selection.StratifiedKFold K-FOLD 교차검증을 위한 함수 Parameters
n_splits : default=5
shuffle : bool, default=False
random_state: (int) default=None
각 클래스에대한 폴드의 랜덤성을 제어하는 인덱스들에 순서를 부여하고 그 순서의 영향을 미치게 한다.
텍스트 마이닝 (text Mining)
텍스트마이닝은 자연어처리 기술에 기반한다. 인간 언어 중 문자로 표현된 언어를 컴퓨터로 분석 처리하고 그 구조와 의미를 이해하고자하는 기술이 바로 자연언어처리기술이다. 텍스트 마이닝은 한마디로 비정형 텍스트 데이터에서 가치와 의미가 있는 정보를 찾아내는(mining) 기술이라고 할 수 있다. 사용자는 텍스트 마이닝 기술을 통해 방대한 정보 뭉치에서 의미있는 정보를 추출해내고, 다른 정보와의 연계성을 파악하며, 텍스트가 가진 카테고리를 찾아내는 등, 단순한 정보 검색 그 이상의 결과를 얻어 낼 수 있다. 컴퓨터가 인간이 사용하는 언어로 기술된 정보를 깊이 분석하고 그 안에 숨겨진 정보를 발굴해내기 위해서는 대용량 언어 자원과 복잡한 통계적, 규칙적 알고리즘이 적용되어야만 한다.
교차 검증
Train set과 test set으로 평가를 하고 반복적으로 모델을 튜닝하다보면 test set에만 과적합되는 결과가 생긴다. 내가 만든 모델이 test set에만 잘 동작하는 모델이 되는 것이다. 이 문제를 해결하고자 교차검증이 필요하다. 과적합의 원인은 test set이 데이터 중 일부분으로 고정되어있고, 이 일부분의 데이터셋에 대해 성능이 잘 나오도록 파라미터를 반복적으로 튜닝하기 때문에 발생한다. 교차검증은 데이터의 모든 부분을 사용하여 모델을 검증하고 test set을 하나로 고정하지않는다. 전체 데이터셋을 k개의 subset으로 나누고 k번의 평가를 실행하는데, 이때 test set을 중복없이 바꾸어가면서 평가를 진행한다.
K-Fold 교차검증
정의 : K개의 fold를 만들어서 진행하는 교차 검증 사용 이유
총 데이터 개수가 적은 데이터 셋에대해 정확도 향상
Train, valid, test 세개의 데이터셋으로 분류하는것보다 train과 test로만 분류할 때 학습 데이터 셋이 더 많기 때문
과정
기존 과정과 같이 training set와 test set을 나눈다
Training을 k개의 fold로 나눈다(위의 그림은 5개로 나눔
한 개의 fold에 있는 데이터를 다시 k개로 쪼갠 다음, k-1개는 training data, 마지막 한 개한 validation Data set으로 지정한다.
모델을 생성하고 예측을 진행하여 이에대한 에러값을 추출한다.
다음 Fold에서는 Vaildation set을 바꿔서 지정하고, 이전 Fold에서 Validation역할을 했던 Set은 다시 training set으로 활용한다.
이를 K번 반복한다.
Posted Updated 2 hours read (About 13601 words)
Titanic data
결정 트리, 랜덤포레스트, XGBoost, lightBGM, CATBoost 비교
전처리
1
!pip install catboost
Requirement already satisfied: catboost in /usr/local/lib/python3.7/dist-packages (0.25.1)
Requirement already satisfied: plotly in /usr/local/lib/python3.7/dist-packages (from catboost) (4.4.1)
Requirement already satisfied: graphviz in /usr/local/lib/python3.7/dist-packages (from catboost) (0.10.1)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from catboost) (1.15.0)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from catboost) (3.2.2)
Requirement already satisfied: pandas>=0.24.0 in /usr/local/lib/python3.7/dist-packages (from catboost) (1.1.5)
Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from catboost) (1.4.1)
Requirement already satisfied: numpy>=1.16.0 in /usr/local/lib/python3.7/dist-packages (from catboost) (1.19.5)
Requirement already satisfied: retrying>=1.3.3 in /usr/local/lib/python3.7/dist-packages (from plotly->catboost) (1.3.3)
Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (2.8.1)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (1.3.1)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (2.4.7)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (0.10.0)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.24.0->catboost) (2018.9)
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import xgboost as xgb import lightgbm as lgbm import catboost as cb from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC from sklearn.ensemble import AdaBoostClassifier from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics from sklearn.model_selection import RandomizedSearchCV
-----
Best parameters {'max_depth': 11}
Mean cross-validated accuracy score of the best_estimator: 0.817
-----
CPU times: user 191 ms, sys: 4.34 ms, total: 196 ms
Wall time: 205 ms
-----
Best parameters {'max_depth': 11}
Mean cross-validated accuracy score of the best_estimator: 0.817
-----
CPU times: user 166 ms, sys: 680 µs, total: 167 ms
Wall time: 168 ms
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_search.py:281: UserWarning: The total space of parameters 6 is smaller than n_iter=50. Running 6 iterations. For exhaustive searches, use GridSearchCV.
% (grid_size, self.n_iter, grid_size), UserWarning)
print('-----') print(f'Best parameters {model_random_forest.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: '+ \ f'{model_random_forest.best_score_:.3f}' ) cross_valid_scores['random_forest'] = model_random_forest.best_score_ print('-----')
-----
Best parameters {'max_depth': 11, 'n_estimators': 25}
Mean cross-validated accuracy score of the best_estimator: 0.844
-----
CPU times: user 4.93 s, sys: 30.4 ms, total: 4.96 s
Wall time: 4.98 s
print('-----') print(f'Best parameters {model2_random_forest_rs.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: '+ \ f'{model2_random_forest_rs.best_score_:.3f}' ) cross_valid_scores['random_forest'] = model2_random_forest_rs.best_score_ print('-----')
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_search.py:281: UserWarning: The total space of parameters 30 is smaller than n_iter=50. Running 30 iterations. For exhaustive searches, use GridSearchCV.
% (grid_size, self.n_iter, grid_size), UserWarning)
-----
Best parameters {'n_estimators': 25, 'max_depth': 11}
Mean cross-validated accuracy score of the best_estimator: 0.844
-----
CPU times: user 4.88 s, sys: 35.5 ms, total: 4.92 s
Wall time: 4.92 s
print('-----') print(f'Best parameters {model_xgb.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: ' + f'{model_xgb.best_score_:.3f}' ) cross_valid_scores['xgboost'] = model_xgb.best_score_ print('-----')
-----
Best parameters {'learning_rate': 0.1, 'max_depth': 7, 'n_estimators': 100}
Mean cross-validated accuracy score of the best_estimator: 0.846
-----
CPU times: user 13.8 s, sys: 189 ms, total: 14 s
Wall time: 14.1 s
xgboost에서 하이퍼파라미터튜닝을 위해 GridSearch를 진행. time : 14.3 s Best parameters {‘n_estimators’: 100, ‘max_depth’: 7, ‘learning_rate’: 0.1}
-----
Best parameters {'n_estimators': 100, 'max_depth': 7, 'learning_rate': 0.1}
Mean cross-validated accuracy score of the best_estimator: 0.846
-----
CPU times: user 9.31 s, sys: 113 ms, total: 9.42 s
Wall time: 9.41 s
xgboost에서 두 서치의 성능을 보기위해 똑같은 환경에서 RandomSearch를 진행. time : 9.46 s Best parameters {‘n_estimators’: 100, ‘max_depth’: 7, ‘learning_rate’: 0.1}
print('-----') print(f'Best parameters {model_lgbm.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: ' + f'{model_lgbm.best_score_:.3f}' ) cross_valid_scores['lightgbm'] = model_lgbm.best_score_ print('-----')
/usr/local/lib/python3.7/dist-packages/lightgbm/basic.py:1209: UserWarning: categorical_feature in Dataset is overridden.
New categorical_feature is ['Embarked', 'IsAlone', 'Sex', 'TicketNumber', 'Title']
'New categorical_feature is {}'.format(sorted(list(categorical_feature))))
-----
Best parameters {'learning_rate': 0.1, 'n_estimators': 25, 'num_leaves': 15}
Mean cross-validated accuracy score of the best_estimator: 0.827
-----
CPU times: user 5.83 s, sys: 346 ms, total: 6.18 s
Wall time: 6.2 s
-----
Best parameters {'num_leaves': 31, 'n_estimators': 100, 'learning_rate': 0.05}
Mean cross-validated accuracy score of the best_estimator: 0.846
-----
CPU times: user 4.66 s, sys: 210 ms, total: 4.87 s
Wall time: 4.87 s
print('-----') print(f'Best parameters {model_catboost_rs.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: ' + f'{model_catboost_rs.best_score_:.3f}' ) cross_valid_scores['catboost'] = model_catboost_rs.best_score_ print('-----')
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_validation.py:536: FitFailedWarning: Estimator fit failed. The score on this train-test partition for these parameters will be set to nan. Details:
_catboost.CatBoostError: catboost/private/libs/options/catboost_options.cpp:893: max_leaves option works only with lossguide tree growing
FitFailedWarning)
-----
Best parameters {'num_leaves': 31, 'n_estimators': 100, 'learning_rate': 0.01}
Mean cross-validated accuracy score of the best_estimator: 0.832
-----
CPU times: user 6.45 s, sys: 702 ms, total: 7.15 s
Wall time: 7.18 s
여기서 우리가 하이퍼 파라미터 튜닝을 위해 넣은 n_estimators= 25는 랜덤포레스트를 구성하는 나무의 갯수를 뜻한다. 기본 파라미터는 100개인데, 튜닝에서 25를 넣어주니 정확도도 더 올라갔고, 속도도 더 줄어듬을 확인 할 수 있었다. 이것은 자료의 양이 많지않아 25개의 트리로 구성하는게 더 빠르고 적합하다 것을 의미한다.
그리고 나는 이 데이터에서 Cat부스트의 성능에 주목했다. cat부스트에서 주목해야할 점은, 다른 모형들에 비해 기본적으로 뛰어난 정확도이다. 이것은 Cat부스트의 특징때문인데, cat부스트는 수치형데이터보다 범주형 데이터 분석에 더 탁월한 성능을 가지고있다. 그래서 하이퍼 파라미터 튜닝후에는 정확도가 0.988인, 거의 1에 가까운 값이 나왔다고 생각한다
Posted Updated 14 minutes read (About 2100 words)
Titanic data
결정 트리, 랜덤포레스트, XGBoost, lightBGM, CATBoost 비교
전처리
1
!pip install catboost
Collecting catboost
[?25l Downloading https://files.pythonhosted.org/packages/47/80/8e9c57ec32dfed6ba2922bc5c96462cbf8596ce1a6f5de532ad1e43e53fe/catboost-0.25.1-cp37-none-manylinux1_x86_64.whl (67.3MB)
[K |████████████████████████████████| 67.3MB 57kB/s
[?25hRequirement already satisfied: plotly in /usr/local/lib/python3.7/dist-packages (from catboost) (4.4.1)
Requirement already satisfied: scipy in /usr/local/lib/python3.7/dist-packages (from catboost) (1.4.1)
Requirement already satisfied: numpy>=1.16.0 in /usr/local/lib/python3.7/dist-packages (from catboost) (1.19.5)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from catboost) (3.2.2)
Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from catboost) (1.15.0)
Requirement already satisfied: pandas>=0.24.0 in /usr/local/lib/python3.7/dist-packages (from catboost) (1.1.5)
Requirement already satisfied: graphviz in /usr/local/lib/python3.7/dist-packages (from catboost) (0.10.1)
Requirement already satisfied: retrying>=1.3.3 in /usr/local/lib/python3.7/dist-packages (from plotly->catboost) (1.3.3)
Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (1.3.1)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (2.4.7)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (0.10.0)
Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->catboost) (2.8.1)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.24.0->catboost) (2018.9)
Installing collected packages: catboost
Successfully installed catboost-0.25.1
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import xgboost as xgb import lightgbm as lgbm import catboost as cb from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC from sklearn.ensemble import AdaBoostClassifier from sklearn.neighbors import KNeighborsClassifier
from sklearn import metrics from sklearn.model_selection import RandomizedSearchCV
-----
Best parameters {'max_depth': 11}
Mean cross-validated accuracy score of the best_estimator: 0.817
-----
CPU times: user 180 ms, sys: 2.04 ms, total: 182 ms
Wall time: 202 ms
print('-----') print(f'Best parameters {model_random_forest.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: '+ \ f'{model_random_forest.best_score_:.3f}' ) cross_valid_scores['random_forest'] = model_random_forest.best_score_ print('-----')
-----
Best parameters {'max_depth': 11, 'n_estimators': 25}
Mean cross-validated accuracy score of the best_estimator: 0.844
-----
CPU times: user 4.84 s, sys: 43 ms, total: 4.89 s
Wall time: 4.9 s
print('-----') print(f'Best parameters {model2_random_forest_rs.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: '+ \ f'{model2_random_forest_rs.best_score_:.3f}' ) cross_valid_scores['random_forest'] = model2_random_forest_rs.best_score_ print('-----')
/usr/local/lib/python3.7/dist-packages/sklearn/model_selection/_search.py:281: UserWarning: The total space of parameters 30 is smaller than n_iter=50. Running 30 iterations. For exhaustive searches, use GridSearchCV.
% (grid_size, self.n_iter, grid_size), UserWarning)
-----
Best parameters {'n_estimators': 25, 'max_depth': 11}
Mean cross-validated accuracy score of the best_estimator: 0.844
-----
CPU times: user 4.68 s, sys: 27.1 ms, total: 4.71 s
Wall time: 4.73 s
print('-----') print(f'Best parameters {model_xgb.best_params_}') print( f'Mean cross-validated accuracy score of the best_estimator: ' + f'{model_xgb.best_score_:.3f}' ) cross_valid_scores['xgboost'] = model_xgb.best_score_ print('-----')
-----
Best parameters {'learning_rate': 0.1, 'max_depth': 7, 'n_estimators': 100}
Mean cross-validated accuracy score of the best_estimator: 0.846
-----
CPU times: user 13.7 s, sys: 177 ms, total: 13.9 s
Wall time: 14 s
xgboost에서 하이퍼파라미터튜닝을 위해 GridSearch를 진행. time : 14.3 s Best parameters {‘n_estimators’: 100, ‘max_depth’: 7, ‘learning_rate’: 0.1}
-----
Best parameters {'n_estimators': 100, 'max_depth': 7, 'learning_rate': 0.1}
Mean cross-validated accuracy score of the best_estimator: 0.846
-----
CPU times: user 9.22 s, sys: 119 ms, total: 9.34 s
Wall time: 9.34 s
xgboost에서 두 서치의 성능을 보기위해 똑같은 환경에서 RandomSearch를 진행. time : 9.46 s Best parameters {‘n_estimators’: 100, ‘max_depth’: 7, ‘learning_rate’: 0.1}
df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=list("ABCD"))#가우시안 표준 정규분포에서 난수 matrix array생성f=pd.DataFrame(np.random.randn(6,4),index=dates,columns=list("ABCD")) #가우시안 표준 정규분포에서 난수 matrix array생성df
Out[ ]:
A
B
C
D
2013-01-01
0.076484
0.747200
0.378133
-0.459580
2013-01-02
0.331515
-0.308679
2.492327
1.544272
2013-01-03
0.175129
1.136551
1.649191
1.887292
2013-01-04
-0.602191
0.424951
1.219719
0.728339
2013-01-05
-0.289813
0.310278
1.205465
1.814098
2013-01-06
0.123148
2.174075
-0.157369
-0.103182
직렬로 변환할수있는 dict형을 데이터 프레임으로 생성한다.
In [ ]:
df2=pd.DataFrame({#keys는 자동으로 열의 이름이 된다. "A":1.0,#비어있는 값들에 전부 1.0이 들어감"B":pd.Timestamp("20130102"),"C":pd.Series(1,index=list(range(4)),dtype="float32"),"D":np.array([3]*4,dtype="int32"),# 배열 3 , 3, 3, 3 생긴거 차례대로 들어감."E":pd.Categorical(["test","train","test","train"]),"F":"foo"})df2
Out[ ]:
A
B
C
D
E
F
0
1.0
2013-01-02
1.0
3
test
foo
1
1.0
2013-01-02
1.0
3
train
foo
2
1.0
2013-01-02
1.0
3
test
foo
3
1.0
2013-01-02
1.0
3
train
foo
In [ ]:
df2.dtypes
Out[ ]:
A float64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
Numpy배열은 전체 배열에 대해 하나의 dtype을 가지고있고, pandas DataFrame은 열당 하나의 dtype을 가진다. Numpy를 사용해서 dataFrame을 불러오려면 모든 dtype을 저장할 수 있는 Numpy 유형을 찾기때문에 모든 값들을 따로 Python 객체에 캐스팅 해야한다는 뜻이다. 그래서 Numpy로 DataFrame을 작업하려면 많은 것을 감당해야한다.
여기서 df는 하나의 dtype이므로 DataFrame.to_numpy()를 사용하면 빠르고 데이터 복사가 필요없다.
fig,ax=plt.subplots()# 틀 그리기.#fig는 figure로써 전체 subplot을 말한다. 서브플롯 안에 몇개의 그래프가있던지 그걸 담는 틀.#ax는 axe로써 전체중 낱낱개를 말한다. 그래프의 수가 많아지면 배열 형태로 저장. ex) ax[1], ax[3]ax.bar(tips_day["day"],tips_day["tip"],color="lightgray")#bar그리기ax.set_title("tip (mean)",fontsize=16,pad=12)#타이틀 그리기plt.show()
In [13]:
ax.patches#ax에 있는 patches? 서브플롯 안의 객체를 말하는 듯.
Out[13]:
[<matplotlib.patches.Rectangle at 0x7f3e844b0450>,
<matplotlib.patches.Rectangle at 0x7f3e844f47d0>,
<matplotlib.patches.Rectangle at 0x7f3e844b0890>,
<matplotlib.patches.Rectangle at 0x7f3e8443d310>]
Rectangle 객체가 4개 있다는 뜻이다. 높이를 확인하면 요일별 평균 데이터가 그대로 있다.
In [14]:
foriinrange(len(ax.patches)):print(f"height of patch[{i}] = {ax.patches[i].get_height()}")
height of patch[0] = 2.771451612903226
height of patch[1] = 2.734736842105263
height of patch[2] = 2.993103448275862
height of patch[3] = 3.255131578947369
#일요일 데이터만 골라서 짙은 빨강 칠하기fig,ax=plt.subplots()ax.bar(tips_day["day"],tips_day["tip"],color="lightgray")ax.set_title("tip (mean)",fontsize=16,pad=12)# Sunday#sunday는 4번째 객체이므로 patches[3]ax.patches[3].set_facecolor("darkred")#facecolor. 안의 바탕색ax.patches[3].set_edgecolor("black")#edgecolor 외관선 색plt.show()
fig,ax=plt.subplots()ax.bar(tips_day["day"],tips_day["tip"],color="lightgray")ax.set_title("tip (mean)",fontsize=16,pad=12)# Valuesh_pad=0.1#글자 배치를 위한 패드를 깔아주기foriinrange(4):fontweight="normal"color="k"ifi==3:# Sundayfontweight="bold"#sunday일때 굵은 글씨color="darkred"#어두운 붉은 글씨#그래프 객체에 텍스트 붙이는 함수 ax.textax.text(i,tips_day["tip"].loc[i]+h_pad,f"{tips_day['tip'].loc[i]:0.2f}",#글자 색 지정horizontalalignment='center',fontsize=12,fontweight=fontweight,color=color)#글자 색 지정 tips_day['tip']은 tip열거 뽑아낸거, loc은 그중에 i번째, 0.2f는 소숫점 두자리까지만.# Sundayax.patches[3].set_facecolor("darkred")ax.patches[3].set_edgecolor("black")# set_rangeax.set_ylim(0,4)plt.show()
odict_values([<matplotlib.spines.Spine object at 0x7f3e84001650>, <matplotlib.spines.Spine object at 0x7f3e840b35d0>, <matplotlib.spines.Spine object at 0x7f3e8414af90>, <matplotlib.spines.Spine object at 0x7f3e84096f50>])
공식 문서에따르면 Spine은 Patch의 subclass이고 set_patch_circle,set_patch_arc가 호출되면 원이나 호를 그리기도 한다. 선을 그리는 set_patch_line이 기본값이다.
Spine 숨기기? : set_visible(False)
In [28]:
fig,ax=plt.subplots()ax=plot_example(ax)ax.spines["top"].set_visible(False)ax.spines["left"].set_visible(False)ax.spines["right"].set_visible(False)#위,옆 축들을 다 지워버렸다.
In [29]:
fig,ax=plt.subplots()ax=plot_example(ax)ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["left"].set_bounds(1,3)#set_bounds를 이용해서 1~3까지만 축을 그렸다.
#포지션을 통해서 left축(y축)과 그래프 간격을 띄운다fig,ax=plt.subplots()ax=plot_example(ax)ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["left"].set_position(("outward",10))##set_position을 이용해 left 축을 10만큼 띄운다.
In [31]:
#만약 축을 안쪽으로 당겨오고 싶으면 outward 음수 값을 넣는다. fig,ax=plt.subplots(ncols=3,figsize=(15,3))foriinrange(3):# 그래프 세개 한번에 그리기ax[i]=plot_example(ax[i])ax[i].spines["top"].set_visible(False)ax[i].spines["right"].set_visible(False)# ax[0] : spine을 data 영역에서 ^지정된 거리^만큼 이동 ax[0].spines["left"].set_position(("outward",-50))# ax[1] : spine을 ^axes의 지정된 위치^에 설정ax[1].spines["left"].set_position(("axes",0.3))# ax[2] : spine을 ^data의 지정된 위치^에 설정ax[2].spines["left"].set_position(("data",2.5))
fig,ax=plt.subplots(ncols=3,figsize=(15,3))foriinrange(3):# 그래프 세개 한번에 그리기ax[i]=plot_example(ax[i])ax[i].spines["top"].set_visible(False)ax[i].spines["right"].set_visible(False)ax[0].spines["left"].set_position(("outward",10))# axis={“both”, “x”, “y”} 인자로 방향을 지정한다. # ax[0] : x, y 둘 다 ax[0].grid(axis="both")# ax[1] : x축에서만ax[1].grid(axis="x")# ax[2] : y축에서만ax[2].grid(axis="y")
# !!! 오류나는 코드임 !!!frommatplotlib.tickerimport(MultipleLocator,AutoMinorLocator)fig,ax=plt.subplots()ax=plot_example(ax)# top, right, left spines 안보이기ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["left"].set_visible(False)# y축 tick 설정ax.yaxis.set_major_locator(MultipleLocator(1))# major tick을 1 단위로 설정ax.yaxis.set_major_formatter('{x:0.2f}')# major tick format 지정ax.yaxis.set_minor_locator(MultipleLocator(0.5))# minor tick을 0.5 단위로 지정plt.plot()
---------------------------------------------------------------------------TypeError Traceback (most recent call last)
<ipython-input-56-33d5c6f4fbaf> in <module>() 11# y축 tick 설정 12 ax.yaxis.set_major_locator(MultipleLocator(1))# major tick을 1 단위로 설정---> 13ax.yaxis.set_major_formatter('{x:0.2f}')# major tick format 지정 14 ax.yaxis.set_minor_locator(MultipleLocator(0.5))# minor tick을 0.5 단위로 지정 15/usr/local/lib/python3.7/dist-packages/matplotlib/axis.py in set_major_formatter(self, formatter) 1626 formatter :`~matplotlib.ticker.Formatter` 1627 """
-> 1628cbook._check_isinstance(mticker.Formatter, formatter=formatter) 1629 self.isDefault_majfmt =False 1630 self.major.formatter = formatter
/usr/local/lib/python3.7/dist-packages/matplotlib/cbook/__init__.py in _check_isinstance(_types, **kwargs) 2126", ".join(names[:-1])+" or "+ names[-1] 2127if len(names)>1else names[0],-> 2128 type_name(type(v))))
2129 2130TypeError: 'formatter' must be an instance of matplotlib.ticker.Formatter, not a str
세팅 환경에 의해서 ax.yaxis.set_major_formatter(formatter) 에서 오류 발생.
TypeError: 'formatter' must be an instance of matplotlib.ticker.Formatter, not a str
set_major_formatter에는 matplotlib.ticker.Formatter의 형식으로 들어가야 한다.
해결방법
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator, FuncFormatter)
을 설치하고,
def major_formatter(x, pos):
return "{%.2f}" % x
formatter = FuncFormatter(major_formatter)
#정상 작동frommatplotlib.tickerimport(MultipleLocator,AutoMinorLocator)fig,ax=plt.subplots()ax=plot_example(ax)# top, right, left spines 안보이기ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["left"].set_visible(False)# y축 tick 설정#여기서 major 라인, minor 라인 먼저 설정한다. ax.yaxis.set_major_locator(MultipleLocator(1))# major tick을 1 단위로 설정ax.yaxis.set_major_formatter(formatter)# major tick format 지정 (오류가 나면 matplotlib upgrade)ax.yaxis.set_minor_locator(MultipleLocator(0.5))# minor tick을 0.5 단위로 지정plt.plot()
Out[49]:
[]
In [52]:
fig,ax=plt.subplots(ncols=3,figsize=(15,3))foriinrange(3):# 그래프 세개 한번에 그리기ax[i]=plot_example(ax[i],zorder=2)# zorder: bar를 grid 앞으로.ax[i].spines["top"].set_visible(False)ax[i].spines["right"].set_visible(False)ax[i].spines["left"].set_position(("outward",10))ax[i].yaxis.set_major_locator(MultipleLocator(1))ax[i].yaxis.set_major_formatter(formatter)ax[i].yaxis.set_minor_locator(MultipleLocator(0.5))# ax[0] : major, minor 둘 다ax[0].grid(axis="y",which="both")# ax[1] : major만ax[1].grid(axis="y",which="major")# ax[2] : major만 + 여러 옵션ax[2].grid(axis="y",which="major",color="r",ls=":",lw=0.5,alpha=0.5)#clolor red, 점선, 투명도 낮추기.plt.show()
In [55]:
fig,ax=plt.subplots()ax=plot_example(ax,zorder=2)ax.spines["top"].set_visible(False)ax.spines["right"].set_visible(False)ax.spines["left"].set_visible(False)ax.yaxis.set_major_locator(MultipleLocator(1))ax.yaxis.set_major_formatter(formatter)ax.yaxis.set_minor_locator(MultipleLocator(0.5))ax.grid(axis="y",which="major",color="lightgray")# major line에는 강조하기위해 회색줄ax.grid(axis="y",which="minor",ls=":")# minor라인에는 점선 줄