{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# American Express - Default Prediction\n# Team Tuffline\nTeam Members\n\nAA1932 - Chamod Eshwarage\n\nAA1884 - Rusini Siyara Liyanachchi\n\nAA1841 - J.A. Ruwini Shashipraba\n\nAA1857 - W.M Shehan Udantha\n\nAA1696 - Prasadi Hansika\n\n# Data Set Problems\nAmerican Express is a globally integrated payments company. The largest payment card issuer in the world, they provide customers with access to products, insights, and experiences that enrich lives and build business success.\n\nWe’ll be apply our machine learning skills to predict credit default which allows lenders to optimize lending decisions.\n\nData pre-processing and feature engineering will be performed to prepare the dataset before it is used by the machine learning model.\n\n# Objectives\nThe objective of this competition is to predict the probability that a customer does not pay back their credit card balance amount in the future based on their monthly customer profile.\n\n# Data Set Description\nThe dataset contains aggregated profile features for each customer at each statement date. Features are anonymized and normalized, and fall into the following general categories,\n\nD = Delinquency variables\n\nS = Spend variables\n\nP = Payment variables\n\nB = Balance variables\n\nR = Risk variables\n\nwith the following features being categorical:\n\n['B_30', 'B_38', 'D_114', 'D_116', 'D_117', 'D_120', 'D_126', 'D_63', 'D_64', 'D_66', 'D_68']\n\nOur task is to predict, for each customer_ID, the probability of a future payment default (target = 1).\n\nNote that the negative class has been subsampled for this dataset at 5%, and thus receives a 20x weighting in the scoring metric.\n\n# Importing Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\n%matplotlib inline\nimport random\n\nimport warnings \nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:06.583007Z","iopub.execute_input":"2022-08-08T15:39:06.583596Z","iopub.status.idle":"2022-08-08T15:39:06.591146Z","shell.execute_reply.started":"2022-08-08T15:39:06.583558Z","shell.execute_reply":"2022-08-08T15:39:06.589863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random.seed(42)\nplt.style.use('fivethirtyeight')\nwarnings.filterwarnings('ignore')\nsns.color_palette(\"flare\", as_cmap=True)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:06.596747Z","iopub.execute_input":"2022-08-08T15:39:06.597780Z","iopub.status.idle":"2022-08-08T15:39:06.614477Z","shell.execute_reply.started":"2022-08-08T15:39:06.597732Z","shell.execute_reply":"2022-08-08T15:39:06.613362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loding Data","metadata":{}},{"cell_type":"code","source":"\ndf_train = pd.read_feather('../input/amexfeather/train_data.ftr')\ndf_train = df_train.groupby('customer_ID').tail(1).set_index('customer_ID')\n\ntest = pd.read_feather('../input/amexfeather/test_data.ftr')\ntest = test.groupby('customer_ID').tail(1).set_index('customer_ID')                         ","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:06.616472Z","iopub.execute_input":"2022-08-08T15:39:06.616929Z","iopub.status.idle":"2022-08-08T15:39:58.570594Z","shell.execute_reply.started":"2022-08-08T15:39:06.616893Z","shell.execute_reply":"2022-08-08T15:39:58.568737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:58.575078Z","iopub.execute_input":"2022-08-08T15:39:58.575612Z","iopub.status.idle":"2022-08-08T15:39:58.608265Z","shell.execute_reply.started":"2022-08-08T15:39:58.575572Z","shell.execute_reply":"2022-08-08T15:39:58.607217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Missing values","metadata":{}},{"cell_type":"markdown","source":"Lets take only the latest transaction from each customer.\n\nLatest transaction may have missing values, we will perform forward fill for those missing values.\n\n","metadata":{}},{"cell_type":"code","source":"null_vals = df_train.isna().sum().sort_values(ascending=False)\nnull_vals[null_vals > 0 ]","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:58.612049Z","iopub.execute_input":"2022-08-08T15:39:58.612340Z","iopub.status.idle":"2022-08-08T15:39:59.022993Z","shell.execute_reply.started":"2022-08-08T15:39:58.612315Z","shell.execute_reply":"2022-08-08T15:39:59.021799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.title(\"Distribution of null values\")\nnull_vals[null_vals > 0 ].plot(kind = 'hist');","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:59.024864Z","iopub.execute_input":"2022-08-08T15:39:59.025540Z","iopub.status.idle":"2022-08-08T15:39:59.433144Z","shell.execute_reply.started":"2022-08-08T15:39:59.025500Z","shell.execute_reply":"2022-08-08T15:39:59.432113Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"There are several columns in our dataset that have close to one million missing values, or almost the same number of rows, so it would be best to remove those columns.","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(40,10))\nplt.title(\"Null value count\")\nplt.xlabel(\"Columns\")\nplt.ylabel(\"Count\")\nnull_vals[null_vals > 0 ].plot(kind=\"bar\");","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:39:59.438109Z","iopub.execute_input":"2022-08-08T15:39:59.440745Z","iopub.status.idle":"2022-08-08T15:40:00.925656Z","shell.execute_reply.started":"2022-08-08T15:39:59.440701Z","shell.execute_reply":"2022-08-08T15:40:00.924680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Target Imbalance","metadata":{}},{"cell_type":"code","source":"sns.countplot(\n    df_train[\"target\"].values,\n).set_xlabel(\"Target\");","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:00.927072Z","iopub.execute_input":"2022-08-08T15:40:00.928127Z","iopub.status.idle":"2022-08-08T15:40:01.123160Z","shell.execute_reply.started":"2022-08-08T15:40:00.928082Z","shell.execute_reply":"2022-08-08T15:40:01.122170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = df_train['target']\nX = df_train.drop(['target'],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:01.124549Z","iopub.execute_input":"2022-08-08T15:40:01.125607Z","iopub.status.idle":"2022-08-08T15:40:01.526950Z","shell.execute_reply.started":"2022-08-08T15:40:01.125562Z","shell.execute_reply":"2022-08-08T15:40:01.525921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=26,stratify=y)\n\nprint(\"X_train Training Data Size :\",X_train.shape[0])\nprint(\"X_test Testing Data Size   :\",X_test.shape[0])","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:01.530866Z","iopub.execute_input":"2022-08-08T15:40:01.531178Z","iopub.status.idle":"2022-08-08T15:40:02.772078Z","shell.execute_reply.started":"2022-08-08T15:40:01.531151Z","shell.execute_reply":"2022-08-08T15:40:02.771023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# How does each variable correlate with the target?\n\nCount of each type of variables","metadata":{}},{"cell_type":"code","source":"var_count = {}\nfor col in df_train.columns :\n    if col.startswith(\"S_\"):\n        var_count[\"Spend variables\"] = var_count.get(\"Spend variables\", 0) + 1 \n    if col.startswith(\"D_\"):\n        var_count[\"Deliquency variables\"] = var_count.get(\"Deliquency variables\", 0) + 1\n    if col.startswith(\"B_\"):\n        var_count[\"Balance variables\"] = var_count.get(\"Balance variables\", 0) + 1\n    if col.startswith(\"R_\"):\n        var_count[\"Risk variables\"] = var_count.get(\"Risk variables\", 0) + 1\n    if col.startswith(\"P_\"):\n        var_count[\"Payment variables\"] = var_count.get(\"Payment variables\", 0) + 1\nplt.figure(figsize=(15,5))\nsns.barplot(x=list(var_count.keys()), y=list(var_count.values()));","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:02.773631Z","iopub.execute_input":"2022-08-08T15:40:02.774020Z","iopub.status.idle":"2022-08-08T15:40:02.970749Z","shell.execute_reply.started":"2022-08-08T15:40:02.773982Z","shell.execute_reply":"2022-08-08T15:40:02.969720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Payment variables (P_*) vs Target¶\n\n","metadata":{}},{"cell_type":"code","source":"payment_vars = [col for col in df_train.columns if col.startswith(\"P_\")]\ncorr = df_train[payment_vars+[\"target\"]].corr()\nsns.heatmap(corr, annot=True, cmap=\"Purples\");","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:02.972317Z","iopub.execute_input":"2022-08-08T15:40:02.972661Z","iopub.status.idle":"2022-08-08T15:40:03.254609Z","shell.execute_reply.started":"2022-08-08T15:40:02.972626Z","shell.execute_reply":"2022-08-08T15:40:03.253675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axes = plt.subplots(1,3, figsize=(20,5))\naxes = axes.ravel()\n\nfor i, col in enumerate(payment_vars)  :\n    sns.histplot(data = df_train, x = col, hue='target', ax=axes[i])\n\nfig.suptitle(\"Distribution of Payment Variables w.r.t target\")\nfig.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:03.256109Z","iopub.execute_input":"2022-08-08T15:40:03.257126Z","iopub.status.idle":"2022-08-08T15:40:44.779678Z","shell.execute_reply.started":"2022-08-08T15:40:03.257086Z","shell.execute_reply":"2022-08-08T15:40:44.778686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"P_4\"].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:44.781186Z","iopub.execute_input":"2022-08-08T15:40:44.782183Z","iopub.status.idle":"2022-08-08T15:40:44.803834Z","shell.execute_reply.started":"2022-08-08T15:40:44.782144Z","shell.execute_reply":"2022-08-08T15:40:44.802988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train[\"P_4\"] = df_train[\"P_4\"].apply(lambda x : 0 if x == 0 else 1)\nplt.title(\"P_4 w.r.t target\")\nsns.countplot(data = df_train, x = \"P_4\", hue = \"target\");","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:44.804981Z","iopub.execute_input":"2022-08-08T15:40:44.805317Z","iopub.status.idle":"2022-08-08T15:40:45.370690Z","shell.execute_reply.started":"2022-08-08T15:40:44.805282Z","shell.execute_reply":"2022-08-08T15:40:45.369723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Higher the P_2 lower the chances of default\n\nTarget = 1 (i.e. default) is following a normal distribution in both P_2 and P_3\n\nWhen P_4 is 1, there's 50% of chance of being default but when it goes 0 lot of cases seem to be having less default","metadata":{}},{"cell_type":"code","source":"df_train.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:45.372330Z","iopub.execute_input":"2022-08-08T15:40:45.372989Z","iopub.status.idle":"2022-08-08T15:40:45.379670Z","shell.execute_reply.started":"2022-08-08T15:40:45.372949Z","shell.execute_reply":"2022-08-08T15:40:45.378475Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = df_train.dropna(axis=1, thresh=int(0.80 * len(df_train)))\ndf_train.shape","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:45.381621Z","iopub.execute_input":"2022-08-08T15:40:45.381927Z","iopub.status.idle":"2022-08-08T15:40:46.019175Z","shell.execute_reply.started":"2022-08-08T15:40:45.381901Z","shell.execute_reply":"2022-08-08T15:40:46.018009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_counts = df_train['target'].value_counts()\nplt.figure(figsize = (8,6))\nsns.barplot(label_counts.index, label_counts.values, alpha = 0.9)\nplt.xticks(rotation = 'vertical')\nplt.xlabel('Class', fontsize =12)\nplt.ylabel('Counts', fontsize = 12)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:46.020945Z","iopub.execute_input":"2022-08-08T15:40:46.021347Z","iopub.status.idle":"2022-08-08T15:40:46.203713Z","shell.execute_reply.started":"2022-08-08T15:40:46.021310Z","shell.execute_reply":"2022-08-08T15:40:46.202695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = df_train['target']\nX = df_train.drop(['target'],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:46.204988Z","iopub.execute_input":"2022-08-08T15:40:46.206071Z","iopub.status.idle":"2022-08-08T15:40:46.446029Z","shell.execute_reply.started":"2022-08-08T15:40:46.206033Z","shell.execute_reply":"2022-08-08T15:40:46.445015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=26,stratify=y)\n\nprint(\"X_train Training Data Size :\",X_train.shape[0])\nprint(\"X_test Testing Data Size   :\",X_test.shape[0])","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:46.447417Z","iopub.execute_input":"2022-08-08T15:40:46.449066Z","iopub.status.idle":"2022-08-08T15:40:47.473868Z","shell.execute_reply.started":"2022-08-08T15:40:46.449025Z","shell.execute_reply":"2022-08-08T15:40:47.472677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test Data","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport glob\nfrom scipy.stats import rankdata\n\npaths = [x for x in glob.glob('../input/*/*.csv') if 'amex-default-prediction' not in x]\ndfs = [pd.read_csv(x) for x in paths]\ndfs = [x.sort_values(by='customer_ID') for x in dfs]\n\npaths = [x for x in glob.glob('../input/*/*.csv') if 'amex-default-prediction' not in x]\npaths\n\nfor df in dfs:\n    df['prediction'] = np.clip(df['prediction'], 0, 1)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:47.475527Z","iopub.execute_input":"2022-08-08T15:40:47.476227Z","iopub.status.idle":"2022-08-08T15:40:53.992671Z","shell.execute_reply.started":"2022-08-08T15:40:47.476188Z","shell.execute_reply":"2022-08-08T15:40:53.991602Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submitions","metadata":{}},{"cell_type":"code","source":"submit = pd.read_csv('../input/amex-default-prediction/sample_submission.csv')\nsubmit['prediction'] = 0\n\nfor df in dfs:\n    submit['prediction'] += df['prediction']\n    \nsubmit['prediction'] /= 4\n\nsubmit.to_csv('mean_submission.csv', index=None)\n\n\nsubmit = pd.read_csv('../input/amex-default-prediction/sample_submission.csv')\nsubmit['prediction'] = 0\n\nfor df in dfs:\n    submit['prediction'] += rankdata(df['prediction'])/df.shape[0]\n    \nsubmit['prediction'] /= 4\n\nsubmit.to_csv('rank_submission.csv', index=None)\n","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:40:53.994281Z","iopub.execute_input":"2022-08-08T15:40:53.994666Z","iopub.status.idle":"2022-08-08T15:41:02.985616Z","shell.execute_reply.started":"2022-08-08T15:40:53.994629Z","shell.execute_reply":"2022-08-08T15:41:02.984299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"weights = [0.52, 0.87, 0.95, 0.57, 1, 0.8]","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:41:02.991720Z","iopub.execute_input":"2022-08-08T15:41:02.992114Z","iopub.status.idle":"2022-08-08T15:41:02.997923Z","shell.execute_reply.started":"2022-08-08T15:41:02.992084Z","shell.execute_reply":"2022-08-08T15:41:02.995820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit = pd.read_csv('../input/amex-default-prediction/sample_submission.csv')\nsubmit['prediction'] = 0\n\nfor df, weight in zip(dfs, weights):\n    submit['prediction'] += (df['prediction'] * weight)\n    \nsubmit['prediction'] /= np.sum(weights)\n\nsubmit.to_csv('mean_submission.csv', index=None)\n\n \nsubmit = pd.read_csv('../input/amex-default-prediction/sample_submission.csv')\nsubmit['prediction'] = 0\n\nfor df, weight in zip(dfs, weights):\n    submit['prediction'] += (rankdata(df['prediction'])/df.shape[0]) * weight\n    \nsubmit['prediction'] /= 4\n\nsubmit.to_csv('submission.csv', index=None)    ","metadata":{"execution":{"iopub.status.busy":"2022-08-08T15:41:03.000032Z","iopub.execute_input":"2022-08-08T15:41:03.000900Z","iopub.status.idle":"2022-08-08T15:41:11.010832Z","shell.execute_reply.started":"2022-08-08T15:41:03.000810Z","shell.execute_reply":"2022-08-08T15:41:11.009471Z"},"trusted":true},"execution_count":null,"outputs":[]}]}