{"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"}],"dockerImageVersionId":30732,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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":"2024-06-27T10:53:52.874879Z","iopub.execute_input":"2024-06-27T10:53:52.875299Z","iopub.status.idle":"2024-06-27T10:53:53.999883Z","shell.execute_reply.started":"2024-06-27T10:53:52.875266Z","shell.execute_reply":"2024-06-27T10:53:53.998585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train = pd.read_csv('/kaggle/input/affel-ds2-credit-card/train.csv')\ny_train = pd.read_csv('/kaggle/input/affel-ds2-credit-card/test.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-27T10:54:36.151035Z","iopub.execute_input":"2024-06-27T10:54:36.151430Z","iopub.status.idle":"2024-06-27T10:54:40.658512Z","shell.execute_reply.started":"2024-06-27T10:54:36.151396Z","shell.execute_reply":"2024-06-27T10:54:40.657346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 데이터 살펴보기","metadata":{}},{"cell_type":"code","source":"X_train.info()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T10:56:55.174568Z","iopub.execute_input":"2024-06-27T10:56:55.174995Z","iopub.status.idle":"2024-06-27T10:56:55.210791Z","shell.execute_reply.started":"2024-06-27T10:56:55.174957Z","shell.execute_reply":"2024-06-27T10:56:55.209762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train.describe()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T10:57:55.730673Z","iopub.execute_input":"2024-06-27T10:57:55.731092Z","iopub.status.idle":"2024-06-27T10:57:56.034381Z","shell.execute_reply.started":"2024-06-27T10:57:55.731057Z","shell.execute_reply":"2024-06-27T10:57:56.033304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train.head(3)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T10:58:09.956883Z","iopub.execute_input":"2024-06-27T10:58:09.957297Z","iopub.status.idle":"2024-06-27T10:58:09.983100Z","shell.execute_reply.started":"2024-06-27T10:58:09.957265Z","shell.execute_reply":"2024-06-27T10:58:09.981974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualization","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport seaborn as sns\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:02:32.718469Z","iopub.execute_input":"2024-06-27T11:02:32.718865Z","iopub.status.idle":"2024-06-27T11:02:33.362770Z","shell.execute_reply.started":"2024-06-27T11:02:32.718833Z","shell.execute_reply":"2024-06-27T11:02:33.361761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 피처(독립변수) 분포 시각화를 위한 작업\nX_train_c = X_train['Class']\nX_train_1 = X_train.drop(columns=['Class', 'id'])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:02:35.369002Z","iopub.execute_input":"2024-06-27T11:02:35.369403Z","iopub.status.idle":"2024-06-27T11:02:35.392565Z","shell.execute_reply.started":"2024-06-27T11:02:35.369372Z","shell.execute_reply":"2024-06-27T11:02:35.391203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 시각화\nplt.figure(figsize=(20, 16))\nnum_features = len(X_train.columns)\n\nfor i, col in enumerate(X_train_1.columns, 1):\n    plt.subplot((num_features // 5) + 1, 5, i)\n    sns.histplot(X_train_1[col], bins=30, kde=True)\n    plt.title(f'Distribution of {col}')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:03:48.043328Z","iopub.execute_input":"2024-06-27T11:03:48.043761Z","iopub.status.idle":"2024-06-27T11:04:23.074004Z","shell.execute_reply.started":"2024-06-27T11:03:48.043726Z","shell.execute_reply":"2024-06-27T11:04:23.072935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # 피처 분포 시각화를 통해 생각해본 것들\n# 1. 'Time' 피처는 분포가 고르지 않고 특정 시간대에 거래가 집중되어 있음 = 특정 시간대 거래가 몰려있는 사용자 행동 패턴 도출 가능\n# 2. 'Amount' 피처는 대부분의 거래가 소액>고액. 사기거래 탐지에서 고액거래가 더 리스크가 있으므로 주시 필요\n# 3. PCA 변환된 피처들(V1 ~ V28): 대부분은 정규 분포를 따름. 일부 피처들은 극단적 값 가지는 이상치 존재 가능성 있음","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# boxplot을 통한 시각화\nplt.figure(figsize=(20, 16))\nnum_features = len(X_train_1.columns)\n\nfor i, col in enumerate(X_train_1.columns, 1):\n    plt.subplot((num_features // 5) + 1, 5, i)\n    sns.boxplot(x=X_train_1[col])\n    plt.title(f'Boxplot of {col}')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:05:28.826039Z","iopub.execute_input":"2024-06-27T11:05:28.826572Z","iopub.status.idle":"2024-06-27T11:05:33.769135Z","shell.execute_reply.started":"2024-06-27T11:05:28.826526Z","shell.execute_reply":"2024-06-27T11:05:33.767951Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# scatterplot을 통한 시각화 - 타겟 변수에 따른 색상 구분!\n\nplt.figure(figsize=(20, 16))\nfor i, col in enumerate(X_train_1.columns, 1):\n    plt.subplot((num_features // 5) + 1, 5, i)\n    sns.scatterplot(x=X_train_1[col], y=X_train_c, hue=X_train_c, alpha=0.3)\n    plt.title(f'Scatterplot of {col} vs Class')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:06:32.301175Z","iopub.execute_input":"2024-06-27T11:06:32.301578Z","iopub.status.idle":"2024-06-27T11:09:28.186441Z","shell.execute_reply.started":"2024-06-27T11:06:32.301545Z","shell.execute_reply":"2024-06-27T11:09:28.185229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 타겟 변수인 Class 와의 관계 시각화\nplt.figure(figsize=(20, 16))\nfor i, col in enumerate(X_train_1.columns, 1):\n    plt.subplot(6, 5, i)\n    sns.boxplot(x=X_train_c, y=X_train_1[col])\n    plt.title(f'{col} vs Class')\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:09:34.755123Z","iopub.execute_input":"2024-06-27T11:09:34.755525Z","iopub.status.idle":"2024-06-27T11:09:41.517682Z","shell.execute_reply.started":"2024-06-27T11:09:34.755494Z","shell.execute_reply":"2024-06-27T11:09:41.516238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Class와 피처 간 관계 시각화를 통해 생각해 본 것들\n# 1. Time: 사기 거래와 비사기 거래 간의 분포 차이가 크게 보이지 않음\n# 2. V1 ~ V28: 여러 개 피처에서 사기 거래와 비사기 거래간 분포 차이가 두드러짐(V10, V17 등)\n# 3. Amount: 사기 거래에서 평균적으로 더 높은 값 = 고액 거래 사기 가능성 더 높음 유추","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 상관관계 분석을 위한 시각화\nplt.figure(figsize=(18, 16))\ncorr_matrix = X_train_1.corr()\nsns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm')\nplt.title('Correlation Matrix')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:10:03.117875Z","iopub.execute_input":"2024-06-27T11:10:03.118659Z","iopub.status.idle":"2024-06-27T11:10:06.083082Z","shell.execute_reply.started":"2024-06-27T11:10:03.118622Z","shell.execute_reply":"2024-06-27T11:10:06.082024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# NaN, Outlier","metadata":{}},{"cell_type":"code","source":"# 결측치 확인\nmissing_values = X_train_1.isnull().sum()\nprint(\"Missing values in each feature:\")\nprint(missing_values[missing_values > 0])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:16:02.282744Z","iopub.execute_input":"2024-06-27T11:16:02.283261Z","iopub.status.idle":"2024-06-27T11:16:02.299140Z","shell.execute_reply.started":"2024-06-27T11:16:02.283221Z","shell.execute_reply":"2024-06-27T11:16:02.297892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 이상치를 제거 - IQR\ndef remove_outliers(df):\n    Q1 = df.quantile(0.25)\n    Q3 = df.quantile(0.75)\n    IQR = Q3 - Q1\n    is_outlier = (df < (Q1 - 1.5 * IQR)) | (df > (Q3 + 1.5 * IQR))\n    df_cleaned = df[~is_outlier.any(axis=1)]\n    return df_cleaned","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:22:46.960539Z","iopub.execute_input":"2024-06-27T11:22:46.961515Z","iopub.status.idle":"2024-06-27T11:22:46.967940Z","shell.execute_reply.started":"2024-06-27T11:22:46.961477Z","shell.execute_reply":"2024-06-27T11:22:46.966738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 이상치 제거 전 데이터 크기\nprint(f\"Original dataset shape: {X_train_1.shape}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:23:08.020251Z","iopub.execute_input":"2024-06-27T11:23:08.021159Z","iopub.status.idle":"2024-06-27T11:23:08.026462Z","shell.execute_reply.started":"2024-06-27T11:23:08.021124Z","shell.execute_reply":"2024-06-27T11:23:08.025303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 이상치 제거\nX_train_clean = remove_outliers(X_train_1)\ny_train_clean = X_train_c.loc[X_train_clean.index]","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:14:22.014609Z","iopub.execute_input":"2024-06-27T12:14:22.015424Z","iopub.status.idle":"2024-06-27T12:14:22.219208Z","shell.execute_reply.started":"2024-06-27T12:14:22.015385Z","shell.execute_reply":"2024-06-27T12:14:22.218008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 이상치 제거 후 데이터 크기\nprint(f\"Cleaned dataset shape: {X_train_clean.shape}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:14:32.964750Z","iopub.execute_input":"2024-06-27T12:14:32.965169Z","iopub.status.idle":"2024-06-27T12:14:32.971225Z","shell.execute_reply.started":"2024-06-27T12:14:32.965140Z","shell.execute_reply":"2024-06-27T12:14:32.969890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 이상치 제거 전후 비교\nprint(\"Before cleaning:\")\nprint(X_train_1.describe())\n\nprint(\"\\nAfter cleaning:\")\nprint(X_train_clean.describe())","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:28:14.789270Z","iopub.execute_input":"2024-06-27T11:28:14.789685Z","iopub.status.idle":"2024-06-27T11:28:15.250912Z","shell.execute_reply.started":"2024-06-27T11:28:14.789651Z","shell.execute_reply":"2024-06-27T11:28:15.249519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Scaling","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler","metadata":{"execution":{"iopub.status.busy":"2024-06-27T11:58:56.487274Z","iopub.execute_input":"2024-06-27T11:58:56.487667Z","iopub.status.idle":"2024-06-27T11:58:56.568526Z","shell.execute_reply.started":"2024-06-27T11:58:56.487637Z","shell.execute_reply":"2024-06-27T11:58:56.567081Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 다른 피처들은 PCA를 통해 변환된 값들로 이미 스케일이 비슷할 것으로 예상, Amount와 Time 피처에만 스케일링 적용\n# 값의 범위가 넓을 수 있는 Amount 로그변환\n\nX_train_clean['Log_Amount'] = np.log1p(X_train_clean['Amount'])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:02:47.897587Z","iopub.execute_input":"2024-06-27T12:02:47.898178Z","iopub.status.idle":"2024-06-27T12:02:47.906665Z","shell.execute_reply.started":"2024-06-27T12:02:47.898128Z","shell.execute_reply":"2024-06-27T12:02:47.905339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 로그 변환된 Amount 피처와 Time 피처에 스케일링 적용\nscaler = StandardScaler()\nX_train_clean[['Log_Amount', 'Time']] = scaler.fit_transform(X_train_clean[['Log_Amount', 'Time']])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:03:18.536795Z","iopub.execute_input":"2024-06-27T12:03:18.537237Z","iopub.status.idle":"2024-06-27T12:03:18.550972Z","shell.execute_reply.started":"2024-06-27T12:03:18.537207Z","shell.execute_reply":"2024-06-27T12:03:18.549461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 로그 변환 전 Amount 피처 제거\nX_train_clean = X_train_clean.drop(columns=['Amount'])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:03:42.745656Z","iopub.execute_input":"2024-06-27T12:03:42.746135Z","iopub.status.idle":"2024-06-27T12:03:42.756005Z","shell.execute_reply.started":"2024-06-27T12:03:42.746096Z","shell.execute_reply":"2024-06-27T12:03:42.754950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 데이터 분할","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:06:05.437945Z","iopub.execute_input":"2024-06-27T12:06:05.438325Z","iopub.status.idle":"2024-06-27T12:06:05.544328Z","shell.execute_reply.started":"2024-06-27T12:06:05.438297Z","shell.execute_reply":"2024-06-27T12:06:05.543272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 데이터 분할\nX_train_final, X_val, y_train_final, y_val = train_test_split(X_train_clean, X_train_c.loc[X_train_clean.index], test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:07:14.074929Z","iopub.execute_input":"2024-06-27T12:07:14.075353Z","iopub.status.idle":"2024-06-27T12:07:14.109937Z","shell.execute_reply.started":"2024-06-27T12:07:14.075320Z","shell.execute_reply":"2024-06-27T12:07:14.108696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 결과 확인\nprint(f\"Training set shape: {X_train_final.shape}\")\nprint(f\"Validation set shape: {X_val.shape}\")\nprint(f\"Training labels shape: {y_train_final.shape}\")\nprint(f\"Validation labels shape: {y_val.shape}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:07:33.714348Z","iopub.execute_input":"2024-06-27T12:07:33.714743Z","iopub.status.idle":"2024-06-27T12:07:33.720892Z","shell.execute_reply.started":"2024-06-27T12:07:33.714713Z","shell.execute_reply":"2024-06-27T12:07:33.719749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Training","metadata":{}},{"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression\nfrom sklearn.ensemble import RandomForestClassifier\nimport xgboost as xgb\nfrom xgboost import XGBClassifier\nfrom sklearn.metrics import roc_auc_score, average_precision_score\nfrom sklearn.metrics import classification_report, confusion_matrix, accuracy_score, roc_auc_score, roc_curve","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:22:50.380998Z","iopub.execute_input":"2024-06-27T12:22:50.381422Z","iopub.status.idle":"2024-06-27T12:22:50.387829Z","shell.execute_reply.started":"2024-06-27T12:22:50.381391Z","shell.execute_reply":"2024-06-27T12:22:50.386658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LogisticRegression\nlogistic_model = LogisticRegression(max_iter=1000, random_state=42)\nlogistic_model.fit(X_train_final, y_train_final)\ny_pred_logistic_proba = logistic_model.predict_proba(X_val)[:, 1]\n\n# RandomForest\nrf_model = RandomForestClassifier(n_estimators=100, random_state=42)\nrf_model.fit(X_train_final, y_train_final)\ny_pred_rf_proba = rf_model.predict_proba(X_val)[:, 1]\n\n# XGBoost\nxgb_model = xgb.XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=42)\nxgb_model.fit(X_train_final, y_train_final)\ny_pred_xgb_proba = xgb_model.predict_proba(X_val)[:, 1]","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:34:24.810248Z","iopub.execute_input":"2024-06-27T12:34:24.810689Z","iopub.status.idle":"2024-06-27T12:34:39.249318Z","shell.execute_reply.started":"2024-06-27T12:34:24.810655Z","shell.execute_reply":"2024-06-27T12:34:39.246474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ROC-AUC\nroc_auc_logistic = roc_auc_score(y_val, y_pred_logistic_proba)\nroc_auc_rf = roc_auc_score(y_val, y_pred_rf_proba)\nroc_auc_xgb = roc_auc_score(y_val, y_pred_xgb_proba)\n\nprint(f\"Logistic Regression ROC-AUC: {roc_auc_logistic}\")\nprint(f\"Random Forest ROC-AUC: {roc_auc_rf}\")\nprint(f\"XGBoost ROC-AUC: {roc_auc_xgb}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:34:46.164216Z","iopub.execute_input":"2024-06-27T12:34:46.165023Z","iopub.status.idle":"2024-06-27T12:34:46.191612Z","shell.execute_reply.started":"2024-06-27T12:34:46.164987Z","shell.execute_reply":"2024-06-27T12:34:46.190346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Ensemble\ny_pred_ensemble_proba = (y_pred_logistic_proba + y_pred_rf_proba + y_pred_xgb_proba) / 3\nroc_auc_ensemble = roc_auc_score(y_val, y_pred_ensemble_proba)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:38:24.559171Z","iopub.execute_input":"2024-06-27T12:38:24.559616Z","iopub.status.idle":"2024-06-27T12:38:24.573524Z","shell.execute_reply.started":"2024-06-27T12:38:24.559582Z","shell.execute_reply":"2024-06-27T12:38:24.572210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ALL ROC-AUC Score\nprint(f\"Logistic Regression ROC-AUC: {roc_auc_logistic}\")\nprint(f\"Random Forest ROC-AUC: {roc_auc_rf}\")\nprint(f\"XGBoost ROC-AUC: {roc_auc_xgb}\")\nprint(f\"Ensemble ROC-AUC: {roc_auc_ensemble}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:39:22.005595Z","iopub.execute_input":"2024-06-27T12:39:22.006070Z","iopub.status.idle":"2024-06-27T12:39:22.012351Z","shell.execute_reply.started":"2024-06-27T12:39:22.006034Z","shell.execute_reply":"2024-06-27T12:39:22.011257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ROC Curve\nfpr_logistic, tpr_logistic, _ = roc_curve(y_val, y_pred_logistic_proba)\nfpr_rf, tpr_rf, _ = roc_curve(y_val, y_pred_rf_proba)\nfpr_xgb, tpr_xgb, _ = roc_curve(y_val, y_pred_xgb_proba)\nfpr_ensemble, tpr_ensemble, _ = roc_curve(y_val, y_pred_ensemble_proba)\n\nplt.figure(figsize=(10, 8))\nplt.plot(fpr_logistic, tpr_logistic, label=f'Logistic Regression (AUC = {roc_auc_logistic:.2f})')\nplt.plot(fpr_rf, tpr_rf, label=f'Random Forest (AUC = {roc_auc_rf:.2f})')\nplt.plot(fpr_xgb, tpr_xgb, label=f'XGBoost (AUC = {roc_auc_xgb:.2f})')\nplt.plot(fpr_ensemble, tpr_ensemble, label=f'Ensemble (AUC = {roc_auc_ensemble:.2f})')\nplt.plot([0, 1], [0, 1], 'k--', label='Random Chance')\n\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('ROC Curve Comparison')\nplt.legend(loc='best')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:38:39.864371Z","iopub.execute_input":"2024-06-27T12:38:39.864784Z","iopub.status.idle":"2024-06-27T12:38:40.262109Z","shell.execute_reply.started":"2024-06-27T12:38:39.864750Z","shell.execute_reply":"2024-06-27T12:38:40.261043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Hyper Parameter Tuning","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import GridSearchCV","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:41:18.230030Z","iopub.execute_input":"2024-06-27T12:41:18.230471Z","iopub.status.idle":"2024-06-27T12:41:18.235426Z","shell.execute_reply.started":"2024-06-27T12:41:18.230439Z","shell.execute_reply":"2024-06-27T12:41:18.234311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LogisticRegression HyperParamter Tuing\nparam_grid_logistic = {\n    'C': [0.01, 0.1, 1, 10, 100],\n    'solver': ['liblinear', 'saga']\n}\n\nlogistic_model = LogisticRegression(max_iter=1000, random_state=42)\ngrid_search_logistic = GridSearchCV(logistic_model, param_grid_logistic, cv=5, scoring='roc_auc')\ngrid_search_logistic.fit(X_train_final, y_train_final)\n\nprint(f\"Best parameters for Logistic Regression: {grid_search_logistic.best_params_}\")\nprint(f\"Best ROC-AUC for Logistic Regression: {grid_search_logistic.best_score_}\")\n\nbest_logistic_model = grid_search_logistic.best_estimator_","metadata":{"execution":{"iopub.status.busy":"2024-06-27T12:41:21.548985Z","iopub.execute_input":"2024-06-27T12:41:21.549912Z","iopub.status.idle":"2024-06-27T12:51:43.189492Z","shell.execute_reply.started":"2024-06-27T12:41:21.549861Z","shell.execute_reply":"2024-06-27T12:51:43.188187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# RandomForest HyperParameter Tuning\nparam_grid_rf = {\n    'n_estimators': [100, 200, 300],\n    'max_depth': [None, 10, 20, 30],\n    'min_samples_split': [2, 5, 10]\n}\n\nrf_model = RandomForestClassifier(random_state=42)\ngrid_search_rf = GridSearchCV(rf_model, param_grid_rf, cv=5, scoring='roc_auc')\ngrid_search_rf.fit(X_train_final, y_train_final)\n\nprint(f\"Best parameters for Random Forest: {grid_search_rf.best_params_}\")\nprint(f\"Best ROC-AUC for Random Forest: {grid_search_rf.best_score_}\")\n\nbest_rf_model = grid_search_rf.best_estimator_","metadata":{"execution":{"iopub.status.busy":"2024-06-27T13:41:28.348113Z","iopub.execute_input":"2024-06-27T13:41:28.349271Z","iopub.status.idle":"2024-06-27T14:38:03.852866Z","shell.execute_reply.started":"2024-06-27T13:41:28.349227Z","shell.execute_reply":"2024-06-27T14:38:03.851691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# XGBoost HyperParamter Tuning\nparam_grid_xgb = {\n    'n_estimators': [100, 200, 300],\n    'max_depth': [3, 6, 9],\n    'learning_rate': [0.01, 0.1, 0.2]\n}\n\nxgb_model = xgb.XGBClassifier(use_label_encoder=False, eval_metric='logloss', random_state=42)\ngrid_search_xgb = GridSearchCV(xgb_model, param_grid_xgb, cv=5, scoring='roc_auc')\ngrid_search_xgb.fit(X_train_final, y_train_final)\n\nprint(f\"Best parameters for XGBoost: {grid_search_xgb.best_params_}\")\nprint(f\"Best ROC-AUC for XGBoost: {grid_search_xgb.best_score_}\")\n\nbest_xgb_model = grid_search_xgb.best_estimator_","metadata":{"execution":{"iopub.status.busy":"2024-06-27T14:47:53.770311Z","iopub.execute_input":"2024-06-27T14:47:53.770752Z","iopub.status.idle":"2024-06-27T14:50:20.030849Z","shell.execute_reply.started":"2024-06-27T14:47:53.770713Z","shell.execute_reply":"2024-06-27T14:50:20.029675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 최적화 모델을 사용해 predict\ny_pred_logistic_proba_best = best_logistic_model.predict_proba(X_val)[:, 1]\ny_pred_rf_proba_best = best_rf_model.predict_proba(X_val)[:, 1]\ny_pred_xgb_proba_best = best_xgb_model.predict_proba(X_val)[:, 1]","metadata":{"execution":{"iopub.status.busy":"2024-06-27T14:51:22.138881Z","iopub.execute_input":"2024-06-27T14:51:22.139385Z","iopub.status.idle":"2024-06-27T14:51:22.328082Z","shell.execute_reply.started":"2024-06-27T14:51:22.139350Z","shell.execute_reply":"2024-06-27T14:51:22.327100Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Ensemble Predict\ny_pred_ensemble_proba_best = (y_pred_logistic_proba_best + y_pred_rf_proba_best + y_pred_xgb_proba_best) / 3\nroc_auc_ensemble_best = roc_auc_score(y_val, y_pred_ensemble_proba_best)","metadata":{"execution":{"iopub.status.busy":"2024-06-27T14:51:24.483056Z","iopub.execute_input":"2024-06-27T14:51:24.484158Z","iopub.status.idle":"2024-06-27T14:51:24.498569Z","shell.execute_reply.started":"2024-06-27T14:51:24.484114Z","shell.execute_reply":"2024-06-27T14:51:24.497281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 최적화 모델의 ROC-AUC Score\nprint(f\"Optimized Logistic Regression ROC-AUC: {roc_auc_score(y_val, y_pred_logistic_proba_best)}\")\nprint(f\"Optimized Random Forest ROC-AUC: {roc_auc_score(y_val, y_pred_rf_proba_best)}\")\nprint(f\"Optimized XGBoost ROC-AUC: {roc_auc_score(y_val, y_pred_xgb_proba_best)}\")\nprint(f\"Optimized Ensemble ROC-AUC: {roc_auc_ensemble_best}\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T14:51:26.728073Z","iopub.execute_input":"2024-06-27T14:51:26.728464Z","iopub.status.idle":"2024-06-27T14:51:26.754479Z","shell.execute_reply.started":"2024-06-27T14:51:26.728435Z","shell.execute_reply":"2024-06-27T14:51:26.753325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ROC Curve;Re\nfpr_ensemble_best, tpr_ensemble_best, _ = roc_curve(y_val, y_pred_ensemble_proba_best)\n\nplt.figure(figsize=(10, 8))\nplt.plot(fpr_ensemble_best, tpr_ensemble_best, label=f'Optimized Ensemble (AUC = {roc_auc_ensemble_best:.2f})')\nplt.plot([0, 1], [0, 1], 'k--', label='Random Chance')\n\nplt.xlabel('False Positive Rate')\nplt.ylabel('True Positive Rate')\nplt.title('ROC Curve for Optimized Ensemble')\nplt.legend(loc='best')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-27T14:51:29.479511Z","iopub.execute_input":"2024-06-27T14:51:29.479960Z","iopub.status.idle":"2024-06-27T14:51:29.834934Z","shell.execute_reply.started":"2024-06-27T14:51:29.479919Z","shell.execute_reply":"2024-06-27T14:51:29.833749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 최적 모델 선택 및 테스트 데이터 예측","metadata":{}},{"cell_type":"code","source":"# X_train = pd.read_csv('/kaggle/input/affel-ds2-credit-card/train.csv')\n# y_train = pd.read_csv('/kaggle/input/affel-ds2-credit-card/test.csv')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 최적화된 모델\nbest_model = best_xgb_model","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:23:50.662306Z","iopub.execute_input":"2024-06-27T15:23:50.662734Z","iopub.status.idle":"2024-06-27T15:23:50.668288Z","shell.execute_reply.started":"2024-06-27T15:23:50.662699Z","shell.execute_reply":"2024-06-27T15:23:50.666986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_test = pd.read_csv('/kaggle/input/affel-ds2-credit-card/test.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:22:15.245177Z","iopub.execute_input":"2024-06-27T15:22:15.245616Z","iopub.status.idle":"2024-06-27T15:22:16.428821Z","shell.execute_reply.started":"2024-06-27T15:22:15.245581Z","shell.execute_reply":"2024-06-27T15:22:16.427612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 테스트 데이터 전처리\nX_test_clean = X_test.drop(columns=['id'], errors='ignore')\nX_test_clean['Log_Amount'] = np.log1p(X_test_clean['Amount'])\nX_test_clean[['Log_Amount', 'Time']] = scaler.transform(X_test_clean[['Log_Amount', 'Time']])\nX_test_clean = X_test_clean.drop(columns=['Amount'])","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:22:31.081824Z","iopub.execute_input":"2024-06-27T15:22:31.082274Z","iopub.status.idle":"2024-06-27T15:22:31.116135Z","shell.execute_reply.started":"2024-06-27T15:22:31.082239Z","shell.execute_reply":"2024-06-27T15:22:31.114984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 최적 모델로 테스트 데이터 예측\ny_test_pred = best_model.predict_proba(X_test_clean)[:, 1]","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:24:03.243540Z","iopub.execute_input":"2024-06-27T15:24:03.243985Z","iopub.status.idle":"2024-06-27T15:24:03.321504Z","shell.execute_reply.started":"2024-06-27T15:24:03.243950Z","shell.execute_reply":"2024-06-27T15:24:03.320582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 예측 결과 저장\nsubmission = pd.DataFrame({'id': X_test['id'], 'Class': y_test_pred})\nsubmission.to_csv('240627_submission.csv', index=False)\n\nprint(\"예측 결과가 '240627_submission.csv' 파일에 저장되었습니다.\")","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:24:10.067575Z","iopub.execute_input":"2024-06-27T15:24:10.068003Z","iopub.status.idle":"2024-06-27T15:24:10.393495Z","shell.execute_reply.started":"2024-06-27T15:24:10.067973Z","shell.execute_reply":"2024-06-27T15:24:10.392283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 결과 확인\nsubmission = pd.read_csv('240627_submission.csv')\nprint(submission.head())","metadata":{"execution":{"iopub.status.busy":"2024-06-27T15:24:33.374118Z","iopub.execute_input":"2024-06-27T15:24:33.374511Z","iopub.status.idle":"2024-06-27T15:24:33.426796Z","shell.execute_reply.started":"2024-06-27T15:24:33.374480Z","shell.execute_reply":"2024-06-27T15:24:33.425474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}