{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 8.5 안전 운전자 예측 경진대회 성능 개선 II : XGBoost 모델","metadata":{"papermill":{"duration":0.021334,"end_time":"2021-08-09T11:39:38.812568","exception":false,"start_time":"2021-08-09T11:39:38.791234","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import pandas as pd\n\n# 데이터 경로\ndata_path = '/kaggle/input/porto-seguro-safe-driver-prediction/'\n\ntrain = pd.read_csv(data_path + 'train.csv', index_col='id')\ntest = pd.read_csv(data_path + 'test.csv', index_col='id')\nsubmission = pd.read_csv(data_path + 'sample_submission.csv', index_col='id')","metadata":{"papermill":{"duration":9.340015,"end_time":"2021-08-09T11:39:48.264853","exception":false,"start_time":"2021-08-09T11:39:38.924838","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:54:58.564216Z","iopub.execute_input":"2022-08-06T14:54:58.564744Z","iopub.status.idle":"2022-08-06T14:55:08.274488Z","shell.execute_reply.started":"2022-08-06T14:54:58.564645Z","shell.execute_reply":"2022-08-06T14:55:08.273516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.5.1 피처 엔지니어링","metadata":{"papermill":{"duration":0.019962,"end_time":"2021-08-09T11:39:48.305765","exception":false,"start_time":"2021-08-09T11:39:48.285803","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 데이터 합치기","metadata":{"papermill":{"duration":0.020582,"end_time":"2021-08-09T11:39:48.347471","exception":false,"start_time":"2021-08-09T11:39:48.326889","status":"completed"},"tags":[]}},{"cell_type":"code","source":"all_data = pd.concat([train, test], ignore_index=True)\nall_data = all_data.drop('target', axis=1) # 타깃값 제거\n\nall_features = all_data.columns # 전체 피처","metadata":{"papermill":{"duration":1.316112,"end_time":"2021-08-09T11:39:49.683898","exception":false,"start_time":"2021-08-09T11:39:48.367786","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:08.276598Z","iopub.execute_input":"2022-08-06T14:55:08.276951Z","iopub.status.idle":"2022-08-06T14:55:09.856513Z","shell.execute_reply.started":"2022-08-06T14:55:08.276899Z","shell.execute_reply":"2022-08-06T14:55:09.855761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 명목형 피처 원-핫 인코딩","metadata":{"papermill":{"duration":0.024454,"end_time":"2021-08-09T11:39:49.730159","exception":false,"start_time":"2021-08-09T11:39:49.705705","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.preprocessing import OneHotEncoder\n\n# 명목형 피처\ncat_features = [feature for feature in all_features if 'cat' in feature]\n\n# 원-핫 인코딩 적용\nonehot_encoder = OneHotEncoder()\nencoded_cat_matrix = onehot_encoder.fit_transform(all_data[cat_features]) ","metadata":{"papermill":{"duration":3.123907,"end_time":"2021-08-09T11:39:52.874196","exception":false,"start_time":"2021-08-09T11:39:49.750289","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:09.857612Z","iopub.execute_input":"2022-08-06T14:55:09.857825Z","iopub.status.idle":"2022-08-06T14:55:12.838407Z","shell.execute_reply.started":"2022-08-06T14:55:09.857800Z","shell.execute_reply":"2022-08-06T14:55:12.837544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 파생 피처 추가","metadata":{"papermill":{"duration":0.020061,"end_time":"2021-08-09T11:39:52.914732","exception":false,"start_time":"2021-08-09T11:39:52.894671","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# '데이터 하나당 결측값 개수'를 파생 피처로 추가\nall_data['num_missing'] = (all_data==-1).sum(axis=1)","metadata":{"papermill":{"duration":0.254271,"end_time":"2021-08-09T11:39:53.189661","exception":false,"start_time":"2021-08-09T11:39:52.93539","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:12.840490Z","iopub.execute_input":"2022-08-06T14:55:12.840734Z","iopub.status.idle":"2022-08-06T14:55:13.046404Z","shell.execute_reply.started":"2022-08-06T14:55:12.840707Z","shell.execute_reply":"2022-08-06T14:55:13.045308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 명목형 피처, calc 분류 피처를 제외한 피처\nremaining_features = [feature for feature in all_features\n                      if ('cat' not in feature and 'calc' not in feature)] \n# num_missing을 remaining_features에 추가\nremaining_features.append('num_missing')","metadata":{"papermill":{"duration":0.027032,"end_time":"2021-08-09T11:39:53.236982","exception":false,"start_time":"2021-08-09T11:39:53.20995","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:13.047836Z","iopub.execute_input":"2022-08-06T14:55:13.048219Z","iopub.status.idle":"2022-08-06T14:55:13.053564Z","shell.execute_reply.started":"2022-08-06T14:55:13.048158Z","shell.execute_reply":"2022-08-06T14:55:13.052549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 분류가 ind인 피처\nind_features = [feature for feature in all_features if 'ind' in feature]\n\nis_first_feature = True\nfor ind_feature in ind_features:\n    if is_first_feature:\n        all_data['mix_ind'] = all_data[ind_feature].astype(str) + '_'\n        is_first_feature = False\n    else:\n        all_data['mix_ind'] += all_data[ind_feature].astype(str) + '_'","metadata":{"papermill":{"duration":24.089055,"end_time":"2021-08-09T11:40:17.346457","exception":false,"start_time":"2021-08-09T11:39:53.257402","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:13.055427Z","iopub.execute_input":"2022-08-06T14:55:13.056155Z","iopub.status.idle":"2022-08-06T14:55:38.291803Z","shell.execute_reply.started":"2022-08-06T14:55:13.056115Z","shell.execute_reply":"2022-08-06T14:55:38.290758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_data['mix_ind']","metadata":{"papermill":{"duration":0.03701,"end_time":"2021-08-09T11:40:17.404484","exception":false,"start_time":"2021-08-09T11:40:17.367474","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:38.293503Z","iopub.execute_input":"2022-08-06T14:55:38.293749Z","iopub.status.idle":"2022-08-06T14:55:38.303844Z","shell.execute_reply.started":"2022-08-06T14:55:38.293720Z","shell.execute_reply":"2022-08-06T14:55:38.302884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_count_features = []\nfor feature in cat_features+['mix_ind']:\n    val_counts_dict = all_data[feature].value_counts().to_dict()\n    all_data[f'{feature}_count'] = all_data[feature].apply(lambda x: \n                                                           val_counts_dict[x])\n    cat_count_features.append(f'{feature}_count')","metadata":{"papermill":{"duration":8.424645,"end_time":"2021-08-09T11:40:25.850123","exception":false,"start_time":"2021-08-09T11:40:17.425478","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:38.305085Z","iopub.execute_input":"2022-08-06T14:55:38.305464Z","iopub.status.idle":"2022-08-06T14:55:47.936255Z","shell.execute_reply.started":"2022-08-06T14:55:38.305413Z","shell.execute_reply":"2022-08-06T14:55:47.935408Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_count_features","metadata":{"papermill":{"duration":0.03088,"end_time":"2021-08-09T11:40:25.902673","exception":false,"start_time":"2021-08-09T11:40:25.871793","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:47.937635Z","iopub.execute_input":"2022-08-06T14:55:47.937858Z","iopub.status.idle":"2022-08-06T14:55:47.943745Z","shell.execute_reply.started":"2022-08-06T14:55:47.937832Z","shell.execute_reply":"2022-08-06T14:55:47.942838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 필요 없는 피처 제거","metadata":{"papermill":{"duration":0.023272,"end_time":"2021-08-09T11:40:25.947231","exception":false,"start_time":"2021-08-09T11:40:25.923959","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from scipy import sparse\n\n# 필요 없는 피처들\ndrop_features = ['ps_ind_14', 'ps_ind_10_bin', 'ps_ind_11_bin', \n                 'ps_ind_12_bin', 'ps_ind_13_bin', 'ps_car_14']\n\n# remaining_features, cat_count_features에서 drop_features를 제거한 데이터\nall_data_remaining = all_data[remaining_features+cat_count_features].drop(drop_features, axis=1)\n\n# 데이터 합치기\nall_data_sprs = sparse.hstack([sparse.csr_matrix(all_data_remaining),\n                               encoded_cat_matrix],\n                              format='csr')","metadata":{"papermill":{"duration":5.35722,"end_time":"2021-08-09T11:40:31.325595","exception":false,"start_time":"2021-08-09T11:40:25.968375","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:47.946651Z","iopub.execute_input":"2022-08-06T14:55:47.946999Z","iopub.status.idle":"2022-08-06T14:55:54.065019Z","shell.execute_reply.started":"2022-08-06T14:55:47.946948Z","shell.execute_reply":"2022-08-06T14:55:54.064178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 데이터 나누기","metadata":{"papermill":{"duration":0.021242,"end_time":"2021-08-09T11:40:31.36788","exception":false,"start_time":"2021-08-09T11:40:31.346638","status":"completed"},"tags":[]}},{"cell_type":"code","source":"num_train = len(train) # 훈련 데이터 개수\n\n# 훈련 데이터와 테스트 데이터 나누기\nX = all_data_sprs[:num_train]\nX_test = all_data_sprs[num_train:]\n\ny = train['target'].values","metadata":{"papermill":{"duration":0.959572,"end_time":"2021-08-09T11:40:32.348323","exception":false,"start_time":"2021-08-09T11:40:31.388751","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:54.066369Z","iopub.execute_input":"2022-08-06T14:55:54.066682Z","iopub.status.idle":"2022-08-06T14:55:55.294504Z","shell.execute_reply.started":"2022-08-06T14:55:54.066641Z","shell.execute_reply":"2022-08-06T14:55:55.293553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 정규화 지니계수 계산 함수","metadata":{"papermill":{"duration":0.020777,"end_time":"2021-08-09T11:40:32.38993","exception":false,"start_time":"2021-08-09T11:40:32.369153","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import numpy as np\n\ndef eval_gini(y_true, y_pred):\n    # 실제값과 예측값의 크기가 같은지 확인 (값이 다르면 오류 발생)\n    assert y_true.shape == y_pred.shape\n\n    n_samples = y_true.shape[0]                      # 데이터 개수\n    L_mid = np.linspace(1 / n_samples, 1, n_samples) # 대각선 값\n\n    # 1) 예측값에 대한 지니계수\n    pred_order = y_true[y_pred.argsort()] # y_pred 크기순으로 y_true 값 정렬\n    L_pred = np.cumsum(pred_order) / np.sum(pred_order) # 로렌츠 곡선\n    G_pred = np.sum(L_mid - L_pred)       # 예측 값에 대한 지니계수\n\n    # 2) 예측이 완벽할 때 지니계수\n    true_order = y_true[y_true.argsort()] # y_true 크기순으로 y_true 값 정렬\n    L_true = np.cumsum(true_order) / np.sum(true_order) # 로렌츠 곡선\n    G_true = np.sum(L_mid - L_true)       # 예측이 완벽할 때 지니계수\n\n    # 정규화된 지니계수\n    return G_pred / G_true","metadata":{"papermill":{"duration":0.029989,"end_time":"2021-08-09T11:40:32.441058","exception":false,"start_time":"2021-08-09T11:40:32.411069","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:55.295796Z","iopub.execute_input":"2022-08-06T14:55:55.296128Z","iopub.status.idle":"2022-08-06T14:55:55.303593Z","shell.execute_reply.started":"2022-08-06T14:55:55.296083Z","shell.execute_reply":"2022-08-06T14:55:55.302676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# XGBoost용 gini() 함수\ndef gini(preds, dtrain):\n    labels = dtrain.get_label()\n    return 'gini', eval_gini(labels, preds)","metadata":{"papermill":{"duration":0.02826,"end_time":"2021-08-09T11:40:32.490223","exception":false,"start_time":"2021-08-09T11:40:32.461963","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:55.304903Z","iopub.execute_input":"2022-08-06T14:55:55.305230Z","iopub.status.idle":"2022-08-06T14:55:55.314830Z","shell.execute_reply.started":"2022-08-06T14:55:55.305190Z","shell.execute_reply":"2022-08-06T14:55:55.313808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.5.2 하이퍼파라미터 최적화","metadata":{"papermill":{"duration":0.020383,"end_time":"2021-08-09T11:40:32.531958","exception":false,"start_time":"2021-08-09T11:40:32.511575","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 데이터셋 준비","metadata":{"papermill":{"duration":0.020691,"end_time":"2021-08-09T11:40:32.5737","exception":false,"start_time":"2021-08-09T11:40:32.553009","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import xgboost as xgb\nfrom sklearn.model_selection import train_test_split\n\n# 8:2 비율로 훈련 데이터, 검증 데이터 분리 (베이지안 최적화 수행용)\nX_train, X_valid, y_train, y_valid = train_test_split(X, y, \n                                                      test_size=0.2, \n                                                      random_state=0)\n# 베이지안 최적화용 데이터셋\nbayes_dtrain = xgb.DMatrix(X_train, y_train)\nbayes_dvalid = xgb.DMatrix(X_valid, y_valid)","metadata":{"papermill":{"duration":0.787486,"end_time":"2021-08-09T11:40:33.382467","exception":false,"start_time":"2021-08-09T11:40:32.594981","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:55.316125Z","iopub.execute_input":"2022-08-06T14:55:55.316461Z","iopub.status.idle":"2022-08-06T14:55:56.209323Z","shell.execute_reply.started":"2022-08-06T14:55:55.316421Z","shell.execute_reply":"2022-08-06T14:55:56.208483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 하이퍼파라미터 범위 설정","metadata":{"papermill":{"duration":0.020704,"end_time":"2021-08-09T11:40:33.424334","exception":false,"start_time":"2021-08-09T11:40:33.40363","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 베이지안 최적화를 위한 하이퍼파라미터 범위\nparam_bounds = {'max_depth': (4, 8),\n                'subsample': (0.6, 0.9),\n                'colsample_bytree': (0.7, 1.0),\n                'min_child_weight': (5, 7),\n                'gamma': (8, 11),\n                'reg_alpha': (7, 9),\n                'reg_lambda': (1.1, 1.5),\n                'scale_pos_weight': (1.4, 1.6)}\n\n# 값이 고정된 하이퍼파라미터\nfixed_params = {'objective': 'binary:logistic',\n                'learning_rate': 0.02,\n                'random_state': 1991}","metadata":{"papermill":{"duration":0.029252,"end_time":"2021-08-09T11:40:33.47495","exception":false,"start_time":"2021-08-09T11:40:33.445698","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:56.210508Z","iopub.execute_input":"2022-08-06T14:55:56.211071Z","iopub.status.idle":"2022-08-06T14:55:56.216957Z","shell.execute_reply.started":"2022-08-06T14:55:56.211026Z","shell.execute_reply":"2022-08-06T14:55:56.216053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### (베이지안 최적화용) 평가지표 계산 함수 작성","metadata":{"papermill":{"duration":0.021186,"end_time":"2021-08-09T11:40:33.517164","exception":false,"start_time":"2021-08-09T11:40:33.495978","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def eval_function(max_depth, subsample, colsample_bytree, min_child_weight,\n                 reg_alpha, gamma, reg_lambda, scale_pos_weight):\n    '''최적화하려는 평가지표(지니계수) 계산 함수'''\n    # 베이지안 최적화를 수행할 하이퍼파라미터\n    params = {'max_depth': int(round(max_depth)),\n              'subsample': subsample,\n              'colsample_bytree': colsample_bytree,\n              'min_child_weight': min_child_weight,\n              'gamma': gamma,\n              'reg_alpha':reg_alpha,\n              'reg_lambda': reg_lambda,\n              'scale_pos_weight': scale_pos_weight}\n    # 값이 고정된 하이퍼파라미터도 추가\n    params.update(fixed_params)\n    \n    print('하이퍼파라미터 :', params)    \n        \n    # XGBoost 모델 훈련\n    xgb_model = xgb.train(params=params, \n                          dtrain=bayes_dtrain,\n                          num_boost_round=2000,\n                          evals=[(bayes_dvalid, 'bayes_dvalid')],\n                          maximize=True,\n                          feval=gini,\n                          early_stopping_rounds=200,\n                          verbose_eval=False)\n                           \n    best_iter = xgb_model.best_iteration # 최적 반복 횟수\n    # 검증 데이터로 예측 수행\n    preds = xgb_model.predict(bayes_dvalid, \n                              iteration_range=(0, best_iter))\n    # 지니계수 계산\n    gini_score = eval_gini(y_valid, preds)\n    print(f'지니계수 : {gini_score}\\n')\n    \n    return gini_score","metadata":{"papermill":{"duration":0.031798,"end_time":"2021-08-09T11:40:33.57044","exception":false,"start_time":"2021-08-09T11:40:33.538642","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:56.218233Z","iopub.execute_input":"2022-08-06T14:55:56.218881Z","iopub.status.idle":"2022-08-06T14:55:56.228731Z","shell.execute_reply.started":"2022-08-06T14:55:56.218846Z","shell.execute_reply":"2022-08-06T14:55:56.227984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 최적화 수행","metadata":{"papermill":{"duration":0.020926,"end_time":"2021-08-09T11:40:33.61246","exception":false,"start_time":"2021-08-09T11:40:33.591534","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from bayes_opt import BayesianOptimization\n\n# 베이지안 최적화 객체 생성\noptimizer = BayesianOptimization(f=eval_function, \n                                 pbounds=param_bounds, \n                                 random_state=0)\n\n# 베이지안 최적화 수행\noptimizer.maximize(init_points=3, n_iter=6)","metadata":{"papermill":{"duration":8424.657546,"end_time":"2021-08-09T14:00:58.292109","exception":false,"start_time":"2021-08-09T11:40:33.634563","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:55:56.229857Z","iopub.execute_input":"2022-08-06T14:55:56.230694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 결과 확인","metadata":{"papermill":{"duration":0.025409,"end_time":"2021-08-09T14:00:58.343159","exception":false,"start_time":"2021-08-09T14:00:58.31775","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 평가함수 점수가 최대일 때 하이퍼파라미터\nmax_params = optimizer.max['params']\nmax_params","metadata":{"papermill":{"duration":0.035124,"end_time":"2021-08-09T14:00:58.403727","exception":false,"start_time":"2021-08-09T14:00:58.368603","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 정수형 하이퍼파라미터 변환\nmax_params['max_depth'] = int(round(max_params['max_depth']))\n\n# 값이 고정된 하이퍼파라미터 추가\nmax_params.update(fixed_params)\nmax_params","metadata":{"papermill":{"duration":0.037261,"end_time":"2021-08-09T14:00:58.467284","exception":false,"start_time":"2021-08-09T14:00:58.430023","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.5.3 모델 훈련 및 성능 검증","metadata":{"papermill":{"duration":0.025933,"end_time":"2021-08-09T14:00:58.519727","exception":false,"start_time":"2021-08-09T14:00:58.493794","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.model_selection import StratifiedKFold\n\n# 층화 K 폴드 교차 검증기 생성\nfolds = StratifiedKFold(n_splits=5, shuffle=True, random_state=1991)\n\n# OOF 방식으로 훈련된 모델로 검증 데이터 타깃값을 예측한 확률을 담을 1차원 배열\noof_val_preds = np.zeros(X.shape[0]) \n# OOF 방식으로 훈련된 모델로 테스트 데이터 타깃값을 예측한 확률을 담을 1차원 배열\noof_test_preds = np.zeros(X_test.shape[0]) \n\n# OOF 방식으로 모델 훈련, 검증, 예측\nfor idx, (train_idx, valid_idx) in enumerate(folds.split(X, y)):\n    # 각 폴드를 구분하는 문구 출력\n    print('#'*40, f'폴드 {idx+1} / 폴드 {folds.n_splits}', '#'*40)\n    \n    # 훈련용 데이터, 검증용 데이터 설정\n    X_train, y_train = X[train_idx], y[train_idx]\n    X_valid, y_valid = X[valid_idx], y[valid_idx]\n\n    # XGBoost 전용 데이터셋 생성 \n    dtrain = xgb.DMatrix(X_train, y_train)\n    dvalid = xgb.DMatrix(X_valid, y_valid)\n    dtest = xgb.DMatrix(X_test)\n    # XGBoost 모델 훈련\n    xgb_model = xgb.train(params=max_params, \n                          dtrain=dtrain,\n                          num_boost_round=2000,\n                          evals=[(dvalid, 'valid')],\n                          maximize=True,\n                          feval=gini,\n                          early_stopping_rounds=200,\n                          verbose_eval=100)\n\n    # 모델 성능이 가장 좋을 때의 부스팅 반복 횟수 저장\n    best_iter = xgb_model.best_iteration\n    # 테스트 데이터를 활용해 OOF 예측\n    oof_test_preds += xgb_model.predict(dtest,\n                                        iteration_range=(0, best_iter))/folds.n_splits\n    \n    # 모델 성능 평가를 위한 검증 데이터 타깃값 예측 \n    oof_val_preds[valid_idx] += xgb_model.predict(dvalid, \n                                                  iteration_range=(0, best_iter))\n    \n    # 검증 데이터 예측 확률에 대한 정규화 지니계수\n    gini_score = eval_gini(y_valid, oof_val_preds[valid_idx])\n    print(f'폴드 {idx+1} 지니계수 : {gini_score}\\n')","metadata":{"papermill":{"duration":5798.009054,"end_time":"2021-08-09T15:37:36.555036","exception":false,"start_time":"2021-08-09T14:00:58.545982","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('OOF 검증 데이터 지니계수 :', eval_gini(y, oof_val_preds))","metadata":{"papermill":{"duration":0.17782,"end_time":"2021-08-09T15:37:36.780817","exception":false,"start_time":"2021-08-09T15:37:36.602997","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.5.4 예측 및 결과 제출","metadata":{"papermill":{"duration":0.048497,"end_time":"2021-08-09T15:37:36.879167","exception":false,"start_time":"2021-08-09T15:37:36.83067","status":"completed"},"tags":[]}},{"cell_type":"code","source":"submission['target'] = oof_test_preds\nsubmission.to_csv('submission.csv')","metadata":{"papermill":{"duration":2.326551,"end_time":"2021-08-09T15:37:39.252685","exception":false,"start_time":"2021-08-09T15:37:36.926134","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]}]}