{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":63054,"databundleVersionId":6872631,"sourceType":"competition"}],"dockerImageVersionId":30579,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Importing necessary libraries\nFirst of all we will import the necessary libraries required for our classification task. Numpy and pandas for data processing, and seaborn and matplotlib for data visualisation","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:07.311642Z","iopub.execute_input":"2023-11-21T19:30:07.312099Z","iopub.status.idle":"2023-11-21T19:30:08.833366Z","shell.execute_reply.started":"2023-11-21T19:30:07.312067Z","shell.execute_reply":"2023-11-21T19:30:08.832460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Importing\nLet's first import and view our dataset","metadata":{}},{"cell_type":"code","source":"# Import and view the training data\ndata=pd.read_csv(\"/kaggle/input/anyas-gojo-revival-bondman/trainData.csv\")\ndata","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:08.835438Z","iopub.execute_input":"2023-11-21T19:30:08.835911Z","iopub.status.idle":"2023-11-21T19:30:14.032373Z","shell.execute_reply.started":"2023-11-21T19:30:08.835875Z","shell.execute_reply":"2023-11-21T19:30:14.031393Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exploratory Data Analysis","metadata":{}},{"cell_type":"code","source":"# Checking the shape of data\ndata.shape","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:14.033701Z","iopub.execute_input":"2023-11-21T19:30:14.034098Z","iopub.status.idle":"2023-11-21T19:30:14.040967Z","shell.execute_reply.started":"2023-11-21T19:30:14.034064Z","shell.execute_reply":"2023-11-21T19:30:14.039488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Summarizing the data\ndata.info()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:14.042099Z","iopub.execute_input":"2023-11-21T19:30:14.042395Z","iopub.status.idle":"2023-11-21T19:30:14.630310Z","shell.execute_reply.started":"2023-11-21T19:30:14.042371Z","shell.execute_reply":"2023-11-21T19:30:14.629372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As we can see, the dataset doesn't have any missing values","metadata":{}},{"cell_type":"code","source":"# Selecting numerical features\nnumerical_data = data.select_dtypes(include='number')\n\n# Append the features of numerical_data to list\nnumerical_features=numerical_data.columns.tolist()\n\nprint(f'There are {len(numerical_features)} numerical features:', '\\n')\nnumerical_features","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:14.634043Z","iopub.execute_input":"2023-11-21T19:30:14.634529Z","iopub.status.idle":"2023-11-21T19:30:14.652958Z","shell.execute_reply.started":"2023-11-21T19:30:14.634489Z","shell.execute_reply":"2023-11-21T19:30:14.651952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Selecting categorical features\ncategorical_data=data.select_dtypes(include= 'object')\n\n# Append the features of categorical_data to list\ncategorical_features=categorical_data.columns.tolist()\n\nprint(f'There are {len(categorical_features)} categorical features:', '\\n')\ncategorical_features","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:14.657686Z","iopub.execute_input":"2023-11-21T19:30:14.658051Z","iopub.status.idle":"2023-11-21T19:30:14.729277Z","shell.execute_reply.started":"2023-11-21T19:30:14.658018Z","shell.execute_reply":"2023-11-21T19:30:14.728304Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"categorical_data.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:14.730691Z","iopub.execute_input":"2023-11-21T19:30:14.731052Z","iopub.status.idle":"2023-11-21T19:30:16.876096Z","shell.execute_reply.started":"2023-11-21T19:30:14.731020Z","shell.execute_reply":"2023-11-21T19:30:16.875209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"numerical_data.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:16.877456Z","iopub.execute_input":"2023-11-21T19:30:16.877760Z","iopub.status.idle":"2023-11-21T19:30:17.074601Z","shell.execute_reply.started":"2023-11-21T19:30:16.877735Z","shell.execute_reply":"2023-11-21T19:30:17.073698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Checking skewness in data\nnumerical_data.skew()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:17.075899Z","iopub.execute_input":"2023-11-21T19:30:17.076178Z","iopub.status.idle":"2023-11-21T19:30:17.119402Z","shell.execute_reply.started":"2023-11-21T19:30:17.076153Z","shell.execute_reply":"2023-11-21T19:30:17.118512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Amount,city population and is_fraud data have very high positive skew","metadata":{}},{"cell_type":"markdown","source":"## DATA VISUALISATION\n","metadata":{}},{"cell_type":"code","source":"numerical_data.hist(figsize=(15,15),bins=10)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:17.120574Z","iopub.execute_input":"2023-11-21T19:30:17.120880Z","iopub.status.idle":"2023-11-21T19:30:19.421101Z","shell.execute_reply.started":"2023-11-21T19:30:17.120855Z","shell.execute_reply":"2023-11-21T19:30:19.420223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Except amt,city_pop,is_fraud, rest distributions are more or less gaussian.\n\nLegitimate transaction frequency is way greater than fraud transactions. This might make our model highly biased and not very efficient ","metadata":{}},{"cell_type":"code","source":"# Finding correlation data\ncorrelation=numerical_data.corr()\ncorrelation","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:19.422219Z","iopub.execute_input":"2023-11-21T19:30:19.422496Z","iopub.status.idle":"2023-11-21T19:30:19.618221Z","shell.execute_reply.started":"2023-11-21T19:30:19.422471Z","shell.execute_reply":"2023-11-21T19:30:19.617325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualising the correlation matrix\nsns.heatmap(correlation,cmap=\"YlGnBu\",annot=True)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:19.619513Z","iopub.execute_input":"2023-11-21T19:30:19.620118Z","iopub.status.idle":"2023-11-21T19:30:20.285788Z","shell.execute_reply.started":"2023-11-21T19:30:19.620080Z","shell.execute_reply":"2023-11-21T19:30:20.285010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Amt and age have higher correlation as compared to the rest of the features amongst numerical data","metadata":{"execution":{"iopub.status.busy":"2023-11-13T20:44:11.369148Z","iopub.execute_input":"2023-11-13T20:44:11.369584Z","iopub.status.idle":"2023-11-13T20:44:11.376470Z","shell.execute_reply.started":"2023-11-13T20:44:11.369550Z","shell.execute_reply":"2023-11-13T20:44:11.375036Z"}}},{"cell_type":"markdown","source":"## Data Preprocessing\nAs we can see,we have a pretty large dataset with around 5 lakh entries. For data processing,we only need numerical values. So we will first drop those text-based features which are not very relevant for the given task.\n\nFrom a general understanding, transaction date and time,location,name of person are not very important details for fraud detection.Hence we will drop them","metadata":{}},{"cell_type":"code","source":"# Drop irrelevant features \ndata=data.drop(['id','trans_date_trans_time','cc_num','merchant','first','last','street','job','trans_num','unix_time','city','zip'],axis=1)\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.286889Z","iopub.execute_input":"2023-11-21T19:30:20.287167Z","iopub.status.idle":"2023-11-21T19:30:20.325882Z","shell.execute_reply.started":"2023-11-21T19:30:20.287141Z","shell.execute_reply":"2023-11-21T19:30:20.324958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Feature Engineering\nNow,we will add a feature 'Age' in the dataset since age is a very important factor in determining the probability of fraud. Older people,not being much aware about technology, are more likely to fall for fraudulent transactions.","metadata":{}},{"cell_type":"code","source":"from datetime import datetime\n\ndata['dob'] = pd.to_datetime(data['dob'])\n\n# Calculate current year\ncurrent_year = datetime.now().year\n\n# Calculate age and create a new 'Age' column in the DataFrame\ndata['Age'] = current_year - data['dob'].dt.year\n\n# Drop dob column\ndata=data.drop('dob',axis=1)\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.330004Z","iopub.execute_input":"2023-11-21T19:30:20.330278Z","iopub.status.idle":"2023-11-21T19:30:20.545569Z","shell.execute_reply.started":"2023-11-21T19:30:20.330254Z","shell.execute_reply":"2023-11-21T19:30:20.544720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check for imbalance in target \ndata['is_fraud'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.546710Z","iopub.execute_input":"2023-11-21T19:30:20.546994Z","iopub.status.idle":"2023-11-21T19:30:20.560623Z","shell.execute_reply.started":"2023-11-21T19:30:20.546953Z","shell.execute_reply":"2023-11-21T19:30:20.559693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"As we can see, the difference between number of fraud and legitimate data is disproportionately high. So we will first separate the data into 2 categories and take equal amounts of data of each category for training","metadata":{}},{"cell_type":"code","source":"# Separate the dataset into legitimate and fraud transactions' data\nlegit = data[data.is_fraud==0]\nfraud = data[data.is_fraud==1]\n\n# View details about the legitimate dataset \nlegit.amt.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.561755Z","iopub.execute_input":"2023-11-21T19:30:20.562309Z","iopub.status.idle":"2023-11-21T19:30:20.641469Z","shell.execute_reply.started":"2023-11-21T19:30:20.562276Z","shell.execute_reply":"2023-11-21T19:30:20.640507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# View details about fraudulent dataset\nfraud.amt.describe()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.642589Z","iopub.execute_input":"2023-11-21T19:30:20.642883Z","iopub.status.idle":"2023-11-21T19:30:20.653063Z","shell.execute_reply.started":"2023-11-21T19:30:20.642858Z","shell.execute_reply":"2023-11-21T19:30:20.652137Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Undersampling\nThis is done so that we have equal number of fraud and legitimate data,to prevent any bias towards a particular category","metadata":{}},{"cell_type":"code","source":"# Undersampling\nlegit_sample=legit.sample(n=7506)\nlegit_sample","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.654146Z","iopub.execute_input":"2023-11-21T19:30:20.654441Z","iopub.status.idle":"2023-11-21T19:30:20.691121Z","shell.execute_reply.started":"2023-11-21T19:30:20.654414Z","shell.execute_reply":"2023-11-21T19:30:20.690032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Concatinate legitimate and fraud datasets\ntotal_sample=pd.concat([legit_sample,fraud],axis=0)\ntotal_sample.shape","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.692146Z","iopub.execute_input":"2023-11-21T19:30:20.692402Z","iopub.status.idle":"2023-11-21T19:30:20.700405Z","shell.execute_reply.started":"2023-11-21T19:30:20.692379Z","shell.execute_reply":"2023-11-21T19:30:20.699509Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Some textual details like state,category and gender can provide us importat details about a transaction being fraudulent. So instead of dropping them, we can one-hot encode them to convert them into numerical form.","metadata":{}},{"cell_type":"code","source":"# Do one hot encoding for textual features\none_hot_encoded_data = pd.get_dummies(total_sample, columns = ['state','category', 'gender'],dtype=int) \none_hot_encoded_data.head()\none_hot_encoded_data.keys()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.701406Z","iopub.execute_input":"2023-11-21T19:30:20.701704Z","iopub.status.idle":"2023-11-21T19:30:20.730806Z","shell.execute_reply.started":"2023-11-21T19:30:20.701675Z","shell.execute_reply":"2023-11-21T19:30:20.729898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check value counts for rach kind of data\none_hot_encoded_data['is_fraud'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.731709Z","iopub.execute_input":"2023-11-21T19:30:20.731946Z","iopub.status.idle":"2023-11-21T19:30:20.738831Z","shell.execute_reply.started":"2023-11-21T19:30:20.731924Z","shell.execute_reply":"2023-11-21T19:30:20.737975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Building and Training\nNow we can train our model. We used logistic regression,Random Forest Classifier,KNN Classifier for training the model but XGBClassifier gave the best score among all","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nimport xgboost as xgb\nfrom sklearn.metrics import roc_auc_score\n\n# Splitting training and target data\ny=one_hot_encoded_data['is_fraud']\nlegit_sample_x=one_hot_encoded_data.drop('is_fraud',axis=1)\n\n# Splitting data into test and train set\nX_train,X_test,y_train,y_test=train_test_split(legit_sample_x,y,test_size=0.2,random_state=1)\n\n# Trainning our model\nmodel = xgb.XGBClassifier()\nmodel.fit(X_train,y_train)\n\n# Predicting labels and calculating roc_auc_score\ny_pred = model.predict(X_test)\nroc_auc_score(y_pred,y_test)\n\n","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:20.739616Z","iopub.execute_input":"2023-11-21T19:30:20.739871Z","iopub.status.idle":"2023-11-21T19:30:21.731290Z","shell.execute_reply.started":"2023-11-21T19:30:20.739845Z","shell.execute_reply":"2023-11-21T19:30:21.730508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Evaluation\nLet's import test data and view it first","metadata":{}},{"cell_type":"code","source":"# Importing test data\ntest_df=pd.read_csv(\"/kaggle/input/anyas-gojo-revival-bondman/testData.csv\")\ntest_df\n","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:21.732481Z","iopub.execute_input":"2023-11-21T19:30:21.732790Z","iopub.status.idle":"2023-11-21T19:30:26.462606Z","shell.execute_reply.started":"2023-11-21T19:30:21.732765Z","shell.execute_reply":"2023-11-21T19:30:26.461716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's do the same preprocessing on test data as we did with training data above","metadata":{}},{"cell_type":"code","source":"test_df=test_df.drop(['id','trans_date_trans_time','cc_num','merchant','first','last','street','job','trans_num','unix_time','city','zip'],axis=1)\ntest_df","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:26.463928Z","iopub.execute_input":"2023-11-21T19:30:26.464564Z","iopub.status.idle":"2023-11-21T19:30:26.504865Z","shell.execute_reply.started":"2023-11-21T19:30:26.464529Z","shell.execute_reply":"2023-11-21T19:30:26.503942Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Convert dob to datetime format\ntest_df['dob'] = pd.to_datetime(test_df['dob'])\n\n# Calculate current year\ncurrent_year = datetime.now().year\n\n# Calculate age and create a new 'Age' column in the DataFrame\ntest_df['Age'] = current_year - test_df['dob'].dt.year\n\ntest_df=test_df.drop('dob',axis=1)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:26.506059Z","iopub.execute_input":"2023-11-21T19:30:26.506807Z","iopub.status.idle":"2023-11-21T19:30:26.711951Z","shell.execute_reply.started":"2023-11-21T19:30:26.506771Z","shell.execute_reply":"2023-11-21T19:30:26.710247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check for missing values\ntest_df.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:26.713302Z","iopub.execute_input":"2023-11-21T19:30:26.713596Z","iopub.status.idle":"2023-11-21T19:30:26.870444Z","shell.execute_reply.started":"2023-11-21T19:30:26.713571Z","shell.execute_reply":"2023-11-21T19:30:26.869722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# One-hot encode the test data\none_hot_encoded_test_data = pd.get_dummies(test_df, columns = ['state','category', 'gender'],dtype=int)\none_hot_encoded_test_data.insert(loc = 15,column = 'state_DE',value = 0)\none_hot_encoded_test_data.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:26.871435Z","iopub.execute_input":"2023-11-21T19:30:26.871726Z","iopub.status.idle":"2023-11-21T19:30:27.353640Z","shell.execute_reply.started":"2023-11-21T19:30:26.871701Z","shell.execute_reply":"2023-11-21T19:30:27.352810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predicting target labels of test data\nNow let's use our model to make predictions for the given test dataset","metadata":{}},{"cell_type":"code","source":"# Making predictions on the test data\npredictions_test = model.predict(one_hot_encoded_test_data)\npredictions_test","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:30:27.354781Z","iopub.execute_input":"2023-11-21T19:30:27.355066Z","iopub.status.idle":"2023-11-21T19:30:28.164596Z","shell.execute_reply.started":"2023-11-21T19:30:27.355045Z","shell.execute_reply":"2023-11-21T19:30:28.163786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Creating a DataFrame with ID and is_fraud columns\nsubmission3 = pd.DataFrame({'id': range(1, 555720), 'is_fraud': predictions_test})\n\n# Saving the DataFrame to a CSV file\nsubmission3.to_csv('submission.csv', index=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:34:20.998955Z","iopub.execute_input":"2023-11-21T19:34:20.999622Z","iopub.status.idle":"2023-11-21T19:34:22.047222Z","shell.execute_reply.started":"2023-11-21T19:34:20.999588Z","shell.execute_reply":"2023-11-21T19:34:22.046319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission3.head()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:34:31.015598Z","iopub.execute_input":"2023-11-21T19:34:31.016465Z","iopub.status.idle":"2023-11-21T19:34:31.024746Z","shell.execute_reply.started":"2023-11-21T19:34:31.016431Z","shell.execute_reply":"2023-11-21T19:34:31.023790Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}