{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":74571,"databundleVersionId":8671431,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, f1_score, roc_auc_score\nfrom lightgbm import LGBMClassifier\nfrom imblearn.over_sampling import SMOTE\nfrom sklearn.model_selection import GridSearchCV, KFold\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-27T07:23:46.143884Z","iopub.execute_input":"2024-06-27T07:23:46.144931Z","iopub.status.idle":"2024-06-27T07:23:50.854756Z","shell.execute_reply.started":"2024-06-27T07:23:46.144889Z","shell.execute_reply":"2024-06-27T07:23:50.853556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 계획\n### Data Overview\n- info, shape ...\n### Data Processing\n- missing value\n- outlier\n### Data Split\n- train / test\n### Model\n- SMOTE\n- LightGBM\n- 로지스틱 회귀","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"# 1. Data Overview","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/affel-ds2-credit-card/train.csv')\ntest = pd.read_csv('/kaggle/input/affel-ds2-credit-card/test.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:23:50.858449Z","iopub.execute_input":"2024-06-27T07:23:50.859246Z","iopub.status.idle":"2024-06-27T07:23:55.555599Z","shell.execute_reply.started":"2024-06-27T07:23:50.859194Z","shell.execute_reply":"2024-06-27T07:23:55.554531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train.shape)\nprint(test.shape)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:24:15.961072Z","iopub.execute_input":"2024-06-27T07:24:15.962232Z","iopub.status.idle":"2024-06-27T07:24:15.969189Z","shell.execute_reply.started":"2024-06-27T07:24:15.962175Z","shell.execute_reply":"2024-06-27T07:24:15.967759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:24:27.644417Z","iopub.execute_input":"2024-06-27T07:24:27.645628Z","iopub.status.idle":"2024-06-27T07:24:27.673797Z","shell.execute_reply.started":"2024-06-27T07:24:27.645582Z","shell.execute_reply":"2024-06-27T07:24:27.672394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:24:34.524034Z","iopub.execute_input":"2024-06-27T07:24:34.524616Z","iopub.status.idle":"2024-06-27T07:24:34.559776Z","shell.execute_reply.started":"2024-06-27T07:24:34.524571Z","shell.execute_reply":"2024-06-27T07:24:34.558431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.info()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:24:56.293872Z","iopub.execute_input":"2024-06-27T07:24:56.294310Z","iopub.status.idle":"2024-06-27T07:24:56.340046Z","shell.execute_reply.started":"2024-06-27T07:24:56.294274Z","shell.execute_reply":"2024-06-27T07:24:56.338856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.describe()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:25:16.801542Z","iopub.execute_input":"2024-06-27T07:25:16.801970Z","iopub.status.idle":"2024-06-27T07:25:17.156520Z","shell.execute_reply.started":"2024-06-27T07:25:16.801940Z","shell.execute_reply":"2024-06-27T07:25:17.155406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.columns","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:25:37.905527Z","iopub.execute_input":"2024-06-27T07:25:37.906628Z","iopub.status.idle":"2024-06-27T07:25:37.914056Z","shell.execute_reply.started":"2024-06-27T07:25:37.906587Z","shell.execute_reply":"2024-06-27T07:25:37.912841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.columns","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:25:45.948684Z","iopub.execute_input":"2024-06-27T07:25:45.949134Z","iopub.status.idle":"2024-06-27T07:25:45.957287Z","shell.execute_reply.started":"2024-06-27T07:25:45.949096Z","shell.execute_reply":"2024-06-27T07:25:45.955987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['Class'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:26:00.946859Z","iopub.execute_input":"2024-06-27T07:26:00.947480Z","iopub.status.idle":"2024-06-27T07:26:00.961864Z","shell.execute_reply.started":"2024-06-27T07:26:00.947423Z","shell.execute_reply":"2024-06-27T07:26:00.960393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# class 분포 확인\nprint(train['Class'].value_counts())\nsns.countplot(x=train['Class'], data=train)\nplt.show\nprint(train['Class'].value_counts(normalize=True))","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:26:34.143641Z","iopub.execute_input":"2024-06-27T07:26:34.144507Z","iopub.status.idle":"2024-06-27T07:26:34.505768Z","shell.execute_reply.started":"2024-06-27T07:26:34.144433Z","shell.execute_reply":"2024-06-27T07:26:34.504577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"### Data overview 결과\n- 칼럼들을 확인하고 전체적인 데이터의 짜임새로 내용 숙지\n- 피처들 타입 중 object는 없음\n- V로 시작하는 칼럼들은 의미를 알 수 없음\n- Amount 피처는 신용카드 트랜잭션 금액\n- Class는 레이블 - 0은 정상거래 / 1은 사기거래\n- Class 분포 확인결과 -> 0 0.997893 / 1 0.002107 (정상거래는 99프로, 사기거래는 0.2프로)\n- Class 분포 확인결과 - 비율 차이가 심함","metadata":{}},{"cell_type":"markdown","source":"# 2. Data Processing","metadata":{}},{"cell_type":"code","source":"print(train.isna().sum().sum())\nprint(test.isna().sum().sum())\n# 결측치 없음","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:28:40.320629Z","iopub.execute_input":"2024-06-27T07:28:40.321082Z","iopub.status.idle":"2024-06-27T07:28:40.346707Z","shell.execute_reply.started":"2024-06-27T07:28:40.321050Z","shell.execute_reply":"2024-06-27T07:28:40.345441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.duplicated().sum() \n# 중복값 없음","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:28:45.914199Z","iopub.execute_input":"2024-06-27T07:28:45.914630Z","iopub.status.idle":"2024-06-27T07:28:46.361827Z","shell.execute_reply.started":"2024-06-27T07:28:45.914598Z","shell.execute_reply":"2024-06-27T07:28:46.360443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def del_outlier(df=None, column=None, weight=1.5):\n    fraud = df[df[\"Class\"] == 1][column]\n    \n    quantile_25 = np.percentile(fraud.values, 25)\n    quantile_75 = np.percentile(fraud.values, 75)\n    iqr = quantile_75 - quantile_25\n    \n    iqr_weight = iqr * weight\n    lowest_val = quantile_25 - iqr_weight\n    highest_val = quantile_75 + iqr_weight\n    \n    outlier_index = fraud[(fraud < lowest_val) | (fraud > highest_val)].index\n    \n    return outdel_df","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:32:15.654843Z","iopub.execute_input":"2024-06-27T07:32:15.655333Z","iopub.status.idle":"2024-06-27T07:32:15.663526Z","shell.execute_reply.started":"2024-06-27T07:32:15.655299Z","shell.execute_reply":"2024-06-27T07:32:15.662032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 데이터 전처리 과정\n- 결측치 없음\n- 이상치는 백분위수로 함수를 만들어서 제거","metadata":{}},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"X = train.drop('Class', axis=1) \ny = train['Class']","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:33:52.770412Z","iopub.execute_input":"2024-06-27T07:33:52.770871Z","iopub.status.idle":"2024-06-27T07:33:52.798190Z","shell.execute_reply.started":"2024-06-27T07:33:52.770835Z","shell.execute_reply":"2024-06-27T07:33:52.796926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:33:53.554558Z","iopub.execute_input":"2024-06-27T07:33:53.554993Z","iopub.status.idle":"2024-06-27T07:33:53.690687Z","shell.execute_reply.started":"2024-06-27T07:33:53.554963Z","shell.execute_reply":"2024-06-27T07:33:53.689305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"smote = SMOTE(random_state=0)\n\nX_train_over, y_train_over = smote.fit_resample(X_train, y_train)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:34:30.152544Z","iopub.execute_input":"2024-06-27T07:34:30.152999Z","iopub.status.idle":"2024-06-27T07:34:30.540497Z","shell.execute_reply.started":"2024-06-27T07:34:30.152964Z","shell.execute_reply":"2024-06-27T07:34:30.539300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"SMOTE 적용 전 학습용 피처/레이블 데이터 세트: \", X_train.shape, y_train.shape)\nprint(\"\\nSMOTE 적용 후 학습용 피처/레이블 데이터 세트: \", X_train_over.shape, y_train_over.shape)\nprint(\"\\nSMOTE 적용 후 레이블 값 분포: \\n\", pd.Series(y_train_over).value_counts())","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:35:38.879736Z","iopub.execute_input":"2024-06-27T07:35:38.880179Z","iopub.status.idle":"2024-06-27T07:35:38.891411Z","shell.execute_reply.started":"2024-06-27T07:35:38.880146Z","shell.execute_reply":"2024-06-27T07:35:38.890260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"class 확인 했을 때 비율 차이가 심했음\n\nSMOTE로 학습 데이터 불균형 해결","metadata":{}},{"cell_type":"markdown","source":"# 모델 학습","metadata":{}},{"cell_type":"code","source":"# 평가 함수\ndef get_clf_eval(y_test, pred, pred_proba=None):\n    confusion = confusion_matrix(y_test, pred)\n    accuracy = accuracy_score(y_test, pred)\n    precision = precision_score(y_test, pred)\n    recall = recall_score(y_test, pred)\n    f1 = f1_score(y_test, pred)\n    \n    roc_auc = roc_auc_score(y_test, pred_proba)\n    \n    \n    print(\"오차 행렬\")\n    print(confusion)\n    print(f\"정확도: {accuracy:.4f}, 정밀도: {precision: .4f}, 재현율: {recall: .4f}, f1스코어: {f1:.4f}, roc-auc: {roc_auc:.4f}\")\n    # 정확도, 정밀도, 재현율, f1, roc auc를 평가","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:41:52.269615Z","iopub.execute_input":"2024-06-27T07:41:52.270116Z","iopub.status.idle":"2024-06-27T07:41:52.281211Z","shell.execute_reply.started":"2024-06-27T07:41:52.270079Z","shell.execute_reply":"2024-06-27T07:41:52.280081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model 함수\ndef get_model_train_eval(model, ftr_train=None, ftr_test=None, tgt_train=None, tgt_test=None):\n    model.fit(ftr_train, tgt_train)\n    pred = model.predict(ftr_test)\n    pred_proba = model.predict_proba(ftr_test)[:, 1]\n    get_clf_eval(tgt_test, pred, pred_proba)\n# 모델 학습 함수","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:41:53.052868Z","iopub.execute_input":"2024-06-27T07:41:53.053334Z","iopub.status.idle":"2024-06-27T07:41:53.062885Z","shell.execute_reply.started":"2024-06-27T07:41:53.053301Z","shell.execute_reply":"2024-06-27T07:41:53.061727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lgbm_clf = LGBMClassifier(n_estimators=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:42:57.314217Z","iopub.execute_input":"2024-06-27T07:42:57.315301Z","iopub.status.idle":"2024-06-27T07:42:57.325723Z","shell.execute_reply.started":"2024-06-27T07:42:57.315248Z","shell.execute_reply":"2024-06-27T07:42:57.324191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# SMOTE 적용 후 LightGBM 학습 후 평가\nget_model_train_eval(model = lgbm_clf, ftr_train=X_train_over, ftr_test=X_test, tgt_train=y_train_over, tgt_test=y_test)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:42:57.987527Z","iopub.execute_input":"2024-06-27T07:42:57.988021Z","iopub.status.idle":"2024-06-27T07:44:34.820647Z","shell.execute_reply.started":"2024-06-27T07:42:57.987983Z","shell.execute_reply":"2024-06-27T07:44:34.819336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### SMOTE와 LightGBM을 사용하여 모델 학습\n- 정확도: 0.9995, 정밀도:  0.8846, 재현율:  0.8519, f1스코어: 0.8679, roc-auc: 0.9726","metadata":{}},{"cell_type":"markdown","source":"# 제출","metadata":{}},{"cell_type":"code","source":"main = lgbm_clf.predict_proba(test)[:, 1]","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:45:40.997458Z","iopub.execute_input":"2024-06-27T07:45:40.997907Z","iopub.status.idle":"2024-06-27T07:45:47.229129Z","shell.execute_reply.started":"2024-06-27T07:45:40.997872Z","shell.execute_reply":"2024-06-27T07:45:47.227969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.shape","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:45:48.505632Z","iopub.execute_input":"2024-06-27T07:45:48.506709Z","iopub.status.idle":"2024-06-27T07:45:48.514170Z","shell.execute_reply.started":"2024-06-27T07:45:48.506670Z","shell.execute_reply":"2024-06-27T07:45:48.512655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"main.shape","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:46:06.263631Z","iopub.execute_input":"2024-06-27T07:46:06.264020Z","iopub.status.idle":"2024-06-27T07:46:06.271203Z","shell.execute_reply.started":"2024-06-27T07:46:06.263990Z","shell.execute_reply":"2024-06-27T07:46:06.270053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({'id': test['id'], 'Class': main})","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:48:02.692519Z","iopub.execute_input":"2024-06-27T07:48:02.693597Z","iopub.status.idle":"2024-06-27T07:48:02.700051Z","shell.execute_reply.started":"2024-06-27T07:48:02.693531Z","shell.execute_reply":"2024-06-27T07:48:02.698861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T07:48:03.531655Z","iopub.execute_input":"2024-06-27T07:48:03.532047Z","iopub.status.idle":"2024-06-27T07:48:03.934792Z","shell.execute_reply.started":"2024-06-27T07:48:03.532019Z","shell.execute_reply":"2024-06-27T07:48:03.933536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 회고\n- 기본적으로 제공되어있던 Baseline과 책을 참고로 진행함\n- 결측치와 이상치 처리하는 부분에선 시간이 적게 걸렸는데 모델 학습을 하는 부분이 굉장히 오래 걸렸다.\n- 해당 파일에는 코드가 굉장히 깔끔하게 정리되어 있는데 이전에 다른 파일에서 진행하면서 이것저것 시도해보다 보니 가독성이 엉망진창인데다 버전관리가 엉켜버려서 이전 파일에서 유의미한 결과를 얻은 코드들을 정리한 파일이 해당 파일이다.\n- 처음엔 스케일링도 해보려 했고 하이퍼파라미터튜닝 Kfold 등등 이것저것 구상하고 시도도 해보았는데 좋은 성과는 이루지 못했다 약 0.42 정도의 점수를 받아서 싹 갈아엎었다.\n- 원본데이터로 로지스틱 회귀, SMOTE 이후 로지스틱 회귀, 원본데이터로 LightGBM, SMOTE 이후 LightGBM을 다 확인해본 결과 SMOTE 적용 후 LightGBM 학습 후 평가가 제일 높은 결과가 나옴을 확인했다.\n- SMOTE 적용 후 LightGBM 학습 후 평가\n    -> 정확도: 0.9995, 정밀도:  0.8846, 재현율:  0.8519, f1스코어: 0.8679, roc-auc: 0.9726","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}