{"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.4 안전 운전자 예측 경진대회 성능 개선 I : LightGBM 모델","metadata":{"papermill":{"duration":0.022759,"end_time":"2021-08-07T03:50:58.530139","exception":false,"start_time":"2021-08-07T03:50:58.50738","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":8.716193,"end_time":"2021-08-07T03:51:07.362348","exception":false,"start_time":"2021-08-07T03:50:58.646155","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:10:59.772200Z","iopub.execute_input":"2022-08-06T13:10:59.773150Z","iopub.status.idle":"2022-08-06T13:11:09.011701Z","shell.execute_reply.started":"2022-08-06T13:10:59.773033Z","shell.execute_reply":"2022-08-06T13:11:09.010868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.4.1 피처 엔지니어링","metadata":{"papermill":{"duration":0.021299,"end_time":"2021-08-07T03:51:07.405483","exception":false,"start_time":"2021-08-07T03:51:07.384184","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 데이터 합치기","metadata":{"papermill":{"duration":0.022194,"end_time":"2021-08-07T03:51:07.449246","exception":false,"start_time":"2021-08-07T03:51:07.427052","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.313468,"end_time":"2021-08-07T03:51:08.784147","exception":false,"start_time":"2021-08-07T03:51:07.470679","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:09.013346Z","iopub.execute_input":"2022-08-06T13:11:09.013575Z","iopub.status.idle":"2022-08-06T13:11:10.080169Z","shell.execute_reply.started":"2022-08-06T13:11:09.013549Z","shell.execute_reply":"2022-08-06T13:11:10.079364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 명목형 피처 원-핫 인코딩","metadata":{"papermill":{"duration":0.02112,"end_time":"2021-08-07T03:51:08.828357","exception":false,"start_time":"2021-08-07T03:51:08.807237","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.036812,"end_time":"2021-08-07T03:51:11.886604","exception":false,"start_time":"2021-08-07T03:51:08.849792","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:10.081382Z","iopub.execute_input":"2022-08-06T13:11:10.081620Z","iopub.status.idle":"2022-08-06T13:11:12.923551Z","shell.execute_reply.started":"2022-08-06T13:11:10.081594Z","shell.execute_reply":"2022-08-06T13:11:12.922680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 파생 피처 추가","metadata":{"papermill":{"duration":0.021034,"end_time":"2021-08-07T03:51:11.929021","exception":false,"start_time":"2021-08-07T03:51:11.907987","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# '데이터 하나당 결측값 개수'를 파생 피처로 추가\nall_data['num_missing'] = (all_data==-1).sum(axis=1)","metadata":{"papermill":{"duration":0.23417,"end_time":"2021-08-07T03:51:12.184427","exception":false,"start_time":"2021-08-07T03:51:11.950257","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:12.925244Z","iopub.execute_input":"2022-08-06T13:11:12.926043Z","iopub.status.idle":"2022-08-06T13:11:13.120573Z","shell.execute_reply.started":"2022-08-06T13:11:12.925997Z","shell.execute_reply":"2022-08-06T13:11:13.119801Z"},"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.02845,"end_time":"2021-08-07T03:51:12.234517","exception":false,"start_time":"2021-08-07T03:51:12.206067","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:13.121799Z","iopub.execute_input":"2022-08-06T13:11:13.122040Z","iopub.status.idle":"2022-08-06T13:11:13.126326Z","shell.execute_reply.started":"2022-08-06T13:11:13.122013Z","shell.execute_reply":"2022-08-06T13:11:13.125751Z"},"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":23.954693,"end_time":"2021-08-07T03:51:36.210479","exception":false,"start_time":"2021-08-07T03:51:12.255786","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:13.127307Z","iopub.execute_input":"2022-08-06T13:11:13.128319Z","iopub.status.idle":"2022-08-06T13:11:39.227121Z","shell.execute_reply.started":"2022-08-06T13:11:13.128284Z","shell.execute_reply":"2022-08-06T13:11:39.226298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_data['mix_ind']","metadata":{"papermill":{"duration":0.035452,"end_time":"2021-08-07T03:51:36.267581","exception":false,"start_time":"2021-08-07T03:51:36.232129","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:39.228239Z","iopub.execute_input":"2022-08-06T13:11:39.228464Z","iopub.status.idle":"2022-08-06T13:11:39.238719Z","shell.execute_reply.started":"2022-08-06T13:11:39.228439Z","shell.execute_reply":"2022-08-06T13:11:39.238002Z"},"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.850842,"end_time":"2021-08-07T03:51:45.141061","exception":false,"start_time":"2021-08-07T03:51:36.290219","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:39.239842Z","iopub.execute_input":"2022-08-06T13:11:39.240409Z","iopub.status.idle":"2022-08-06T13:11:48.848126Z","shell.execute_reply.started":"2022-08-06T13:11:39.240377Z","shell.execute_reply":"2022-08-06T13:11:48.847173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cat_count_features","metadata":{"papermill":{"duration":0.029116,"end_time":"2021-08-07T03:51:45.192104","exception":false,"start_time":"2021-08-07T03:51:45.162988","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:48.849460Z","iopub.execute_input":"2022-08-06T13:11:48.849754Z","iopub.status.idle":"2022-08-06T13:11:48.857276Z","shell.execute_reply.started":"2022-08-06T13:11:48.849717Z","shell.execute_reply":"2022-08-06T13:11:48.856240Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 필요 없는 피처 제거","metadata":{"papermill":{"duration":0.022254,"end_time":"2021-08-07T03:51:45.236527","exception":false,"start_time":"2021-08-07T03:51:45.214273","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from scipy import sparse\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.254913,"end_time":"2021-08-07T03:51:50.513911","exception":false,"start_time":"2021-08-07T03:51:45.258998","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:48.860090Z","iopub.execute_input":"2022-08-06T13:11:48.860454Z","iopub.status.idle":"2022-08-06T13:11:54.863222Z","shell.execute_reply.started":"2022-08-06T13:11:48.860422Z","shell.execute_reply":"2022-08-06T13:11:54.862303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 데이터 나누기","metadata":{"papermill":{"duration":0.02264,"end_time":"2021-08-07T03:51:50.560983","exception":false,"start_time":"2021-08-07T03:51:50.538343","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.956334,"end_time":"2021-08-07T03:51:51.540317","exception":false,"start_time":"2021-08-07T03:51:50.583983","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:54.864572Z","iopub.execute_input":"2022-08-06T13:11:54.865246Z","iopub.status.idle":"2022-08-06T13:11:56.085321Z","shell.execute_reply.started":"2022-08-06T13:11:54.865177Z","shell.execute_reply":"2022-08-06T13:11:56.084402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 정규화 지니계수 계산 함수","metadata":{"papermill":{"duration":0.022254,"end_time":"2021-08-07T03:51:51.584573","exception":false,"start_time":"2021-08-07T03:51:51.562319","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.03054,"end_time":"2021-08-07T03:51:51.637185","exception":false,"start_time":"2021-08-07T03:51:51.606645","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:56.086707Z","iopub.execute_input":"2022-08-06T13:11:56.087223Z","iopub.status.idle":"2022-08-06T13:11:56.094885Z","shell.execute_reply.started":"2022-08-06T13:11:56.087164Z","shell.execute_reply":"2022-08-06T13:11:56.093976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LightGBM용 gini() 함수\ndef gini(preds, dtrain):\n    labels = dtrain.get_label()\n    return 'gini', eval_gini(labels, preds), True # 반환값","metadata":{"papermill":{"duration":0.029576,"end_time":"2021-08-07T03:51:51.68868","exception":false,"start_time":"2021-08-07T03:51:51.659104","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:56.096526Z","iopub.execute_input":"2022-08-06T13:11:56.097118Z","iopub.status.idle":"2022-08-06T13:11:56.105110Z","shell.execute_reply.started":"2022-08-06T13:11:56.097037Z","shell.execute_reply":"2022-08-06T13:11:56.104491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.4.2 하이퍼파라미터 최적화","metadata":{"papermill":{"duration":0.022127,"end_time":"2021-08-07T03:51:51.733203","exception":false,"start_time":"2021-08-07T03:51:51.711076","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 데이터셋 준비","metadata":{"papermill":{"duration":0.021742,"end_time":"2021-08-07T03:51:51.77717","exception":false,"start_time":"2021-08-07T03:51:51.755428","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import lightgbm as lgb\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\n# 베이지안 최적화용 데이터셋\nbayes_dtrain = lgb.Dataset(X_train, y_train)\nbayes_dvalid = lgb.Dataset(X_valid, y_valid)","metadata":{"papermill":{"duration":1.104408,"end_time":"2021-08-07T03:51:52.903933","exception":false,"start_time":"2021-08-07T03:51:51.799525","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:56.106773Z","iopub.execute_input":"2022-08-06T13:11:56.107316Z","iopub.status.idle":"2022-08-06T13:11:57.469250Z","shell.execute_reply.started":"2022-08-06T13:11:56.107274Z","shell.execute_reply":"2022-08-06T13:11:57.468575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 하이퍼파라미터 범위 설정","metadata":{"papermill":{"duration":0.022323,"end_time":"2021-08-07T03:51:52.948916","exception":false,"start_time":"2021-08-07T03:51:52.926593","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 베이지안 최적화를 위한 하이퍼파라미터 범위\nparam_bounds = {'num_leaves': (30, 40),\n                'lambda_l1': (0.7, 0.9),\n                'lambda_l2': (0.9, 1),\n                'feature_fraction': (0.6, 0.7),\n                'bagging_fraction': (0.6, 0.9),\n                'min_child_samples': (6, 10),\n                'min_child_weight': (10, 40)}\n\n# 값이 고정된 하이퍼파라미터\nfixed_params = {'objective': 'binary',\n                'learning_rate': 0.005,\n                'bagging_freq': 1,\n                'force_row_wise': True,\n                'random_state': 1991}","metadata":{"papermill":{"duration":0.03053,"end_time":"2021-08-07T03:51:53.001861","exception":false,"start_time":"2021-08-07T03:51:52.971331","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:57.470714Z","iopub.execute_input":"2022-08-06T13:11:57.471217Z","iopub.status.idle":"2022-08-06T13:11:57.477456Z","shell.execute_reply.started":"2022-08-06T13:11:57.471158Z","shell.execute_reply":"2022-08-06T13:11:57.476868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### (베이지안 최적화용) 평가지표 계산 함수 작성","metadata":{"papermill":{"duration":0.022254,"end_time":"2021-08-07T03:51:53.046698","exception":false,"start_time":"2021-08-07T03:51:53.024444","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def eval_function(num_leaves, lambda_l1, lambda_l2, feature_fraction,\n                  bagging_fraction, min_child_samples, min_child_weight):\n    '''최적화하려는 평가지표(지니계수) 계산 함수'''\n    \n    # 베이지안 최적화를 수행할 하이퍼파라미터 \n    params = {'num_leaves': int(round(num_leaves)),\n              'lambda_l1': lambda_l1,\n              'lambda_l2': lambda_l2,\n              'feature_fraction': feature_fraction,\n              'bagging_fraction': bagging_fraction,\n              'min_child_samples': int(round(min_child_samples)),\n              'min_child_weight': min_child_weight,\n              'feature_pre_filter': False}\n    # 고정된 하이퍼파라미터도 추가\n    params.update(fixed_params)\n    \n    print('하이퍼파라미터:', params)    \n    \n    # LightGBM 모델 훈련\n    lgb_model = lgb.train(params=params, \n                           train_set=bayes_dtrain,\n                           num_boost_round=2500,\n                           valid_sets=bayes_dvalid,\n                           feval=gini,\n                           early_stopping_rounds=300,\n                           verbose_eval=False)\n    # 검증 데이터로 예측 수행\n    preds = lgb_model.predict(X_valid) \n    # 지니계수 계산\n    gini_score = eval_gini(y_valid, preds)\n    print(f'지니계수 : {gini_score}\\n')\n    \n    return gini_score","metadata":{"papermill":{"duration":0.033147,"end_time":"2021-08-07T03:51:53.102485","exception":false,"start_time":"2021-08-07T03:51:53.069338","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:57.478365Z","iopub.execute_input":"2022-08-06T13:11:57.479242Z","iopub.status.idle":"2022-08-06T13:11:57.490486Z","shell.execute_reply.started":"2022-08-06T13:11:57.479178Z","shell.execute_reply":"2022-08-06T13:11:57.489671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 최적화 수행","metadata":{"papermill":{"duration":0.022157,"end_time":"2021-08-07T03:51:53.146863","exception":false,"start_time":"2021-08-07T03:51:53.124706","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)","metadata":{"papermill":{"duration":0.052634,"end_time":"2021-08-07T03:51:53.222432","exception":false,"start_time":"2021-08-07T03:51:53.169798","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:57.493617Z","iopub.execute_input":"2022-08-06T13:11:57.494099Z","iopub.status.idle":"2022-08-06T13:11:57.525498Z","shell.execute_reply.started":"2022-08-06T13:11:57.494056Z","shell.execute_reply":"2022-08-06T13:11:57.524712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 베이지안 최적화 수행\noptimizer.maximize(init_points=3, n_iter=6)","metadata":{"papermill":{"duration":1670.211897,"end_time":"2021-08-07T04:19:43.456979","exception":false,"start_time":"2021-08-07T03:51:53.245082","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:11:57.529354Z","iopub.execute_input":"2022-08-06T13:11:57.529626Z","iopub.status.idle":"2022-08-06T13:42:14.366597Z","shell.execute_reply.started":"2022-08-06T13:11:57.529594Z","shell.execute_reply":"2022-08-06T13:42:14.365575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 결과 확인","metadata":{"papermill":{"duration":0.027336,"end_time":"2021-08-07T04:19:43.513352","exception":false,"start_time":"2021-08-07T04:19:43.486016","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 평가함수 점수가 최대일 때 하이퍼파라미터\nmax_params = optimizer.max['params']\nmax_params","metadata":{"papermill":{"duration":0.036899,"end_time":"2021-08-07T04:19:43.577925","exception":false,"start_time":"2021-08-07T04:19:43.541026","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:42:14.368291Z","iopub.execute_input":"2022-08-06T13:42:14.368581Z","iopub.status.idle":"2022-08-06T13:42:14.376726Z","shell.execute_reply.started":"2022-08-06T13:42:14.368547Z","shell.execute_reply":"2022-08-06T13:42:14.375810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 정수형 하이퍼파라미터 변환\nmax_params['num_leaves'] = int(round(max_params['num_leaves']))\nmax_params['min_child_samples'] = int(round(max_params['min_child_samples']))","metadata":{"papermill":{"duration":0.034946,"end_time":"2021-08-07T04:19:43.640774","exception":false,"start_time":"2021-08-07T04:19:43.605828","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:42:14.377965Z","iopub.execute_input":"2022-08-06T13:42:14.378465Z","iopub.status.idle":"2022-08-06T13:42:14.386217Z","shell.execute_reply.started":"2022-08-06T13:42:14.378422Z","shell.execute_reply":"2022-08-06T13:42:14.385549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 값이 고정된 하이퍼파라미터 추가\nmax_params.update(fixed_params)","metadata":{"papermill":{"duration":0.033899,"end_time":"2021-08-07T04:19:43.702672","exception":false,"start_time":"2021-08-07T04:19:43.668773","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:42:14.387270Z","iopub.execute_input":"2022-08-06T13:42:14.387621Z","iopub.status.idle":"2022-08-06T13:42:14.402476Z","shell.execute_reply.started":"2022-08-06T13:42:14.387593Z","shell.execute_reply":"2022-08-06T13:42:14.401700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_params","metadata":{"papermill":{"duration":0.035241,"end_time":"2021-08-07T04:19:43.765944","exception":false,"start_time":"2021-08-07T04:19:43.730703","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:42:14.403563Z","iopub.execute_input":"2022-08-06T13:42:14.403931Z","iopub.status.idle":"2022-08-06T13:42:14.414866Z","shell.execute_reply.started":"2022-08-06T13:42:14.403898Z","shell.execute_reply":"2022-08-06T13:42:14.414251Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.4.3 모델 훈련 및 성능 검증","metadata":{"papermill":{"duration":0.028236,"end_time":"2021-08-07T04:19:43.822532","exception":false,"start_time":"2021-08-07T04:19:43.794296","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    # LightGBM 전용 데이터셋 생성\n    dtrain = lgb.Dataset(X_train, y_train) # LightGBM 전용 훈련 데이터셋\n    dvalid = lgb.Dataset(X_valid, y_valid) # LightGBM 전용 검증 데이터셋\n                          \n    # LightGBM 모델 훈련\n    lgb_model = lgb.train(params=max_params,    # 최적 하이퍼파라미터\n                          train_set=dtrain,     # 훈련 데이터셋\n                          num_boost_round=2500, # 부스팅 반복 횟수\n                          valid_sets=dvalid,    # 성능 평가용 검증 데이터셋\n                          feval=gini,           # 검증용 평가지표\n                          early_stopping_rounds=300, # 조기종료 조건\n                          verbose_eval=100)     # 100번째마다 점수 출력\n    \n    # 테스트 데이터를 활용해 OOF 예측\n    oof_test_preds += lgb_model.predict(X_test)/folds.n_splits\n    # 모델 성능 평가를 위한 검증 데이터 타깃값 예측 \n    oof_val_preds[valid_idx] += lgb_model.predict(X_valid)\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":1308.974033,"end_time":"2021-08-07T04:41:32.824935","exception":false,"start_time":"2021-08-07T04:19:43.850902","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T13:42:14.416097Z","iopub.execute_input":"2022-08-06T13:42:14.416538Z","iopub.status.idle":"2022-08-06T14:05:30.926064Z","shell.execute_reply.started":"2022-08-06T13:42:14.416508Z","shell.execute_reply":"2022-08-06T14:05:30.925064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('OOF 검증 데이터 지니계수 :', eval_gini(y, oof_val_preds))","metadata":{"papermill":{"duration":0.176155,"end_time":"2021-08-07T04:41:33.058534","exception":false,"start_time":"2021-08-07T04:41:32.882379","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:05:30.927546Z","iopub.execute_input":"2022-08-06T14:05:30.927924Z","iopub.status.idle":"2022-08-06T14:05:31.042712Z","shell.execute_reply.started":"2022-08-06T14:05:30.927889Z","shell.execute_reply":"2022-08-06T14:05:31.042101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 8.4.4 예측 및 결과 제출","metadata":{"papermill":{"duration":0.057574,"end_time":"2021-08-07T04:41:33.173744","exception":false,"start_time":"2021-08-07T04:41:33.11617","status":"completed"},"tags":[]}},{"cell_type":"code","source":"submission['target'] = oof_test_preds\nsubmission.to_csv('submission.csv')","metadata":{"papermill":{"duration":2.358523,"end_time":"2021-08-07T04:41:35.589401","exception":false,"start_time":"2021-08-07T04:41:33.230878","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-08-06T14:05:31.043948Z","iopub.execute_input":"2022-08-06T14:05:31.044391Z","iopub.status.idle":"2022-08-06T14:05:33.405728Z","shell.execute_reply.started":"2022-08-06T14:05:31.044361Z","shell.execute_reply":"2022-08-06T14:05:33.405045Z"},"trusted":true},"execution_count":null,"outputs":[]}]}