{"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":"# 6.5~6.7 자전거 대여 수요 예측 경진대회 모델 성능 개선","metadata":{"papermill":{"duration":0.026639,"end_time":"2021-08-16T04:01:01.662249","exception":false,"start_time":"2021-08-16T04:01:01.63561","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"- [자전거 대여 수요 예측 경진대회 링크](https://www.kaggle.com/c/bike-sharing-demand)\n\n- [모델링 코드 참고 링크](https://www.kaggle.com/viveksrinivasan/eda-ensemble-model-top-10-percentile)","metadata":{"papermill":{"duration":0.028176,"end_time":"2021-08-16T04:01:01.720166","exception":false,"start_time":"2021-08-16T04:01:01.69199","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import pandas as pd\n# 데이터 경로\ndata_path = '/kaggle/input/bike-sharing-demand/'\n\ntrain = pd.read_csv(data_path + 'train.csv')\ntest = pd.read_csv(data_path + 'test.csv')\nsubmission = pd.read_csv(data_path + 'sampleSubmission.csv')","metadata":{"_cell_guid":"057b1690-5b93-9f14-eafe-fad12c00da69","papermill":{"duration":0.287878,"end_time":"2021-08-16T04:01:02.111389","exception":false,"start_time":"2021-08-16T04:01:01.823511","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:19.972553Z","iopub.execute_input":"2022-03-04T07:34:19.972933Z","iopub.status.idle":"2022-03-04T07:34:20.093874Z","shell.execute_reply.started":"2022-03-04T07:34:19.972825Z","shell.execute_reply":"2022-03-04T07:34:20.092991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 피처 엔지니어링","metadata":{"papermill":{"duration":0.025383,"end_time":"2021-08-16T04:01:02.164087","exception":false,"start_time":"2021-08-16T04:01:02.138704","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 이상치 제거","metadata":{}},{"cell_type":"code","source":"# 훈련 데이터에서 weather가 4가 아닌 데이터만 추출\ntrain = train[train['weather'] != 4]","metadata":{"execution":{"iopub.status.busy":"2022-03-04T07:34:20.095517Z","iopub.execute_input":"2022-03-04T07:34:20.096079Z","iopub.status.idle":"2022-03-04T07:34:20.118745Z","shell.execute_reply.started":"2022-03-04T07:34:20.096046Z","shell.execute_reply":"2022-03-04T07:34:20.117992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 데이터 합치기","metadata":{"papermill":{"duration":0.026385,"end_time":"2021-08-16T04:01:02.216903","exception":false,"start_time":"2021-08-16T04:01:02.190518","status":"completed"},"tags":[]}},{"cell_type":"code","source":"all_data = pd.concat([train, test], ignore_index=True)\nall_data","metadata":{"papermill":{"duration":0.088442,"end_time":"2021-08-16T04:01:02.331507","exception":false,"start_time":"2021-08-16T04:01:02.243065","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.12022Z","iopub.execute_input":"2022-03-04T07:34:20.120622Z","iopub.status.idle":"2022-03-04T07:34:20.161408Z","shell.execute_reply.started":"2022-03-04T07:34:20.120586Z","shell.execute_reply":"2022-03-04T07:34:20.160726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 파생 변수(피처) 추가","metadata":{"papermill":{"duration":0.026373,"end_time":"2021-08-16T04:01:02.386543","exception":false,"start_time":"2021-08-16T04:01:02.36017","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from datetime import datetime\n\n# 날짜 피처 생성\nall_data['date'] = all_data['datetime'].apply(lambda x: x.split()[0])\n# 연도 피처 생성\nall_data['year'] = all_data['datetime'].apply(lambda x: x.split()[0].split('-')[0])\n# 월 피처 생성\nall_data['month'] = all_data['datetime'].apply(lambda x: x.split()[0].split('-')[1])\n# 시 피처 생성\nall_data['hour'] = all_data['datetime'].apply(lambda x: x.split()[1].split(':')[0])\n# 요일 피처 생성\nall_data[\"weekday\"] = all_data['date'].apply(lambda dateString : datetime.strptime(dateString,\"%Y-%m-%d\").weekday())","metadata":{"_cell_guid":"18f7c3fc-ffdf-4bc6-1d4c-c455fb4e0141","papermill":{"duration":0.344366,"end_time":"2021-08-16T04:01:02.75778","exception":false,"start_time":"2021-08-16T04:01:02.413414","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.16302Z","iopub.execute_input":"2022-03-04T07:34:20.163375Z","iopub.status.idle":"2022-03-04T07:34:20.458552Z","shell.execute_reply.started":"2022-03-04T07:34:20.163346Z","shell.execute_reply":"2022-03-04T07:34:20.457535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 필요 없는 피처 제거","metadata":{"papermill":{"duration":0.036186,"end_time":"2021-08-16T04:01:02.826974","exception":false,"start_time":"2021-08-16T04:01:02.790788","status":"completed"},"tags":[]}},{"cell_type":"code","source":"drop_features = ['casual', 'registered', 'datetime', 'date', 'windspeed', 'month']\n\nall_data = all_data.drop(drop_features, axis=1)","metadata":{"papermill":{"duration":0.057342,"end_time":"2021-08-16T04:01:02.92176","exception":false,"start_time":"2021-08-16T04:01:02.864418","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.459816Z","iopub.execute_input":"2022-03-04T07:34:20.460126Z","iopub.status.idle":"2022-03-04T07:34:20.474118Z","shell.execute_reply.started":"2022-03-04T07:34:20.460096Z","shell.execute_reply":"2022-03-04T07:34:20.472695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 데이터 나누기","metadata":{"papermill":{"duration":0.027004,"end_time":"2021-08-16T04:01:02.976449","exception":false,"start_time":"2021-08-16T04:01:02.949445","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 훈련 데이터와 테스트 데이터 나누기\nX_train = all_data[~pd.isnull(all_data['count'])]\nX_test = all_data[pd.isnull(all_data['count'])]\n\n# 타깃값 count 제거\nX_train = X_train.drop(['count'], axis=1)\nX_test = X_test.drop(['count'], axis=1)\n\ny = train['count'] # 타깃값","metadata":{"papermill":{"duration":0.046488,"end_time":"2021-08-16T04:01:03.049504","exception":false,"start_time":"2021-08-16T04:01:03.003016","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.475563Z","iopub.execute_input":"2022-03-04T07:34:20.47593Z","iopub.status.idle":"2022-03-04T07:34:20.491414Z","shell.execute_reply.started":"2022-03-04T07:34:20.47587Z","shell.execute_reply":"2022-03-04T07:34:20.490511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 평가지표 계산 함수 작성","metadata":{"papermill":{"duration":0.03003,"end_time":"2021-08-16T04:01:03.107438","exception":false,"start_time":"2021-08-16T04:01:03.077408","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import numpy as np\n\ndef rmsle(y_true, y_pred, convertExp=True):\n    # 지수변환\n    if convertExp:\n        y_true = np.exp(y_true)\n        y_pred = np.exp(y_pred)\n        \n    # 로그변환 후 결측값을 0으로 변환\n    log_true = np.nan_to_num(np.log(y_true+1))\n    log_pred = np.nan_to_num(np.log(y_pred+1))\n    \n    # RMSLE 계산\n    output = np.sqrt(np.mean((log_true - log_pred)**2))\n    return output","metadata":{"papermill":{"duration":0.038583,"end_time":"2021-08-16T04:01:03.175371","exception":false,"start_time":"2021-08-16T04:01:03.136788","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.493197Z","iopub.execute_input":"2022-03-04T07:34:20.493755Z","iopub.status.idle":"2022-03-04T07:34:20.502418Z","shell.execute_reply.started":"2022-03-04T07:34:20.493708Z","shell.execute_reply":"2022-03-04T07:34:20.50147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6.5 성능 개선 I : 릿지 회귀 모델","metadata":{"papermill":{"duration":0.028154,"end_time":"2021-08-16T04:01:03.234205","exception":false,"start_time":"2021-08-16T04:01:03.206051","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## 6.5.1 하이퍼 파라미터 최적화(모델 훈련)","metadata":{"papermill":{"duration":0.028817,"end_time":"2021-08-16T04:01:03.293256","exception":false,"start_time":"2021-08-16T04:01:03.264439","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"### 모델 생성","metadata":{"papermill":{"duration":0.02733,"end_time":"2021-08-16T04:01:03.350188","exception":false,"start_time":"2021-08-16T04:01:03.322858","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.linear_model import Ridge\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn import metrics\n\nridge_model = Ridge()","metadata":{"papermill":{"duration":1.2318,"end_time":"2021-08-16T04:01:04.608585","exception":false,"start_time":"2021-08-16T04:01:03.376785","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:20.503749Z","iopub.execute_input":"2022-03-04T07:34:20.504381Z","iopub.status.idle":"2022-03-04T07:34:21.805729Z","shell.execute_reply.started":"2022-03-04T07:34:20.504339Z","shell.execute_reply":"2022-03-04T07:34:21.804702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 그리드서치 객체 생성","metadata":{"papermill":{"duration":0.025957,"end_time":"2021-08-16T04:01:04.660621","exception":false,"start_time":"2021-08-16T04:01:04.634664","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 하이퍼 파라미터 값 목록\nridge_params = {'max_iter':[3000], 'alpha':[0.1, 1, 2, 3, 4, 10, 30, 100, 200, 300, 400, 800, 900, 1000]}\n\n# 교차 검증용 평가 함수(RMSLE 점수 계산)\nrmsle_scorer = metrics.make_scorer(rmsle, greater_is_better=False)\n# 그리드서치(with 릿지) 객체 생성\ngridsearch_ridge_model = GridSearchCV(estimator=ridge_model,   # 릿지 모델\n                                      param_grid=ridge_params, # 값 목록\n                                      scoring=rmsle_scorer,    # 평가지표\n                                      cv=5)                    # 교차검증 분할 수","metadata":{"papermill":{"duration":0.037757,"end_time":"2021-08-16T04:01:04.723725","exception":false,"start_time":"2021-08-16T04:01:04.685968","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:21.80867Z","iopub.execute_input":"2022-03-04T07:34:21.808956Z","iopub.status.idle":"2022-03-04T07:34:21.816079Z","shell.execute_reply.started":"2022-03-04T07:34:21.808922Z","shell.execute_reply":"2022-03-04T07:34:21.814989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 그리드서치 수행","metadata":{"papermill":{"duration":0.025077,"end_time":"2021-08-16T04:01:04.775118","exception":false,"start_time":"2021-08-16T04:01:04.750041","status":"completed"},"tags":[]}},{"cell_type":"code","source":"log_y = np.log(y) # 타깃값 로그변환\ngridsearch_ridge_model.fit(X_train, log_y) # 훈련(그리드서치)","metadata":{"papermill":{"duration":4.412621,"end_time":"2021-08-16T04:01:09.214754","exception":false,"start_time":"2021-08-16T04:01:04.802133","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:21.817761Z","iopub.execute_input":"2022-03-04T07:34:21.818454Z","iopub.status.idle":"2022-03-04T07:34:24.32431Z","shell.execute_reply.started":"2022-03-04T07:34:21.81841Z","shell.execute_reply":"2022-03-04T07:34:24.323099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('최적 하이퍼파라미터 :', gridsearch_ridge_model.best_params_)","metadata":{"papermill":{"duration":0.063125,"end_time":"2021-08-16T04:01:09.326477","exception":false,"start_time":"2021-08-16T04:01:09.263352","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:24.329773Z","iopub.execute_input":"2022-03-04T07:34:24.332562Z","iopub.status.idle":"2022-03-04T07:34:24.34446Z","shell.execute_reply.started":"2022-03-04T07:34:24.332497Z","shell.execute_reply":"2022-03-04T07:34:24.343474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6.5.2 성능 검증","metadata":{"papermill":{"duration":0.027501,"end_time":"2021-08-16T04:01:09.382203","exception":false,"start_time":"2021-08-16T04:01:09.354702","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 예측\npreds = gridsearch_ridge_model.best_estimator_.predict(X_train) \n\n# 평가\nprint(f'릿지 회귀 RMSLE 값 : {rmsle(log_y, preds, True):.4f}') ","metadata":{"papermill":{"duration":0.165182,"end_time":"2021-08-16T04:01:09.57332","exception":false,"start_time":"2021-08-16T04:01:09.408138","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:24.346565Z","iopub.execute_input":"2022-03-04T07:34:24.347459Z","iopub.status.idle":"2022-03-04T07:34:24.384934Z","shell.execute_reply.started":"2022-03-04T07:34:24.3474Z","shell.execute_reply":"2022-03-04T07:34:24.384073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6.6 성능 개선 II : 라쏘 회귀 모델","metadata":{"papermill":{"duration":0.025903,"end_time":"2021-08-16T04:01:09.627769","exception":false,"start_time":"2021-08-16T04:01:09.601866","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## 6.6.1 하이퍼 파라미터 최적화(모델 훈련)","metadata":{"papermill":{"duration":0.025933,"end_time":"2021-08-16T04:01:09.680902","exception":false,"start_time":"2021-08-16T04:01:09.654969","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.linear_model import Lasso\n\n# 모델 생성\nlasso_model = Lasso()\n# 하이퍼파라미터 값 목록\nlasso_alpha = 1/np.array([0.1, 1, 2, 3, 4, 10, 30, 100, 200, 300, 400, 800, 900, 1000])\nlasso_params = {'max_iter':[3000], 'alpha':lasso_alpha}\n# 그리드서치(with 라쏘) 객체 생성\ngridsearch_lasso_model = GridSearchCV(estimator=lasso_model,\n                                      param_grid=lasso_params,\n                                      scoring=rmsle_scorer,\n                                      cv=5)\n# 그리드서치 수행\nlog_y = np.log(y)\ngridsearch_lasso_model.fit(X_train, log_y)\n\nprint('최적 하이퍼파라미터 :', gridsearch_lasso_model.best_params_)","metadata":{"papermill":{"duration":6.443738,"end_time":"2021-08-16T04:01:16.151014","exception":false,"start_time":"2021-08-16T04:01:09.707276","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:24.38625Z","iopub.execute_input":"2022-03-04T07:34:24.386784Z","iopub.status.idle":"2022-03-04T07:34:28.192008Z","shell.execute_reply.started":"2022-03-04T07:34:24.386741Z","shell.execute_reply":"2022-03-04T07:34:28.191135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6.6.2 성능 검증","metadata":{"papermill":{"duration":0.028013,"end_time":"2021-08-16T04:01:16.218746","exception":false,"start_time":"2021-08-16T04:01:16.190733","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 예측\npreds = gridsearch_lasso_model.best_estimator_.predict(X_train)\n\n# 평가\nprint(f'라쏘 회귀 RMSLE 값 : {rmsle(log_y, preds, True):.4f}')","metadata":{"papermill":{"duration":0.170077,"end_time":"2021-08-16T04:01:16.415444","exception":false,"start_time":"2021-08-16T04:01:16.245367","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:28.193304Z","iopub.execute_input":"2022-03-04T07:34:28.193866Z","iopub.status.idle":"2022-03-04T07:34:28.230153Z","shell.execute_reply.started":"2022-03-04T07:34:28.193822Z","shell.execute_reply":"2022-03-04T07:34:28.229275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 6.7 성능 개선 III : 랜덤 포레스트 회귀 모델","metadata":{"papermill":{"duration":0.027352,"end_time":"2021-08-16T04:01:16.471265","exception":false,"start_time":"2021-08-16T04:01:16.443913","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## 6.7.1 하이퍼 파라미터 최적화(모델 훈련)","metadata":{"papermill":{"duration":0.027033,"end_time":"2021-08-16T04:01:16.52626","exception":false,"start_time":"2021-08-16T04:01:16.499227","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestRegressor\n\n# 모델 생성\nrandomforest_model = RandomForestRegressor()\n# 그리드서치 객체 생성\nrf_params = {'random_state':[42], 'n_estimators':[100, 120, 140]}\ngridsearch_random_forest_model = GridSearchCV(estimator=randomforest_model,\n                                              param_grid=rf_params,\n                                              scoring=rmsle_scorer,\n                                              cv=5)\n# 그리드서치 수행\nlog_y = np.log(y)\ngridsearch_random_forest_model.fit(X_train, log_y)\n\nprint('최적 하이퍼파라미터 :', gridsearch_random_forest_model.best_params_)","metadata":{"papermill":{"duration":56.875969,"end_time":"2021-08-16T04:02:13.42991","exception":false,"start_time":"2021-08-16T04:01:16.553941","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-03-04T07:34:28.231464Z","iopub.execute_input":"2022-03-04T07:34:28.232046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6.7.2 모델 성능 검증","metadata":{"papermill":{"duration":0.027606,"end_time":"2021-08-16T04:02:13.486024","exception":false,"start_time":"2021-08-16T04:02:13.458418","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# 예측\npreds = gridsearch_random_forest_model.best_estimator_.predict(X_train)\n\n# 평가\nprint(f'랜덤 포레스트 회귀 RMSLE 값 : {rmsle(log_y, preds, True):.4f}')","metadata":{"papermill":{"duration":0.407082,"end_time":"2021-08-16T04:02:13.92098","exception":false,"start_time":"2021-08-16T04:02:13.513898","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6.7.3 예측 및 결과 제출","metadata":{"papermill":{"duration":0.027645,"end_time":"2021-08-16T04:02:13.976104","exception":false,"start_time":"2021-08-16T04:02:13.948459","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\n\nrandomforest_preds = gridsearch_random_forest_model.best_estimator_.predict(X_test)\n\nfigure, axes = plt.subplots(ncols=2)\nfigure.set_size_inches(10, 4)\n\nsns.histplot(y, bins=50, ax=axes[0])\naxes[0].set_title('Train Data Distribution')\nsns.histplot(np.exp(randomforest_preds), bins=50, ax=axes[1])\naxes[1].set_title('Predicted Test Data Distribution');","metadata":{"papermill":{"duration":1.097311,"end_time":"2021-08-16T04:02:15.102346","exception":false,"start_time":"2021-08-16T04:02:14.005035","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission['count'] = np.exp(randomforest_preds) # 지수변환\nsubmission.to_csv('submission.csv', index=False)","metadata":{"papermill":{"duration":0.068719,"end_time":"2021-08-16T04:02:15.199894","exception":false,"start_time":"2021-08-16T04:02:15.131175","status":"completed"},"tags":[],"trusted":true},"execution_count":null,"outputs":[]}]}