{"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":"# Overview\nmission\n\n코드 탭에서 \"new notebook\"으로 문제 풀기 (생성된 csv파일 다운로드)  \n예측한 csv파일 \"Submit Predictions\"하기  \n[분류] 신용카드 사기 거래를 탐지  \n\n이 데이터셋은 PCA 변환을 거친 수치형 변수들만 포함하고 있습니다. 안타깝게도 기밀 유지 문제로 인해 원본 특징과 데이터에 대한 자세한 배경 정보는 제공할 수 없습니다. V1, V2, …, V28은 PCA로 얻은 주성분이며, PCA 변환을 거치지 않은 유일한 특징은 'Time'과 'Amount'입니다. 'Time'은 각 거래와 데이터셋의 첫 거래 사이의 경과 시간(초)을 나타내며, 'Amount'는 거래 금액입니다. 'Amount' 특징은 예시 의존적 비용 민감 학습 등에 사용될 수 있습니다. 'Class'는 응답 변수로, 사기 거래인 경우 1, 그렇지 않은 경우 0의 값을 가집니다.\n \n\n예측할 값(y): Class (0:Not fraud, 1:fraud)  \n\n평가: roc-auc 평가지표  \n\n\n\n\n---\n제출 형식 (fraud의 확률값)  \n \nid,Class   \n0,0.3  \n1,0.48   \n2,0.3  \n3,0.83  \n---","metadata":{}},{"cell_type":"code","source":"#라이브러리 호출\n\n#EDA\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np\n\n#데이터 전처리\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.model_selection import train_test_split\nfrom imblearn.over_sampling import SMOTE\n\n#모델선택\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import classification_report, confusion_matrix, roc_auc_score","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:54:14.191851Z","iopub.execute_input":"2024-05-28T02:54:14.192228Z","iopub.status.idle":"2024-05-28T02:54:14.198916Z","shell.execute_reply.started":"2024-05-28T02:54:14.192200Z","shell.execute_reply":"2024-05-28T02:54:14.197571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 1. 탐색적 데이터 분석 (EDA)\n","metadata":{}},{"cell_type":"markdown","source":"## 데이터 로드 및 기본 정보 확인\n\n\t•\t데이터 로드\n\t•\t데이터의 기본 통계량 확인\n\t•\t결측치 확인","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv(\"/kaggle/input/big-data-analytics-certification-kr-2024-2/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/big-data-analytics-certification-kr-2024-2/test.csv\")\n\n# 데이터의 기본 정보 확인\nprint(train.info() , test.info())\nprint(train.describe() , test.describe())\nprint(train.isnull().sum() , test.isna().sum())","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:44:28.425921Z","iopub.execute_input":"2024-05-28T02:44:28.427182Z","iopub.status.idle":"2024-05-28T02:44:31.056437Z","shell.execute_reply.started":"2024-05-28T02:44:28.427140Z","shell.execute_reply":"2024-05-28T02:44:31.055335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 데이터 시각화\n\n\t•\t클래스 불균형 시각화\n\t•\t‘Time’과 ‘Amount’ 변수의 분포 시각화\n\t•\tPCA 변환된 변수들 간의 상관관계 확인","metadata":{}},{"cell_type":"code","source":"# 클래스 불균형 시각화\nsns.countplot(x='Class', data=train)\nplt.title('Class Distribution')\nplt.show()\n\n# 'Time'과 'Amount' 변수의 분포 시각화\nplt.figure(figsize=(12, 6))\nplt.subplot(1, 2, 1)\nsns.histplot(train['Time'], bins=50, kde=True)\nplt.title('Time Distribution')\n\nplt.subplot(1, 2, 2)\nsns.histplot(train['Amount'], bins=30, kde=True)\nplt.title('Amount Distribution')\n\nplt.show()\n\n#amount가 너무 비대칭이라 보기 힘드니 로그처리\n#log1p는 log(1 + x)를 계산하여 0 값을 처리\nplt.figure(figsize=(10, 6))\nsns.histplot(np.log1p(train['Amount']), bins=50, kde=True)\nplt.title('Histogram and KDE of Log-Transformed Amount')\nplt.xlabel('Log(Amount + 1)')\nplt.show()\n\n\n# PCA 변환된 변수들 간의 상관관계 확인\nplt.figure(figsize=(12, 10))\ncorrelation_matrix = train.iloc[:, :-1].corr()\nsns.heatmap(correlation_matrix, annot=False, cmap='coolwarm')\nplt.title('Correlation Matrix of PCA Components')\nplt.show()\n\n#class = 1인 데이터의 Amount 분포 시각화\n#이것도 불균형할수있으니 log처리\n\nplt.figure(figsize=(10, 6))\nsns.histplot(np.log1p(train.loc[train['Class'] == 1,'Amount']), bins=50, kde=True)\nplt.title('Histogram and KDE of Log-Transformed Amount (class = 1)')\nplt.xlabel('Log(Amount + 1)')\nplt.show()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:44:31.058754Z","iopub.execute_input":"2024-05-28T02:44:31.059177Z","iopub.status.idle":"2024-05-28T02:44:36.024019Z","shell.execute_reply.started":"2024-05-28T02:44:31.059139Z","shell.execute_reply":"2024-05-28T02:44:36.022932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 2. 데이터 전처리","metadata":{}},{"cell_type":"markdown","source":"## 데이터 정규화\n\n\t•\t‘Amount’ 변수 정규화 \n    •\t‘Time’ 변수 정규화","metadata":{}},{"cell_type":"code","source":"# 스케일링전 데이터 확인\nprint(train[['Time', 'Amount']].head())\nprint(test[['Time', 'Amount']].head())\n\n# Standard Scaler를 사용하여 'Time'과 'Amount' 변수를 스케일링\nscaler = StandardScaler()\ntrain[['Time', 'Amount']] = scaler.fit_transform(train[['Time', 'Amount']])\ntest[['Time', 'Amount']] = scaler.transform(test[['Time', 'Amount']])\n\n# 스케일링된 데이터 확인\nprint(train[['Time', 'Amount']].head())\nprint(test[['Time', 'Amount']].head())","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:44:36.027157Z","iopub.execute_input":"2024-05-28T02:44:36.027867Z","iopub.status.idle":"2024-05-28T02:44:36.060867Z","shell.execute_reply.started":"2024-05-28T02:44:36.027832Z","shell.execute_reply":"2024-05-28T02:44:36.059604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 훈련 및 테스트 데이터 분리\n\n\t•\tStratified Split (층화 샘플링)\n\n   \n양성 클래스(즉, 사기 거래) 비율이 매우 낮은 극도로 불균형한 데이터셋에서 데이터 분할은 특별한 주의가 필요하다.. 일반적인 train_test_split 방법을 사용할 때, 소수의 양성 클래스 샘플이 훈련 세트나 테스트 세트 중 한 곳에 치우치는 상황이 발생할 수 있는데 stratify=y 옵션을 사용해주면된다.\n\n\t•\tSMOTE (Synthetic Minority Over-sampling Technique)\nSMOTE(Synthetic Minority Over-sampling Technique)는 불균형한 데이터셋에서 소수 클래스(minority class)의 샘플을 생성하여 데이터셋을 균형 있게 만드는 오버샘플링 기법. \n데이터를 복제하는 방식이기 때문에 훈련데이터셋에만 적용하는게 중요하다!\n\n!!! 덜 복제하며 성능을 높이기위해 훈련,검정데이터를 분리하고 훈련데이터셋에만 적용해보도록 하자. !!! ","metadata":{}},{"cell_type":"code","source":"X_train = train.drop( ['id','Class'], axis=1)\ny_train = train['Class']\n\nX_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.3, random_state=42, stratify= y_train)\n\n# SMOTE를 사용하여 훈련 세트 오버샘플링\nsm = SMOTE(random_state=42)\nX_tr_res, y_tr_res = sm.fit_resample(X_tr, y_tr)\n\n# 클래스 비율 확인\nprint(\"Original class distribution:\")\nprint(y_train.value_counts(normalize=True))\nprint(\"Resampled train class distribution:\")\nprint(pd.Series(y_tr_res).value_counts(normalize=True))\nprint(\"val class distribution:\")\nprint(y_val.value_counts(normalize=True))","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:54:36.448097Z","iopub.execute_input":"2024-05-28T02:54:36.448483Z","iopub.status.idle":"2024-05-28T02:54:36.807711Z","shell.execute_reply.started":"2024-05-28T02:54:36.448454Z","shell.execute_reply":"2024-05-28T02:54:36.806427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 3. 모델 선택 및 학습\n","metadata":{}},{"cell_type":"markdown","source":"## 모델 선택\n\n\t•\t불균형 데이터셋에 적합한 모델 선택: RandomForest, Gradient Boosting, XGBoost 등","metadata":{}},{"cell_type":"code","source":"# RandomForestClassifier 학습\nmodel = RandomForestClassifier(random_state=42)\nmodel.fit(X_tr_res, y_tr_res)\n\n# 검정데이터로 예측\ny_pred = model.predict(X_val)\ny_pred_proba = model.predict_proba(X_val)[:, 1]\n\n# 평가\nprint(confusion_matrix(y_val, y_pred))\nprint(classification_report(y_val, y_pred))\nprint(f'ROC AUC: {roc_auc_score(y_val, y_pred_proba)}')","metadata":{"execution":{"iopub.status.busy":"2024-05-28T02:55:04.743781Z","iopub.execute_input":"2024-05-28T02:55:04.744214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}