{"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":80687,"databundleVersionId":8672016,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# 목차\n1. 들어가며\n2. 파일 불러오기 및 데이터 확인\n3. 초기 모델링 및 평가\n3. EDA 및 전처리\n4. 재모델링\n5. 평가\n\n제가 작성한 결과물은 학습용으로 https://lsjsj92.tistory.com/555 에 있는 내용 대부분 참고하였습니다. 양질의 자료를 공유해주신 선생님께 감사드립니다. <br>\n선생님 덕분에 학습에 많은 도움이 되었습니다.","metadata":{}},{"cell_type":"markdown","source":"## 1. 들어가며\n`[신용카드거래 사기 탐지]` <br>\n\n이 불균형한 데이터셋은 PCA 변환을 거친 수치형 변수들만 있으며 V1, V2, …, V28은 PCA로 얻은 주성분이며, <br>\nPCA 변환을 거치지 않은 유일한 특징은 'Time'과 'Amount'으로 'Time'은 각 거래와 데이터셋의 첫 거래 사이의 경과 시간(초)을 나타내며, 'Amount'는 거래 금액을 나타낸다. <br>\n\n`유의사항`으로는 클래스 불균형 비율을 고려하여, 정밀도-재현율 곡선 아래 영역(AUPRC)을 사용하여 정확도를 측정해야하며\n과제 제출 조건은 다음과 같다 <br>\n\n<u>거래금액을 확인하여 id랑 class 사기유무1, 0인 2개의 컬럼으로 제출할 것</u> <br>\n![image.png](attachment:6238b996-626c-4f09-9424-70aed0e7c85a.png) <br><br>","metadata":{},"attachments":{"6238b996-626c-4f09-9424-70aed0e7c85a.png":{"image/png":"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"}}},{"cell_type":"markdown","source":"## 2. 파일 불러오기 및 데이터 확인\n불균형 데이터에는 혼동행렬 정확도가 큰 의미가 없다하니 confusion_matrix는 사용하지 않겠다","metadata":{}},{"cell_type":"code","source":"import pandas as pd, numpy as np\nfrom sklearn.preprocessing import StandardScaler, RobustScaler, MinMaxScaler\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.linear_model import LogisticRegression\nimport seaborn as sns, matplotlib.pyplot as plt\nfrom sklearn.pipeline import Pipeline\nfrom imblearn.pipeline import Pipeline\nfrom imblearn.over_sampling import SMOTE, ADASYN\nfrom sklearn.metrics import roc_auc_score","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:09.588802Z","iopub.execute_input":"2024-05-29T00:18:09.589246Z","iopub.status.idle":"2024-05-29T00:18:09.596704Z","shell.execute_reply.started":"2024-05-29T00:18:09.589203Z","shell.execute_reply":"2024-05-29T00:18:09.595315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv('../input/big-data-analytics-certification-kr-2024-2/train.csv', encoding='utf-8-sig')\ntest = pd.read_csv('../input/big-data-analytics-certification-kr-2024-2/test.csv', encoding='utf-8-sig')\ntrain.shape, test.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:09.598433Z","iopub.execute_input":"2024-05-29T00:18:09.598892Z","iopub.status.idle":"2024-05-29T00:18:12.111981Z","shell.execute_reply.started":"2024-05-29T00:18:09.598862Z","shell.execute_reply":"2024-05-29T00:18:12.110870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.114100Z","iopub.execute_input":"2024-05-29T00:18:12.114501Z","iopub.status.idle":"2024-05-29T00:18:12.171616Z","shell.execute_reply.started":"2024-05-29T00:18:12.114470Z","shell.execute_reply":"2024-05-29T00:18:12.170379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.173280Z","iopub.execute_input":"2024-05-29T00:18:12.173692Z","iopub.status.idle":"2024-05-29T00:18:12.221660Z","shell.execute_reply.started":"2024-05-29T00:18:12.173656Z","shell.execute_reply":"2024-05-29T00:18:12.220625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.select_dtypes(include='O')\n# all numeric\n\ntest.select_dtypes(include='O')\n# all numeric\n\n\nset(train)- set(test)\n# {'Class'} ----> 중복되지 않는 피처\n\ntrain.iloc[:,-1].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.224132Z","iopub.execute_input":"2024-05-29T00:18:12.224465Z","iopub.status.idle":"2024-05-29T00:18:12.241471Z","shell.execute_reply.started":"2024-05-29T00:18:12.224437Z","shell.execute_reply":"2024-05-29T00:18:12.240400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"여기서 문제가 하나 있는데 사기인게 360, 아닌게 17만으로 너무 편향되어 있다 그렇다면 통계량을 확인해보자","metadata":{}},{"cell_type":"code","source":"train.describe()\n# 일단 잘 모르는 V1~V28를 제외하고, time과 amount의 표준편차가 크니 산포가 넓게 분포해있군\n# 우선 distribution change를 위해 time과 amount를 normalization 해주자","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.242916Z","iopub.execute_input":"2024-05-29T00:18:12.243244Z","iopub.status.idle":"2024-05-29T00:18:12.560014Z","shell.execute_reply.started":"2024-05-29T00:18:12.243218Z","shell.execute_reply":"2024-05-29T00:18:12.558949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. 초기 모델링 및 평가\n위에서 normalization을 위해 EDA로 넘어가는 과정은 잠깐 제쳐두고, 우선 아무 피처링도 하지 않은 상태에서 모델을 학습해서 평가해보자 <br>\n`사기확률  360(약1%), 사기 아닐확률 170523(약99%)`","metadata":{}},{"cell_type":"code","source":"X=train.drop(['id', 'Class'], axis=1)\ny=train['Class']","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.561344Z","iopub.execute_input":"2024-05-29T00:18:12.561731Z","iopub.status.idle":"2024-05-29T00:18:12.583410Z","shell.execute_reply.started":"2024-05-29T00:18:12.561683Z","shell.execute_reply":"2024-05-29T00:18:12.582339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.584807Z","iopub.execute_input":"2024-05-29T00:18:12.585185Z","iopub.status.idle":"2024-05-29T00:18:12.634160Z","shell.execute_reply.started":"2024-05-29T00:18:12.585155Z","shell.execute_reply":"2024-05-29T00:18:12.632922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.638615Z","iopub.execute_input":"2024-05-29T00:18:12.639692Z","iopub.status.idle":"2024-05-29T00:18:12.647456Z","shell.execute_reply.started":"2024-05-29T00:18:12.639656Z","shell.execute_reply":"2024-05-29T00:18:12.646209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"~~신용카드 사기거래에 적합한 oversampling인 SMOTE와 ADASYN을 활용해 pipeline 2개 구축해서 학습 후 평가해보자 (너무 오래 걸린다)~~ <br>\n미리 rf, lr로 평가를 해보자","metadata":{}},{"cell_type":"code","source":"x_tr, x_val, y_tr, y_val = train_test_split(X, y, random_state=10)\nx_tr.shape, x_val.shape, y_tr.shape, y_val.shape\n\nrf = RandomForestClassifier(random_state=2024)\nlr = LogisticRegression(random_state=2024)\n\nrf.fit(x_tr, y_tr)\nrf_pred = rf.predict_proba(x_val)[:, 1]\nroc_auc_rf = roc_auc_score(y_val, rf_pred)\n\n\n\n# # SMOTE\n# s_pipeline = Pipeline([\n#     ('smote', SMOTE(random_state=2024)),\n#     ('classifier', rf)\n# ])\n\n# # ADASYN\n# a_pipeline = Pipeline([\n#     ('adasyn', ADASYN(random_state=2024)),\n#     ('classifier', lr)\n# ])\n\n# # evaluation1\n# s_pipeline.fit(x_tr, y_tr)\n# y_pred_s = s_pipeline.predict(x_val)\n# y_pred_s\n# y_pred_proba_s = s_pipeline.predict_proba(x_val)[:, 1]\n# roc_auc_s = roc_auc_score(y_val, y_pred_proba_s)\n# print(f\"ROC AUC Score: {roc_auc_s}\")\n\n# # evaluation2\n# a_pipeline.fit(x_tr, y_tr)\n# y_pred_a = a_pipeline.predict(x_val)\n# y_pred_proba_a = a_pipeline.predict_proba(x_val)[:, 1] \n# roc_auc_a = roc_auc_score(y_val, y_pred_proba_a)","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:18:12.648987Z","iopub.execute_input":"2024-05-29T00:18:12.649322Z","iopub.status.idle":"2024-05-29T00:20:01.825411Z","shell.execute_reply.started":"2024-05-29T00:18:12.649294Z","shell.execute_reply":"2024-05-29T00:20:01.824278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"roc_auc_rf\n# 모델 피처링도 안해서 unbalanced class인데 0.95는 너무 말도 안되는 수치므로 전처리를 하자 아까 위에 멈췄던 train.describe()에서 이어서 하겠다","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:01.830815Z","iopub.execute_input":"2024-05-29T00:20:01.831265Z","iopub.status.idle":"2024-05-29T00:20:01.838416Z","shell.execute_reply.started":"2024-05-29T00:20:01.831232Z","shell.execute_reply":"2024-05-29T00:20:01.837344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. EDA 및 전처리\ntrain.describe()를 근거로 분포를 확인해보자","metadata":{}},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(18, 4))\namount = train['Amount'].values\ntime = train['Time'].abs().values\n\nsns.distplot(amount, ax=ax[0], color='r')\nax[0].set_title('Distribution of Amount(Transaction)')\nax[0].set_xlim([min(amount), max(amount)])\n\nsns.distplot(time, ax=ax[1], color='b')\nax[1].set_title(\"Distribution of Time(Transaction)\")\nax[1].set_xlim([min(time), max(time)])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:01.839631Z","iopub.execute_input":"2024-05-29T00:20:01.839964Z","iopub.status.idle":"2024-05-29T00:20:04.082035Z","shell.execute_reply.started":"2024-05-29T00:20:01.839914Z","shell.execute_reply":"2024-05-29T00:20:04.081010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"자 Amount와 Time의 분포를 보면, 특이한 점이 있는데<br>\n1번째 그림인 Amount는 대부분 0에 위치하는 경향이 있고 17500까지 조금씩 이어져있다 <br>\n2번째 그림인 Time은 Amount보다는 고르게 분포해있고 그림을 보면 0~12만 까지의 수치인데 이는 그림이 잘려 더 수치가 크다는 것을 알 수 있다 <br>\n\n여기서 문제는 두 데이터의 분포가 너무 큰데, 데이터 분포가 크면 머신러닝 모델이 제대로 동작하지 않을 수도 있다 <br>\n`왜? -->` 너무 큰 값에 쏠리는 현상이 생길 수도.. <br>\n\n그래서 data normalization을 할건데 여기서는 standardization과 log scale을 사용해보자","metadata":{}},{"cell_type":"markdown","source":"### Amount 컬럼 data normalization\namount컬럼에 log변환과 StandardScaler변환 어떤게 나은지 비교해보자<br><br>\n\n<u>참고</u> <br>\n.values(reshape(-1,1)) `-->` values로 numpy array로 반환 후 reshape(-1,1)를 통해 1col 2dim array로 변환","metadata":{}},{"cell_type":"code","source":"scaler = StandardScaler()\ntrain['ss_amount'] = scaler.fit_transform(train['Amount'].values.reshape(-1,1))\ntrain['logged_amount'] = np.log1p(train['Amount'].values.reshape(-1,1)) ","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:04.083671Z","iopub.execute_input":"2024-05-29T00:20:04.084125Z","iopub.status.idle":"2024-05-29T00:20:04.100484Z","shell.execute_reply.started":"2024-05-29T00:20:04.084075Z","shell.execute_reply":"2024-05-29T00:20:04.099246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 2, figsize=(18, 4))\nss_amount = train['ss_amount'].values\nlogged_amount = train['logged_amount'].values\n\nsns.distplot(ss_amount, ax=ax[0], color='r')\nax[0].set_xlim([min(ss_amount), max(ss_amount)])\nax[0].set_title(\"StandardScaler - Amount\")\n\nsns.distplot(logged_amount, ax=ax[1], color='b')\nax[1].set_xlim([min(logged_amount), max(logged_amount)])\nax[1].set_title(\"np.log1p - Amount\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:04.101760Z","iopub.execute_input":"2024-05-29T00:20:04.102105Z","iopub.status.idle":"2024-05-29T00:20:07.414863Z","shell.execute_reply.started":"2024-05-29T00:20:04.102076Z","shell.execute_reply":"2024-05-29T00:20:07.413776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"train['Amount']에 대해 왼쪽이 Standardization 변환, 우측이 log1p 변환인데 \n데이터 분포 수치가 0~17500로 있던게 많이 줄었는 것을 확인할 수 있다<br>\n\n이 중에 좌측인 StandardScaler 변환한 결과가 기존 Amount와 데이터 분포가 상당히 유사하기에 Amount에는 StandardScaler를 채택하자 <br>\n이어서 Time컬럼도 정규화하자","metadata":{}},{"cell_type":"markdown","source":"### time 컬럼 data normalization","metadata":{}},{"cell_type":"code","source":"rs = RobustScaler()\ntrain['rs_time'] = rs.fit_transform(train['Time'].values.reshape(-1,1))\ntrain['logged_time'] = np.log1p(train['Time'].values.reshape(-1,1))\ntrain['std_time'] = scaler.fit_transform(train['Time'].values.reshape(-1,1))","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:07.416548Z","iopub.execute_input":"2024-05-29T00:20:07.417412Z","iopub.status.idle":"2024-05-29T00:20:07.437059Z","shell.execute_reply.started":"2024-05-29T00:20:07.417373Z","shell.execute_reply":"2024-05-29T00:20:07.435629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1, 3, figsize=(18, 4))\nrs_time = train['rs_time'].values\nlogged_time = train['logged_time'].values\nstd_time = train['std_time'].values\n\nsns.distplot(rs_time, ax=ax[0], color='r')\nax[0].set_xlim([min(rs_time), max(rs_time)])\nax[0].set_title(\"RobustScaler - Time\")\n\nsns.distplot(logged_time, ax=ax[1], color='b')\nax[1].set_xlim([min(logged_time), max(logged_time)])\nax[1].set_title(\"np.log1p - Time\")\n\nsns.distplot(std_time, ax=ax[2], color='c')\nax[2].set_xlim([min(std_time), max(std_time)])\nax[2].set_title(\"StandardScaler - Time\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:07.438827Z","iopub.execute_input":"2024-05-29T00:20:07.439337Z","iopub.status.idle":"2024-05-29T00:20:10.663596Z","shell.execute_reply.started":"2024-05-29T00:20:07.439295Z","shell.execute_reply":"2024-05-29T00:20:10.662474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"자 train['Time']에 대해서는 기존 데이터 분포와 비슷한 것은 rs와 ss분포인데 그 중 rs가 데이터분포가 조금 더 적게 나왔기에 overfitting에 걸리지 않아 train['Time]에 대해서는 rs를 채택하자  ","metadata":{}},{"cell_type":"markdown","source":"### deleting useless columns that i just tested\nAmount와 Time데이터를 각각 normalizaiton에서 채택한 데이터로 변경하고 나머지와 기존에 있던 Time, Amount도 함께 삭제","metadata":{}},{"cell_type":"code","source":"scaler = StandardScaler()\ntrain['logged_amount'] = np.log1p(train['Amount'].values.reshape(-1,1)) \nrs = RobustScaler()\ntrain['logged_time'] = np.log1p(train['Time'].values.reshape(-1,1))\ntrain['std_time'] = scaler.fit_transform(train['Time'].values.reshape(-1,1))","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.665199Z","iopub.execute_input":"2024-05-29T00:20:10.666306Z","iopub.status.idle":"2024-05-29T00:20:10.685546Z","shell.execute_reply.started":"2024-05-29T00:20:10.666265Z","shell.execute_reply":"2024-05-29T00:20:10.684630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.drop(['logged_amount', 'logged_time', 'std_time', 'Time', 'Amount'], axis=1, inplace=True)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.686840Z","iopub.execute_input":"2024-05-29T00:20:10.687174Z","iopub.status.idle":"2024-05-29T00:20:10.723258Z","shell.execute_reply.started":"2024-05-29T00:20:10.687148Z","shell.execute_reply":"2024-05-29T00:20:10.722246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"자 이제 useless columns들을 drop했는데 보기 좋게 <br>\n마지막에 추가된 컬럼2개를 앞으로 가져오자 <br>\n`왜? -->` 나중에 class(target) 뽑을 때 편하니까","metadata":{}},{"cell_type":"code","source":"ss_amount = train['ss_amount']\nrs_time = train['rs_time']\ntrain.drop(['ss_amount', 'rs_time'], axis=1, inplace=True)\ntrain.insert(0, 'ss_amount', ss_amount)\ntrain.insert(1, 'rs_time', rs_time)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.724766Z","iopub.execute_input":"2024-05-29T00:20:10.725170Z","iopub.status.idle":"2024-05-29T00:20:10.764112Z","shell.execute_reply.started":"2024-05-29T00:20:10.725134Z","shell.execute_reply":"2024-05-29T00:20:10.763012Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. 모델링\n자 이제 train에 채택한 scaling을 test에도 적용해주자","metadata":{}},{"cell_type":"code","source":"test['ss_amount'] = scaler.fit_transform(test['Amount'].values.reshape(-1,1))\ntest['rs_time'] = rs.fit_transform(test['Time'].values.reshape(-1,1))\n\nss_amount_t = scaler.fit_transform(test['Amount'].values.reshape(-1,1))\nrs_time_t = rs.fit_transform(test['Amount'].values.reshape(-1,1))\ntest.drop(['Time', 'Amount'],axis=1, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.765596Z","iopub.execute_input":"2024-05-29T00:20:10.766036Z","iopub.status.idle":"2024-05-29T00:20:10.795155Z","shell.execute_reply.started":"2024-05-29T00:20:10.765998Z","shell.execute_reply":"2024-05-29T00:20:10.794176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = train.drop(['id', 'Class'], axis=1)  \ny = train.pop('Class')\ntest_id = test.pop('id')\ntest.drop(['ss_amount', 'rs_time'], axis=1, inplace=True)\ntest.insert(0, 'ss_amount', ss_amount)\ntest.insert(1, 'rs_time', rs_time)\n\nx_tr, x_val, y_tr, y_val = train_test_split(X, y, random_state=2024)\nx_tr.shape, x_val.shape, y_tr.shape, y_val.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.796894Z","iopub.execute_input":"2024-05-29T00:20:10.797329Z","iopub.status.idle":"2024-05-29T00:20:10.924024Z","shell.execute_reply.started":"2024-05-29T00:20:10.797290Z","shell.execute_reply":"2024-05-29T00:20:10.922389Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rf.fit(x_tr, y_tr)\nrf_pred_proba = rf.predict_proba(x_val)[:,1]\nrf_pred_proba","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.925012Z","iopub.status.idle":"2024-05-29T00:20:10.925397Z","shell.execute_reply.started":"2024-05-29T00:20:10.925215Z","shell.execute_reply":"2024-05-29T00:20:10.925230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"roc_auc_score(y_val, rf_pred_proba)","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.927455Z","iopub.status.idle":"2024-05-29T00:20:10.927852Z","shell.execute_reply.started":"2024-05-29T00:20:10.927656Z","shell.execute_reply":"2024-05-29T00:20:10.927672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"0.92로 아까 전처리 전의 0.95보단 낮아졌다. 여기서 outlier까지 구하면 더 정확도를 낮출 수 있을 것 같은데 시간관계상 일단 생략하겠다. ","metadata":{}},{"cell_type":"code","source":"train","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.929296Z","iopub.status.idle":"2024-05-29T00:20:10.929699Z","shell.execute_reply.started":"2024-05-29T00:20:10.929503Z","shell.execute_reply":"2024-05-29T00:20:10.929519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.931210Z","iopub.status.idle":"2024-05-29T00:20:10.931683Z","shell.execute_reply.started":"2024-05-29T00:20:10.931419Z","shell.execute_reply":"2024-05-29T00:20:10.931436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final_proba = rf.predict_proba(test)[:,1]\nfinal_proba","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:20:10.933022Z","iopub.status.idle":"2024-05-29T00:20:10.933409Z","shell.execute_reply.started":"2024-05-29T00:20:10.933217Z","shell.execute_reply":"2024-05-29T00:20:10.933239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit = {'id': test_id,\n         'Class': final_proba}\nsubmit = pd.DataFrame(submit)\nsubmit.to_csv('joonk2.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:21:09.086806Z","iopub.execute_input":"2024-05-29T00:21:09.087262Z","iopub.status.idle":"2024-05-29T00:21:09.320333Z","shell.execute_reply.started":"2024-05-29T00:21:09.087227Z","shell.execute_reply":"2024-05-29T00:21:09.319298Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit['Class'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-05-29T00:25:42.140417Z","iopub.execute_input":"2024-05-29T00:25:42.141536Z","iopub.status.idle":"2024-05-29T00:25:42.158135Z","shell.execute_reply.started":"2024-05-29T00:25:42.141488Z","shell.execute_reply":"2024-05-29T00:25:42.157004Z"},"trusted":true},"execution_count":null,"outputs":[]}]}