{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":88400,"databundleVersionId":10121331,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# 필요한 패키지를 임포트 후 데이터 불러오기\n\nimport numpy as np\n\nimport pandas as pd\n\n\n\nfrom sklearn.ensemble import RandomForestClassifier, VotingClassifier\n\nfrom sklearn.model_selection import train_test_split, GridSearchCV\n\nfrom sklearn.linear_model import LogisticRegression\n\nfrom lightgbm import LGBMClassifier\n\nfrom xgboost import XGBClassifier\n\nimport seaborn as sns\n\nimport matplotlib.pyplot as plt\n\nfrom sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix, f1_score, roc_auc_score\n\nimport warnings\n\nfrom xgboost import XGBClassifier\n\nwarnings.filterwarnings('ignore')\n\n%matplotlib inline\n\n\n\ntrain = pd.read_csv(\"/kaggle/input/aiffel-ds-3-credit-card-fraud-detection/train.csv\") \n\ntest = pd.read_csv(\"/kaggle/input/aiffel-ds-3-credit-card-fraud-detection/test.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:51.531160Z","iopub.execute_input":"2024-11-13T00:48:51.531626Z","iopub.status.idle":"2024-11-13T00:48:56.924590Z","shell.execute_reply.started":"2024-11-13T00:48:51.531577Z","shell.execute_reply":"2024-11-13T00:48:56.923426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:56.927024Z","iopub.execute_input":"2024-11-13T00:48:56.927429Z","iopub.status.idle":"2024-11-13T00:48:56.964314Z","shell.execute_reply.started":"2024-11-13T00:48:56.927386Z","shell.execute_reply":"2024-11-13T00:48:56.962950Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Analysis","metadata":{}},{"cell_type":"code","source":"# 데이터에서 필요없는 id, Time 컬럼 삭제\n\n# 해당 컬럼은 임의의 값들이 들어가 있으므로 결과 예측과는 관계가 없음\n\ncard_df = train.drop(['id', 'Time'], axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:56.966094Z","iopub.execute_input":"2024-11-13T00:48:56.966614Z","iopub.status.idle":"2024-11-13T00:48:56.990206Z","shell.execute_reply.started":"2024-11-13T00:48:56.966558Z","shell.execute_reply":"2024-11-13T00:48:56.988940Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Class를 제외하고는 모두 float형 자료\n\n# 결측치는 없다\n\ncard_df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:56.991782Z","iopub.execute_input":"2024-11-13T00:48:56.992166Z","iopub.status.idle":"2024-11-13T00:48:57.021577Z","shell.execute_reply.started":"2024-11-13T00:48:56.992128Z","shell.execute_reply":"2024-11-13T00:48:57.020355Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"card_df.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:57.024786Z","iopub.execute_input":"2024-11-13T00:48:57.025195Z","iopub.status.idle":"2024-11-13T00:48:57.347436Z","shell.execute_reply.started":"2024-11-13T00:48:57.025155Z","shell.execute_reply":"2024-11-13T00:48:57.346068Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# V1~V28의 데이터는 차원축소가 진행된 데이터로 무슨 특성을 가지고 있는지 확인이 불가함\n\n# Amount는 카드 사용액수, Class는 결과 예측값임\n\ncard_df['Class'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:57.348939Z","iopub.execute_input":"2024-11-13T00:48:57.349316Z","iopub.status.idle":"2024-11-13T00:48:57.360515Z","shell.execute_reply.started":"2024-11-13T00:48:57.349276Z","shell.execute_reply":"2024-11-13T00:48:57.359314Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 매우 불균형한 데이터임을 확인할 수 있다\n\n# 데이터를 train, test셋으로 분리할 때 그 결괏값이 동일한 비율을 유지하는지 확인이 필요하다\n\nsns.countplot(x='Class', data=card_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:57.362198Z","iopub.execute_input":"2024-11-13T00:48:57.362579Z","iopub.status.idle":"2024-11-13T00:48:57.649190Z","shell.execute_reply.started":"2024-11-13T00:48:57.362539Z","shell.execute_reply":"2024-11-13T00:48:57.647806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 피처별 상관관계 분석\n\n# Class와 상관관계가 높은 값들 위주로 이상치 제거, 나머지 모든 값의 이상치를 제거하기에는 시간이 너무 오래 소요됨\n\n# 음의 상관관계가 높게 나타나는 V10, V12, V14의 이상치 제거\n\nplt.figure(figsize=(9,9))\n\ncorr = card_df.corr()\n\nsns.heatmap(corr, cmap='RdBu')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:57.650989Z","iopub.execute_input":"2024-11-13T00:48:57.651402Z","iopub.status.idle":"2024-11-13T00:48:58.937743Z","shell.execute_reply.started":"2024-11-13T00:48:57.651360Z","shell.execute_reply":"2024-11-13T00:48:58.936386Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Amount의 분포 확인\n\n# 2500 이하 값에 대부분의 값들이 존재\n\nsns.histplot(card_df['Amount'], bins=100, kde=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:48:58.939629Z","iopub.execute_input":"2024-11-13T00:48:58.940153Z","iopub.status.idle":"2024-11-13T00:49:00.386898Z","shell.execute_reply.started":"2024-11-13T00:48:58.940097Z","shell.execute_reply":"2024-11-13T00:49:00.385692Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_features = card_df.iloc[:, :-1]\n\ny_labels = card_df.iloc[:, -1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.388574Z","iopub.execute_input":"2024-11-13T00:49:00.389013Z","iopub.status.idle":"2024-11-13T00:49:00.409401Z","shell.execute_reply.started":"2024-11-13T00:49:00.388969Z","shell.execute_reply":"2024-11-13T00:49:00.407892Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Data Cleaning","metadata":{}},{"cell_type":"code","source":"# 편한 결괏값 확인과 학습, 예측, 평가를 위한 함수 선언\n\n# eval 함수는 정확도, 정밀도, 재현율, f1스코어, roc_auc 점수를 확인할 수 있다\n\ndef eval(y_test, pred=None, pred_proba=None):\n\n    confusion = confusion_matrix(y_test, pred)\n\n    accuracy = accuracy_score(y_test, pred)\n\n    precision = precision_score(y_test, pred)\n\n    recall = recall_score(y_test, pred)\n\n    f1 = f1_score(y_test, pred)\n\n\n\n    roc_auc = roc_auc_score(y_test, pred_proba)\n\n    print(confusion)\n\n    print('정확도: {:.4f}, 정밀도: {:.4f}, 재현율: {:.4f}, F1: {:.4f}, AUC: {:.4f}'.format(accuracy, precision, recall, f1, roc_auc))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.411174Z","iopub.execute_input":"2024-11-13T00:49:00.411666Z","iopub.status.idle":"2024-11-13T00:49:00.420222Z","shell.execute_reply.started":"2024-11-13T00:49:00.411611Z","shell.execute_reply":"2024-11-13T00:49:00.418922Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# eval_after_train 함수는 모델과 데이터셋을 받아 eval 함수를 통해 모델을 학습시키고, 예측하고, 결괏값을 받아볼 수 있는 함수\n\ndef eval_after_train(model, train_X, test_X, train_y, test_y):\n\n    model.fit(train_X, train_y)\n\n    pred = model.predict(test_X)\n\n    pred_proba = model.predict_proba(test_X)[:,1]\n\n    eval(test_y, pred, pred_proba)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.422465Z","iopub.execute_input":"2024-11-13T00:49:00.422868Z","iopub.status.idle":"2024-11-13T00:49:00.433728Z","shell.execute_reply.started":"2024-11-13T00:49:00.422812Z","shell.execute_reply":"2024-11-13T00:49:00.432591Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# preprocessed 함수는 데이터 프레임을 받고 Amount값에 로그함수를 적용하여 정규화한다\n\n# 데이터 분포도가 심하게 왜곡되어 있으므로 로그함수를 적용한다\n\ndef preprocessed(df):\n\n    df_copy = df.copy()\n\n    # numpy log1p를 통해 로그 변환\n\n    amount = np.log1p(df_copy['Amount'])\n\n    df_copy.insert(0, 'Amount_Scaled', amount)\n\n    df_copy.drop('Amount', axis=1, inplace=True)\n\n    return df_copy","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.435443Z","iopub.execute_input":"2024-11-13T00:49:00.435963Z","iopub.status.idle":"2024-11-13T00:49:00.445792Z","shell.execute_reply.started":"2024-11-13T00:49:00.435905Z","shell.execute_reply":"2024-11-13T00:49:00.444209Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"card_df_pp = preprocessed(card_df)\n\ncard_df_pp","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.452812Z","iopub.execute_input":"2024-11-13T00:49:00.453329Z","iopub.status.idle":"2024-11-13T00:49:00.596596Z","shell.execute_reply.started":"2024-11-13T00:49:00.453284Z","shell.execute_reply":"2024-11-13T00:49:00.595179Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 적당한 분포를 가지는 것을 확인할 수 있다\n\nsns.histplot(card_df_pp['Amount_Scaled'], bins=100, kde=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:00.598506Z","iopub.execute_input":"2024-11-13T00:49:00.599081Z","iopub.status.idle":"2024-11-13T00:49:02.015770Z","shell.execute_reply.started":"2024-11-13T00:49:00.599022Z","shell.execute_reply":"2024-11-13T00:49:02.014448Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 이상치는 iqr을 이용해서 삭제한다\n\ndef outlier(df=None, column=None, weight=1.5):\n\n    fraud = df[df['Class']==1][column]\n\n    quantile_25 = np.percentile(fraud.values, 25)\n\n    quantile_75 = np.percentile(fraud.values, 75)\n\n\n\n    iqr = quantile_75 - quantile_25\n\n    iqr_weight = iqr * weight\n\n    lowest_val = quantile_25 - iqr_weight\n\n    highest_val = quantile_75 + iqr_weight\n\n    \n\n    outlier_index = fraud[(fraud < lowest_val) | (fraud > highest_val)].index\n\n    return outlier_index","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.017593Z","iopub.execute_input":"2024-11-13T00:49:02.018038Z","iopub.status.idle":"2024-11-13T00:49:02.026422Z","shell.execute_reply.started":"2024-11-13T00:49:02.017994Z","shell.execute_reply":"2024-11-13T00:49:02.025214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"outlier(card_df, 'V14')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.028295Z","iopub.execute_input":"2024-11-13T00:49:02.029108Z","iopub.status.idle":"2024-11-13T00:49:02.051011Z","shell.execute_reply.started":"2024-11-13T00:49:02.029052Z","shell.execute_reply":"2024-11-13T00:49:02.049460Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 컬럼별 이상치 삭제\n\ncolumns = ['V10', 'V12', 'V14']\n\n\n\nfor column in columns:\n\n    outlier_index = outlier(card_df, column, weight=1.5)\n\n    card_df_pp.drop(outlier_index, axis=0, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.053039Z","iopub.execute_input":"2024-11-13T00:49:02.053476Z","iopub.status.idle":"2024-11-13T00:49:02.146580Z","shell.execute_reply.started":"2024-11-13T00:49:02.053434Z","shell.execute_reply":"2024-11-13T00:49:02.145151Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Modeling","metadata":{}},{"cell_type":"code","source":"# 전처리 적용 전 데이터\n\nX_features = card_df.iloc[:, :-1]\n\ny_labels = card_df.iloc[:, -1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.148656Z","iopub.execute_input":"2024-11-13T00:49:02.149535Z","iopub.status.idle":"2024-11-13T00:49:02.173126Z","shell.execute_reply.started":"2024-11-13T00:49:02.149459Z","shell.execute_reply":"2024-11-13T00:49:02.171719Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 전처리 후 데이터\n\nX_features_pp = card_df_pp.iloc[:,:-1]\n\ny_labels_pp = card_df_pp.iloc[:, -1]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.175094Z","iopub.execute_input":"2024-11-13T00:49:02.175597Z","iopub.status.idle":"2024-11-13T00:49:02.198302Z","shell.execute_reply.started":"2024-11-13T00:49:02.175540Z","shell.execute_reply":"2024-11-13T00:49:02.196567Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train과 test셋으로 분할\n\nX_train, X_test, y_train, y_test = train_test_split(X_features, y_labels, test_size=0.2, random_state=0, stratify=y_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.200186Z","iopub.execute_input":"2024-11-13T00:49:02.200977Z","iopub.status.idle":"2024-11-13T00:49:02.320395Z","shell.execute_reply.started":"2024-11-13T00:49:02.200916Z","shell.execute_reply":"2024-11-13T00:49:02.319131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train_pp, X_test_pp, y_train_pp, y_test_pp = train_test_split(X_features_pp, y_labels_pp, test_size=0.2, random_state=0, stratify=y_labels_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.322154Z","iopub.execute_input":"2024-11-13T00:49:02.322689Z","iopub.status.idle":"2024-11-13T00:49:02.451122Z","shell.execute_reply.started":"2024-11-13T00:49:02.322629Z","shell.execute_reply":"2024-11-13T00:49:02.449830Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1인 값이 비슷한 비율로 들어간 것을 확인할 수 있다\n\nprint(y_train.value_counts()[1]/y_train.count())\n\nprint(y_test.value_counts()[1]/y_test.count())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.453007Z","iopub.execute_input":"2024-11-13T00:49:02.453461Z","iopub.status.idle":"2024-11-13T00:49:02.465990Z","shell.execute_reply.started":"2024-11-13T00:49:02.453407Z","shell.execute_reply":"2024-11-13T00:49:02.464260Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(y_train_pp.value_counts()[1]/y_train_pp.count())\n\nprint(y_test_pp.value_counts()[1]/y_test_pp.count())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.468230Z","iopub.execute_input":"2024-11-13T00:49:02.468862Z","iopub.status.idle":"2024-11-13T00:49:02.480857Z","shell.execute_reply.started":"2024-11-13T00:49:02.468768Z","shell.execute_reply":"2024-11-13T00:49:02.479443Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Class값이 불균형하므로 smote 오버 샘플링 적용\n\nfrom imblearn.over_sampling import SMOTE\n\n\n\nsmote = SMOTE(random_state=0)\n\nX_train_over, y_train_over = smote.fit_resample(X_train, y_train)\n\nX_train_pp_over, y_train_pp_over = smote.fit_resample(X_train_pp, y_train_pp)\n\nprint(X_train.shape)\n\nprint(X_train_over.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:02.482924Z","iopub.execute_input":"2024-11-13T00:49:02.484182Z","iopub.status.idle":"2024-11-13T00:49:03.271367Z","shell.execute_reply.started":"2024-11-13T00:49:02.484122Z","shell.execute_reply":"2024-11-13T00:49:03.269949Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Logistic Regression","metadata":{}},{"cell_type":"code","source":"# 가장 일반적인 Logistic Regression 분류 모델\n\n# 정밀도가 상당히 낮게 나온다\n\nmodel = LogisticRegression(max_iter = 1000)\n\neval_after_train(model, X_train, X_test, y_train, y_test)\n\n\n\nmodel = LogisticRegression(max_iter = 1000)\n\neval_after_train(model, X_train_over, X_test, y_train_over, y_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:03.272878Z","iopub.execute_input":"2024-11-13T00:49:03.273431Z","iopub.status.idle":"2024-11-13T00:49:52.268242Z","shell.execute_reply.started":"2024-11-13T00:49:03.273389Z","shell.execute_reply":"2024-11-13T00:49:52.267165Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = LogisticRegression(max_iter = 1000)\n\neval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n\n\nmodel = LogisticRegression(max_iter = 1000)\n\neval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:52.269645Z","iopub.execute_input":"2024-11-13T00:49:52.270794Z","iopub.status.idle":"2024-11-13T00:49:57.125956Z","shell.execute_reply.started":"2024-11-13T00:49:52.270749Z","shell.execute_reply":"2024-11-13T00:49:57.124638Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### RandomForestClassifier","metadata":{}},{"cell_type":"code","source":"# Random Forest 모델\n\n# 다양한 결정 트리를 결합해 과적합을 줄이고 다양한 데이터 유형에 적응할 수 있다\n\n# 데이터가 균형적이지 않으므로 class_weight 파라미터값을 balanced로 설정했다\n\nmodel = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n\neval_after_train(model, X_train, X_test, y_train, y_test)\n\n\n\nmodel = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n\neval_after_train(model, X_train_over, X_test, y_train_over, y_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:49:57.127514Z","iopub.execute_input":"2024-11-13T00:49:57.131114Z","iopub.status.idle":"2024-11-13T00:55:28.683488Z","shell.execute_reply.started":"2024-11-13T00:49:57.131063Z","shell.execute_reply":"2024-11-13T00:55:28.682193Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 전처리된 데이터가 좀 더 높은 성능을 보여주는 것을 알 수 있다\n\nmodel = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n\neval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n\n\nmodel = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n\neval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T00:55:28.684971Z","iopub.execute_input":"2024-11-13T00:55:28.685337Z","iopub.status.idle":"2024-11-13T01:00:46.019465Z","shell.execute_reply.started":"2024-11-13T00:55:28.685300Z","shell.execute_reply":"2024-11-13T01:00:46.018235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### LightGBM","metadata":{}},{"cell_type":"code","source":"# light gbm은 학습속도가 빠르고 메모리를 적게 사용하는 특징이 있다\n\n# 불균형 데이터에 좋은 성능을 발휘한다\n\n\n\n# 정확도: 0.9995, 정밀도: 0.8750, 재현율: 0.8750, F1: 0.8750, AUC: 0.9806\n\n# 정확도: 0.9996, 정밀도: 0.9524, 재현율: 0.8333, F1: 0.8889, AUC: 0.9763\n\n\n\nmodel = LGBMClassifier(n_estimators=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)\n\neval_after_train(model, X_train, X_test, y_train, y_test)\n\n\n\nmodel = LGBMClassifier(n_estimators=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)\n\neval_after_train(model, X_train_over, X_test, y_train_over, y_test)","metadata":{"scrolled":true,"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:00:46.021244Z","iopub.execute_input":"2024-11-13T01:00:46.021720Z","iopub.status.idle":"2024-11-13T01:03:16.598104Z","shell.execute_reply.started":"2024-11-13T01:00:46.021668Z","shell.execute_reply":"2024-11-13T01:03:16.596891Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 전처리된 데이터가 전체 성능이 좋긴 하나, 재현율과 F1 스코어에서는 못미치는 성능을 보여준다\n\n# 정확도: 0.9996, 정밀도: 0.9500, 재현율: 0.8261, F1: 0.8837, AUC: 0.9790\n\n# 정확도: 0.9995, 정밀도: 0.8841, 재현율: 0.8841, F1: 0.8841, AUC: 0.9838\n\n\n\nmodel = LGBMClassifier(n_estimators=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)\n\neval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n\n\nmodel = LGBMClassifier(n_estimators=1000, num_leaves=64, n_jobs=-1, boost_from_average=False)\n\neval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)","metadata":{"scrolled":true,"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:03:16.599717Z","iopub.execute_input":"2024-11-13T01:03:16.600225Z","iopub.status.idle":"2024-11-13T01:05:53.564179Z","shell.execute_reply.started":"2024-11-13T01:03:16.600170Z","shell.execute_reply":"2024-11-13T01:05:53.562822Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### XGBoost","metadata":{}},{"cell_type":"code","source":"# 강력한 정규화 기능과 병렬 처리 기능을 통해 과적합을 방지하고 성능을 높이는 모델이다\n\n# 여기서도 전처리만 되어 있는 데이터가 성능이 좋음을 알 수 있다\n\n\n\nmodel = XGBClassifier(use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train, X_test, y_train, y_test)\n\n\n\nmodel = XGBClassifier(use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_over, X_test, y_train_over, y_test)\n\n\n\nmodel = XGBClassifier(use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n\n\nmodel = XGBClassifier(use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:05:53.566005Z","iopub.execute_input":"2024-11-13T01:05:53.566503Z","iopub.status.idle":"2024-11-13T01:06:26.762791Z","shell.execute_reply.started":"2024-11-13T01:05:53.566448Z","shell.execute_reply":"2024-11-13T01:06:26.761310Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# V14, V4, Amount_Scaled, V26 순으로 결과에 중요한 영향을 미친다는 사실을 알 수 있음\n\nfrom xgboost import plot_importance\n\nplot_importance(model)\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:06:26.766681Z","iopub.execute_input":"2024-11-13T01:06:26.767139Z","iopub.status.idle":"2024-11-13T01:06:27.280892Z","shell.execute_reply.started":"2024-11-13T01:06:26.767087Z","shell.execute_reply":"2024-11-13T01:06:27.279619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# GridSearchCV를 통해 간단한 하이퍼파라미터 최적화 진행\n\nparam_grid = {\n\n    'max_depth': [3, 5, 7],\n\n    'learning_rate': [0.01, 0.1, 0.2],\n\n    'n_estimators': [100, 200, 300]\n\n}\n\n\n\ngrid_search = GridSearchCV(estimator=model, param_grid=param_grid, scoring='roc_auc', cv=3, verbose=True)\n\ngrid_search.fit(X_train, y_train)\n\n\n\nprint(grid_search.best_params_)\n\nprint(grid_search.best_score_)\n\n\n\ngrid_search = GridSearchCV(estimator=model, param_grid=param_grid, scoring='roc_auc', cv=3, verbose=True)\n\ngrid_search.fit(X_train_pp, y_train_pp)\n\n\n\nprint(grid_search.best_params_)\n\nprint(grid_search.best_score_)\n\n\n\ngrid_search = GridSearchCV(estimator=model, param_grid=param_grid, scoring='roc_auc', cv=3, verbose=True)\n\ngrid_search.fit(X_train_over, y_train_over)\n\n\n\nprint(grid_search.best_params_)\n\nprint(grid_search.best_score_)\n\n\n\ngrid_search = GridSearchCV(estimator=model, param_grid=param_grid, scoring='roc_auc', cv=3, verbose=True)\n\ngrid_search.fit(X_train_pp_over, y_train_pp_over)\n\n\n\nprint(grid_search.best_params_)\n\nprint(grid_search.best_score_)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:06:27.282623Z","iopub.execute_input":"2024-11-13T01:06:27.283136Z","iopub.status.idle":"2024-11-13T01:55:24.848051Z","shell.execute_reply.started":"2024-11-13T01:06:27.283082Z","shell.execute_reply":"2024-11-13T01:55:24.846560Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = XGBClassifier(learning_rate=0.1, max_depth=3, n_estimators=100, use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train, X_test, y_train, y_test)\n\n\n\nmodel = XGBClassifier(learning_rate=0.1, max_depth=7, n_estimators=300, use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n\n\nmodel = XGBClassifier(learning_rate=0.2, max_depth=5, n_estimators=300, use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_over, X_test, y_train_over, y_test)\n\n\n\nmodel = XGBClassifier(learning_rate=0.2, max_depth=5, n_estimators=300, use_label_encoder=False, eval_metric='logloss')\n\neval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:55:24.849575Z","iopub.execute_input":"2024-11-13T01:55:24.850031Z","iopub.status.idle":"2024-11-13T01:56:43.500791Z","shell.execute_reply.started":"2024-11-13T01:55:24.849988Z","shell.execute_reply":"2024-11-13T01:56:43.499291Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# xgboost를 hyperopt를 이용해 하이퍼파라미터 튜닝\n\nfrom hyperopt import hp, fmin, tpe, Trials, STATUS_OK\n\nX_train, X_valid, y_train, y_valid = train_test_split(X_features_pp, y_labels_pp, test_size=0.2, random_state=0)\n\n\n\ndef objective(params):\n\n    model = XGBClassifier(\n\n        n_estimators=int(params['n_estimators']),\n\n        learning_rate=params['learning_rate'],\n\n        max_depth=int(params['max_depth']),\n\n        subsample=params['subsample'],\n\n        colsample_bytree=params['colsample_bytree'],\n\n        scale_pos_weight=params['scale_pos_weight'],\n\n        use_label_encoder=False,\n\n        early_stopping_rounds=10,\n\n        eval_metric=\"auc\"\n\n    )\n\n    \n\n    # 모델 학습\n\n    model.fit(X_train, y_train, eval_set=[(X_valid, y_valid)], verbose=False)\n\n    \n\n    # 예측 및 성능 평가\n\n    y_pred = model.predict_proba(X_valid)[:, 1]\n\n    auc_score = roc_auc_score(y_valid, y_pred)\n\n    \n\n    # Hyperopt는 최소화하려고 하므로 AUC를 음수로 반환\n\n    return {'loss': -auc_score, 'status': STATUS_OK}\n\n\n\n# Hyperopt의 하이퍼파라미터 공간 정의\n\nspace = {\n\n    'n_estimators': hp.quniform('n_estimators', 100, 1000, 100),\n\n    'learning_rate': hp.uniform('learning_rate', 0.01, 0.3),\n\n    'max_depth': hp.quniform('max_depth', 3, 12, 1),\n\n    'subsample': hp.uniform('subsample', 0.5, 1.0),\n\n    'colsample_bytree': hp.uniform('colsample_bytree', 0.5, 1.0),\n\n    'scale_pos_weight': hp.uniform('scale_pos_weight', 1, 10)\n\n}\n\n\n\n# Hyperopt의 Trials 객체 생성\n\ntrials = Trials()\n\n\n\n# Hyperopt로 최적화 수행\n\nbest = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=50, trials=trials)\n\n\n\n# 최적의 하이퍼파라미터 출력\n\nprint(\"Best hyperparameters:\", best)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:56:43.502582Z","iopub.execute_input":"2024-11-13T01:56:43.503522Z","iopub.status.idle":"2024-11-13T01:58:42.744728Z","shell.execute_reply.started":"2024-11-13T01:56:43.503473Z","shell.execute_reply":"2024-11-13T01:58:42.743358Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 최적 하이퍼파라미터 값을 모델에 학습\n\nbest_model = XGBClassifier(\n\n    n_estimators=100,\n\n    learning_rate=best['learning_rate'],\n\n    max_depth=int(best['max_depth']),\n\n    subsample=best['subsample'],\n\n    colsample_bytree=best['colsample_bytree'],\n\n    scale_pos_weight=best['scale_pos_weight'],  # 불균형 처리\n\n    use_label_encoder=False,\n\n    eval_metric=\"auc\"\n\n)\n\n\n\neval_after_train(best_model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T01:58:42.746161Z","iopub.execute_input":"2024-11-13T01:58:42.746897Z","iopub.status.idle":"2024-11-13T01:58:48.422583Z","shell.execute_reply.started":"2024-11-13T01:58:42.746825Z","shell.execute_reply":"2024-11-13T01:58:48.421354Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Voting Classifier","metadata":{}},{"cell_type":"code","source":"# Voting Classifier는 estimator를 추가하여 soft voting 방식으로 진행하는 모델이다\n# 전처리가 되고 smote가 되지 않은 데이터에서 가장 좋은 성능을 보여준다\n\n# 정확도: 0.9995, 정밀도: 0.8986, 재현율: 0.8611, F1: 0.8794, AUC: 0.9772\n# 정확도: 0.9979, 정밀도: 0.4961, 재현율: 0.8889, F1: 0.6368, AUC: 0.9771\n# 정확도: 0.9996, 정밀도: 0.9254, 재현율: 0.8986, F1: 0.9118, AUC: 0.9766\n# 정확도: 0.9946, 정밀도: 0.2645, 재현율: 0.9275, F1: 0.4116, AUC: 0.9757\n\n# rf_model = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n# lgb_model = LGBMClassifier(n_estimators=1000, learning_rate=0.01, max_depth=5, scale_pos_weight=99, random_state=42)\n# lr_model = LogisticRegression(max_iter=1000, class_weight='balanced', random_state=42)\n\n# model = VotingClassifier(estimators=[\n#     ('rf', rf_model),\n#     ('lgb', lgb_model),\n#     ('lr', lr_model)\n# ], voting='soft')\n\n# model_vc = model\n# eval_after_train(model, X_train, X_test, y_train, y_test)\n\n# model_vc = model\n# eval_after_train(model, X_train_over, X_test, y_train_over, y_test)\n\n# model_vc = model\n# eval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n# model_vc = model\n# eval_after_train(model, X_train_pp_over, X_test_pp, y_train_pp_over, y_test_pp)\n\n# 로컬에서 정상동작된 모델이 kaggle 노트북에서는 비정상 동작하여 주석 처리","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:15:57.702339Z","iopub.execute_input":"2024-11-13T02:15:57.702769Z","iopub.status.idle":"2024-11-13T02:15:57.710208Z","shell.execute_reply.started":"2024-11-13T02:15:57.702725Z","shell.execute_reply":"2024-11-13T02:15:57.708887Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Voting Classifier의 성능을 좀 더 향상시켜 보자\n\n# 성능이 좋은 세 개의 estimator가 모였다고 항상 좋은 결과를 내지는 않겠지만, 시도해볼 만한 가치가 있다고 판단했다\n\n\n\n# # Logistic Regression 하이퍼파라미터 튜닝\n\n# lr_param_grid = {\n\n#     'C': [0.01, 0.1, 1, 10, 100],  # 정규화 강도\n\n#     'solver': ['liblinear', 'lbfgs'],  # 최적화 알고리즘\n\n#     'penalty': ['l2'],  # 정규화 방식\n\n# }\n\n\n\n# lr_model = LogisticRegression(random_state=42)\n\n\n\n# # GridSearchCV를 사용하여 최적의 하이퍼파라미터를 찾기\n\n# lr_grid_search = GridSearchCV(estimator=lr_model, param_grid=lr_param_grid, \n\n#                               scoring='accuracy', cv=5)\n\n\n\n# # 학습\n\n# lr_grid_search.fit(X_train_pp, y_train_pp)\n\n\n\n# # 최적의 파라미터 출력\n\n# print(lr_grid_search.best_params_)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:17.707431Z","iopub.execute_input":"2024-11-13T02:16:17.707966Z","iopub.status.idle":"2024-11-13T02:16:17.714765Z","shell.execute_reply.started":"2024-11-13T02:16:17.707885Z","shell.execute_reply":"2024-11-13T02:16:17.713333Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 최적 모델\n\n# lr_best_model = lr_grid_search.best_estimator_\n\n\n\n# # 성능 평가\n\n# eval_after_train(lr_best_model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:18.409743Z","iopub.execute_input":"2024-11-13T02:16:18.410214Z","iopub.status.idle":"2024-11-13T02:16:18.416053Z","shell.execute_reply.started":"2024-11-13T02:16:18.410172Z","shell.execute_reply":"2024-11-13T02:16:18.414657Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 시간이 너무 오래 걸려 전체를 실행할 수 없었음\n\n# # Random Forest 하이퍼파라미터 튜닝\n\n# rf_param_grid = {\n\n#     'n_estimators': [100, 200],  # 트리 수\n\n#     'max_depth': [None, 10, 20, 30],  # 트리의 최대 깊이\n\n#     'min_samples_split': [2, 5, 10],  # 분할을 위한 최소 샘플 수\n\n# }\n\n\n\n# rf_model = RandomForestClassifier(random_state=42)\n\n\n\n# # GridSearchCV를 사용하여 최적의 하이퍼파라미터를 찾기\n\n# rf_grid_search = GridSearchCV(estimator=rf_model, param_grid=rf_param_grid, \n\n#                               scoring='accuracy')\n\n\n\n# # 학습\n\n# rf_grid_search.fit(X_train, y_train)\n\n\n\n# # 최적의 파라미터 출력\n\n# print(rf_grid_search.best_params_)\n\n\n\n# # 최적 모델로 예측\n\n# rf_best_model = rf_grid_search.best_estimator_\n\n\n\n# # 성능 평가\n\n# eval_after_train(rf_best_model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:19.108942Z","iopub.execute_input":"2024-11-13T02:16:19.109387Z","iopub.status.idle":"2024-11-13T02:16:19.119518Z","shell.execute_reply.started":"2024-11-13T02:16:19.109347Z","shell.execute_reply":"2024-11-13T02:16:19.118076Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 가장 성능이 좋은 LGBM 모델을 Voting Classifier에 학습\n\n# [[34100     5]\n#  [   14    55]]\n# 정확도: 0.9994, 정밀도: 0.9167, 재현율: 0.7971, F1: 0.8527, AUC: 0.9764\n\n# rf_model = RandomForestClassifier(n_estimators=100, random_state=0, class_weight='balanced')\n\n\n\n# model = VotingClassifier(estimators=[\n\n#     ('rf', rf_model),\n\n#     ('lgb', best_model),\n\n#     ('lr', lr_best_model)\n\n# ], voting='soft')\n\n\n\n# eval_after_train(model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)\n\n# 실질적인 예측 결과물이 오히려 악화되는 것을 확인했다","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:19.710894Z","iopub.execute_input":"2024-11-13T02:16:19.711373Z","iopub.status.idle":"2024-11-13T02:16:19.718273Z","shell.execute_reply.started":"2024-11-13T02:16:19.711330Z","shell.execute_reply":"2024-11-13T02:16:19.716494Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"불균형 데이터셋에서 가장 성능이 좋은 Light GBM에 hyperopt를 적용해 하이퍼파라미터 튜닝","metadata":{}},{"cell_type":"code","source":"# Light GBM 모델 hyperopt 적용\n\nfrom hyperopt import hp, fmin, tpe, Trials, STATUS_OK\n\nX_train, X_valid, y_train, y_valid = train_test_split(X_features_pp, y_labels_pp, test_size=0.2, random_state=0)\n\n\n\ndef objective(params):\n\n    # LightGBM 모델 생성\n\n    model = LGBMClassifier(\n\n        learning_rate=params['learning_rate'],\n\n        num_leaves=int(params['num_leaves']),\n\n        max_depth=int(params['max_depth']),\n\n        min_data_in_leaf=int(params['min_data_in_leaf']),\n\n        feature_fraction=params['feature_fraction'],\n\n        bagging_fraction=params['bagging_fraction'],\n\n        lambda_l1=params['lambda_l1'],\n\n        lambda_l2=params['lambda_l2'],\n\n        n_estimators=100,\n\n        random_state=42,\n\n        verbose=-1\n\n    )\n\n    \n\n    # 모델 학습\n\n    model.fit(X_train, y_train, eval_set=[(X_valid, y_valid)])\n\n    \n\n    # 예측 및 성능 평가\n\n    y_pred = model.predict_proba(X_valid)[:, 1]\n\n    auc_score = roc_auc_score(y_valid, y_pred)\n\n    \n\n    # Hyperopt는 최소화하려고 하므로 AUC를 음수로 반환\n\n    return {'loss': -auc_score, 'status': STATUS_OK}\n\n\n\n# Hyperopt의 하이퍼파라미터 공간 정의\n\nspace = {\n\n    'learning_rate': hp.uniform('learning_rate', 0.01, 0.3),\n\n    'num_leaves': hp.quniform('num_leaves', 20, 200, 1),\n\n    'max_depth': hp.quniform('max_depth', 3, 12, 1),\n\n    'min_data_in_leaf': hp.quniform('min_data_in_leaf', 10, 100, 1),\n\n    'feature_fraction': hp.uniform('feature_fraction', 0.5, 1.0),\n\n    'bagging_fraction': hp.uniform('bagging_fraction', 0.5, 1.0),\n\n    'lambda_l1': hp.uniform('lambda_l1', 0, 10),\n\n    'lambda_l2': hp.uniform('lambda_l2', 0, 10)\n\n}\n\n\n\n# Hyperopt의 Trials 객체 생성\n\ntrials = Trials()\n\n\n\n# Hyperopt로 최적화 수행\n\nbest = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=50, trials=trials)\n\n\n\n# 최적의 하이퍼파라미터 출력\n\nprint(\"Best hyperparameters:\", best)\n\n\n\n# Hyperopt에서 최적화된 하이퍼파라미터로 최종 모델 학습\n\nbest_model = LGBMClassifier(\n\n    learning_rate=best['learning_rate'],\n\n    num_leaves=int(best['num_leaves']),\n\n    max_depth=int(best['max_depth']),\n\n    min_data_in_leaf=int(best['min_data_in_leaf']),\n\n    feature_fraction=best['feature_fraction'],\n\n    bagging_fraction=best['bagging_fraction'],\n\n    lambda_l1=best['lambda_l1'],\n\n    lambda_l2=best['lambda_l2'],\n\n    n_estimators=100,\n\n    random_state=42\n\n)\n\n\n\neval_after_train(best_model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:12:13.236300Z","iopub.execute_input":"2024-11-13T02:12:13.237079Z","iopub.status.idle":"2024-11-13T02:15:54.388078Z","shell.execute_reply.started":"2024-11-13T02:12:13.237009Z","shell.execute_reply":"2024-11-13T02:15:54.386264Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 가장 성능이 좋은 모델을 학습\n\nbest_model = LGBMClassifier(\n\n    learning_rate=best['learning_rate'],\n\n    num_leaves=int(best['num_leaves']),\n\n    max_depth=int(best['max_depth']),\n\n    min_data_in_leaf=int(best['min_data_in_leaf']),\n\n    feature_fraction=best['feature_fraction'],\n\n    bagging_fraction=best['bagging_fraction'],\n\n    lambda_l1=best['lambda_l1'],\n\n    lambda_l2=best['lambda_l2'],\n\n    n_estimators=100,\n\n    random_state=42,\n\n    verbose=-1\n\n)\n\n\n\neval_after_train(best_model, X_train_pp, X_test_pp, y_train_pp, y_test_pp)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:15:54.390549Z","iopub.execute_input":"2024-11-13T02:15:54.392076Z","iopub.status.idle":"2024-11-13T02:15:57.700903Z","shell.execute_reply.started":"2024-11-13T02:15:54.392022Z","shell.execute_reply":"2024-11-13T02:15:57.699570Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"# 제출용 데이터 출력\n\ntest_copy = preprocessed(test)\n\ntest_copy.drop(['Time', 'id'], axis=1, inplace=True)\n\ny_pred = best_model.predict(test_copy)\n\nsubmission = pd.DataFrame({'id': test['id'], 'Class': y_pred})\n\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:33.519361Z","iopub.execute_input":"2024-11-13T02:16:33.520017Z","iopub.status.idle":"2024-11-13T02:16:34.137280Z","shell.execute_reply.started":"2024-11-13T02:16:33.519950Z","shell.execute_reply":"2024-11-13T02:16:34.135941Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-13T02:16:34.422642Z","iopub.execute_input":"2024-11-13T02:16:34.424087Z","iopub.status.idle":"2024-11-13T02:16:34.437510Z","shell.execute_reply.started":"2024-11-13T02:16:34.424033Z","shell.execute_reply":"2024-11-13T02:16:34.436105Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 회고\n\n\n\n* 사실 이번 퀘스트를 진행하면서 더 높은 점수를 받고자 하는 목표도 있었지만, 데이터의 정제 여부가 결괏값에 어떤 영향을 미치는지 확인해보고자 하는 욕구가 더 컸던 것 같다.\n\n\n\n* 다양한 분류 모델들에 데이터 정제를 적용해보고, smote와 같은 기법들을 적용해보면서 어떤 모델이 어떻게 영향을 받는지가 좀 더 와닿은 것 같다.\n\n\n\n* 그리고 모델을 만들고 성능 점수가 높게 나오는 것이 중요한 게 아니라는 사실을 깨달았다.\n\n\n\n* 여러 번 리더보드에 결괏값을 제출하면서 받은 점수에 따르면, RandomForest의 경우 결과에서는 가장 높은 점수가 나왔지만 점수는 가장 밑을 기었다.\n\n\n\n* 오히려 logistic regression 모델이 높은 성능을 보여주는 것을 보면서 하이퍼파라미터나 모델 선택보다 데이터의 정제 여부가 훨씬 큰 영향을 미친다는 것을 알 수 있었다.\n\n\n\n* 최소한의 데이터 정제만 해놓고 다양한 모델을 돌려보느라 추가적인 작업을 진행하지는 못했지만 한도가 풀리고 나면 다시 한 번 들여다보는 과정을 가져보고 싶다.\n\n\n\n* 작업이 끝나고 나서 Credit Card Fraud Detection 원 과제의 노트북들을 좀 살펴봤는데, 딥러닝과 인공신경망을 활용한 모델이 엄청나게 높은 성적을 내고 있는 걸 발견했다.\n\n\n\n* 모델 선택의 중요성을 깨달았고, 어쩌면 하나의 문제가 다양한 모델을 적용해보고 결괏값을 도출해보는 것보다는 정해진 하나의 모델을 가지고 하이퍼파라미터를 변경하면서 최적의 결과물을 찾는 것이 더 나은 방향일지도 모르겠다는 생각이 들었다.","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}