{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# 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\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-31T14:50:52.393222Z","iopub.execute_input":"2022-07-31T14:50:52.393708Z","iopub.status.idle":"2022-07-31T14:50:52.405865Z","shell.execute_reply.started":"2022-07-31T14:50:52.393671Z","shell.execute_reply":"2022-07-31T14:50:52.404665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 성능 개선 1\n\n베이스라인 모델 자체의 성능 높이기","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\ndata_path = '/kaggle/input/cat-in-the-dat/'\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":{"execution":{"iopub.status.busy":"2022-07-31T14:50:52.408192Z","iopub.execute_input":"2022-07-31T14:50:52.409231Z","iopub.status.idle":"2022-07-31T14:50:55.174218Z","shell.execute_reply.started":"2022-07-31T14:50:52.409187Z","shell.execute_reply":"2022-07-31T14:50:55.172824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 피처 맞춤 인코딩\n\n이전 베이스라인 모델은 모든 피처 원핫으로 인코딩했지만 이것은 피처별로 맞는 인코딩 방식 선택","metadata":{}},{"cell_type":"code","source":"# 데이터 합치기\n\nall_data = pd.concat([train, test])\nall_data = all_data.drop('target', axis = 1)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:55.176548Z","iopub.execute_input":"2022-07-31T14:50:55.176995Z","iopub.status.idle":"2022-07-31T14:50:55.970862Z","shell.execute_reply.started":"2022-07-31T14:50:55.176955Z","shell.execute_reply":"2022-07-31T14:50:55.969480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"이진 피처 인코딩","metadata":{}},{"cell_type":"code","source":"all_data['bin_3'] = all_data['bin_3'].map({'F':0, 'T':1})\nall_data['bin_4'] = all_data['bin_4'].map({'N':0, 'Y':1})","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:55.974180Z","iopub.execute_input":"2022-07-31T14:50:55.974636Z","iopub.status.idle":"2022-07-31T14:50:56.427324Z","shell.execute_reply.started":"2022-07-31T14:50:55.974597Z","shell.execute_reply":"2022-07-31T14:50:56.425806Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"순서형 피처 인코딩","metadata":{}},{"cell_type":"code","source":"ord1dict = {'Novice': 0, 'Contributor': 1, 'Expert':2, 'Master':3, 'Grandmaster':4}\nord2dict = {'Freezing':0, 'Cold':1, 'Warm':2, 'Hot':3, 'Boiling Hot':4, 'Lava Hot':5}\n\nall_data['ord_1'] = all_data['ord_1'].map(ord1dict)\nall_data['ord_2'] = all_data['ord_2'].map(ord2dict)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:56.429339Z","iopub.execute_input":"2022-07-31T14:50:56.429874Z","iopub.status.idle":"2022-07-31T14:50:56.838775Z","shell.execute_reply.started":"2022-07-31T14:50:56.429824Z","shell.execute_reply":"2022-07-31T14:50:56.837305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OrdinalEncoder\n\nord_345 = ['ord_3', 'ord_4', 'ord_5']\n\nord_encoder = OrdinalEncoder() #ordinalencoder은 알파벳 순서대로 숫자로 인코딩\n\nall_data[ord_345] = ord_encoder.fit_transform(all_data[ord_345])\n\n\nfor feature, categories in zip(ord_345, ord_encoder.categories_): #피처별 인코딩 순서 보여줌\n    print(feature)\n    print(categories)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:56.840612Z","iopub.execute_input":"2022-07-31T14:50:56.841719Z","iopub.status.idle":"2022-07-31T14:50:57.774589Z","shell.execute_reply.started":"2022-07-31T14:50:56.841658Z","shell.execute_reply":"2022-07-31T14:50:57.773271Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"명목형 피처 인코딩","metadata":{}},{"cell_type":"code","source":"nom_features = ['nom_' + str(i) for i in range(10)]\n# nom_0 ~ 9까지의 명목형 피처 리스트","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:57.776451Z","iopub.execute_input":"2022-07-31T14:50:57.777607Z","iopub.status.idle":"2022-07-31T14:50:57.784227Z","shell.execute_reply.started":"2022-07-31T14:50:57.777552Z","shell.execute_reply":"2022-07-31T14:50:57.782563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 원핫인코딩을 하면 행렬이 되므로 열 개수가 늘어나서 다시 all_data에 저장 불가. \n# 지금까지는 수작업인코딩이나 ordinal이어서 상관X\n# 따라서 인코딩 후 새로운 변수에 저장\n\nfrom sklearn.preprocessing import OneHotEncoder\nonehot_encoder = OneHotEncoder()\n\nencoded_nom_matrix = onehot_encoder.fit_transform(all_data[nom_features])\n\nencoded_nom_matrix","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:50:57.786008Z","iopub.execute_input":"2022-07-31T14:50:57.788973Z","iopub.status.idle":"2022-07-31T14:51:00.553700Z","shell.execute_reply.started":"2022-07-31T14:50:57.788912Z","shell.execute_reply":"2022-07-31T14:51:00.551420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"원핫을 하면 대부분의 원소가 0으로 채워진 희소행렬(반대는 밀집행렬)이 만들어짐\n\n메모리가 0이면 자리만 차지하고 의미가 없어서 메모리 낭비가 심해짐\n\n이 떄 COO나 CSR로 표현하면 메모리 낭비가 줄어 듦, 그래서 원핫인코더를 사용하면 저절로CSR로 저장","metadata":{}},{"cell_type":"code","source":"all_data = all_data.drop(nom_features, axis = 1)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:00.557695Z","iopub.execute_input":"2022-07-31T14:51:00.558164Z","iopub.status.idle":"2022-07-31T14:51:00.606746Z","shell.execute_reply.started":"2022-07-31T14:51:00.558120Z","shell.execute_reply":"2022-07-31T14:51:00.605528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"날짜 피처 인코딩","metadata":{}},{"cell_type":"code","source":"date_features = ['day', 'month']\n\nencoded_date_matrix = onehot_encoder.fit_transform(all_data[date_features])\n\nall_data = all_data.drop(date_features, axis = 1)\n\nencoded_date_matrix","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:00.608879Z","iopub.execute_input":"2022-07-31T14:51:00.610355Z","iopub.status.idle":"2022-07-31T14:51:00.789607Z","shell.execute_reply.started":"2022-07-31T14:51:00.610263Z","shell.execute_reply":"2022-07-31T14:51:00.788028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 피처 엔지니어링2: 피처 스케일링","metadata":{}},{"cell_type":"markdown","source":"순서형  피처 스케일링: min-max 정규화","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import MinMaxScaler\nord_features = ['ord_' + str(i) for i in range(6)]\nall_data[ord_features] = MinMaxScaler().fit_transform(all_data[ord_features])\n\n# 순서형 피처들도 0~1사이의 값들로 맞추어 주기 (0, 0.2, 0.4 ... 1)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:00.790991Z","iopub.execute_input":"2022-07-31T14:51:00.791397Z","iopub.status.idle":"2022-07-31T14:51:00.886752Z","shell.execute_reply.started":"2022-07-31T14:51:00.791346Z","shell.execute_reply":"2022-07-31T14:51:00.885406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"데이터 합치기: all_data, encoded_nom_matrix, encoded_date_matrix\n\nall_data는 Dataframe 형식이고 나머지 두 개는 CSR형식의 행렬이므로 형식 맞춰주기","metadata":{}},{"cell_type":"code","source":"from scipy import sparse # 사이파이 불러오기\n\nall_data_sprs = sparse.hstack([sparse.csr_matrix(all_data), # crs.matrix(): crs로 바꿔주기, hstac: 행렬을 수평방항으로 합침\n                              encoded_nom_matrix, \n                              encoded_date_matrix], \n                              format = 'csr')               # hstack 기본이 COO형식이라 포맷 지정해주기","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:00.888721Z","iopub.execute_input":"2022-07-31T14:51:00.890127Z","iopub.status.idle":"2022-07-31T14:51:01.688703Z","shell.execute_reply.started":"2022-07-31T14:51:00.890082Z","shell.execute_reply":"2022-07-31T14:51:01.686816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_data_sprs ","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:01.690821Z","iopub.execute_input":"2022-07-31T14:51:01.691404Z","iopub.status.idle":"2022-07-31T14:51:01.702005Z","shell.execute_reply.started":"2022-07-31T14:51:01.691351Z","shell.execute_reply":"2022-07-31T14:51:01.700026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 데이터 나누기\n\n훈련 데이터와 테스트 데이터","metadata":{}},{"cell_type":"code","source":"num_train = len(train)\n\nX_train = all_data_sprs[:num_train]\nX_test = all_data_sprs[num_train:]\n\ny= train['target']","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:01.703997Z","iopub.execute_input":"2022-07-31T14:51:01.704528Z","iopub.status.idle":"2022-07-31T14:51:01.873841Z","shell.execute_reply.started":"2022-07-31T14:51:01.704462Z","shell.execute_reply":"2022-07-31T14:51:01.872434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"훈련 데이터를 훈련 데이터와 검증 데이터로","metadata":{}},{"cell_type":"code","source":"'''from sklearn.model_selection import train_test_split\n\nX_train, X_valid, y_train, y_valid = train_test_split(X_train, y, \n                                                      test_size = 0.1,\n                                                     stratify = y,\n                                                     random_state = 10)'''","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:01.875557Z","iopub.execute_input":"2022-07-31T14:51:01.875943Z","iopub.status.idle":"2022-07-31T14:51:01.886107Z","shell.execute_reply.started":"2022-07-31T14:51:01.875909Z","shell.execute_reply":"2022-07-31T14:51:01.884607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 하이퍼파라미터 최적화\n\n그리드서치 이용 (c: 규제 강도 조절(값이 작을수록 센 규제 강도), max_iter: ?? 암튼 탐색할거임)","metadata":{}},{"cell_type":"code","source":"%%time\n\nfrom sklearn.model_selection import GridSearchCV\nfrom sklearn.linear_model import LogisticRegression\n\nlogistic_model = LogisticRegression()\n\nlr_params = {'C': [0.1, 0.125, 0.2],          # 탐색할 C값들\n             'max_iter':[800, 900, 1000],     # 탐색할 maxiter값들\n             'solver': ['liblinear'],         # 고정된 하이퍼파라미터, 선형회귀 방식으로 무제를 해결한다는 뜻 같음\n             'random_state': [42]}\n\ngridsearch_logistic_model = GridSearchCV(estimator = logistic_model, \n                                         param_grid = lr_params, \n                                         scoring = 'roc_auc', \n                                         cv = 5)\n\ngridsearch_logistic_model.fit(X_train, y)\n\nprint('최적 하이퍼파라미터: ', gridsearch_logistic_model.best_params_)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:52:57.008574Z","iopub.execute_input":"2022-07-31T14:52:57.009044Z","iopub.status.idle":"2022-07-31T15:02:50.424099Z","shell.execute_reply.started":"2022-07-31T14:52:57.009007Z","shell.execute_reply":"2022-07-31T15:02:50.422935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 모델 성능 검증\n\n검증 데이터를 이용하여","metadata":{}},{"cell_type":"code","source":"# 타깃 예측값 구하기\ny_preds = gridsearch_logistic_model.best_estimator_.predict_proba(X_test)[:, 1]","metadata":{"execution":{"iopub.status.busy":"2022-07-31T15:07:43.163739Z","iopub.execute_input":"2022-07-31T15:07:43.164162Z","iopub.status.idle":"2022-07-31T15:07:43.186301Z","shell.execute_reply.started":"2022-07-31T15:07:43.164129Z","shell.execute_reply":"2022-07-31T15:07:43.184948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''# roc auc 검증 데이터로 구해보기\n\nfrom sklearn.metrics import roc_auc_score\n\nroc_auc = roc_auc_score(y_valid, y_valid_preds)\n\nprint(f'검증 데이터 ROC AUC: {roc_auc:.4f}')'''","metadata":{"execution":{"iopub.status.busy":"2022-07-31T14:51:01.969960Z","iopub.status.idle":"2022-07-31T14:51:01.970771Z","shell.execute_reply.started":"2022-07-31T14:51:01.970222Z","shell.execute_reply":"2022-07-31T14:51:01.970245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 원래 코드:훈련 데이터를 훈련/검증으로 나눌 때 0.1 비율로\n# improvecode: 나누는 비율 지정 코드 관련 제거하고 나머지는 동일하게","metadata":{}},{"cell_type":"markdown","source":"# 결과 제출","metadata":{}},{"cell_type":"code","source":"submission['target'] = y_preds\nsubmission.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2022-07-31T15:07:46.103280Z","iopub.execute_input":"2022-07-31T15:07:46.103755Z","iopub.status.idle":"2022-07-31T15:07:46.911235Z","shell.execute_reply.started":"2022-07-31T15:07:46.103719Z","shell.execute_reply":"2022-07-31T15:07:46.910107Z"},"trusted":true},"execution_count":null,"outputs":[]}]}