{"cells":[{"metadata":{"_uuid":"837ccdc8b47fa45f6dd5dedfbf2b054bf09355e3"},"cell_type":"markdown","source":"## Let's import all the necessary libraries"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport lightgbm as lgb\nfrom sklearn.linear_model import Ridge\nimport time\nfrom sklearn import preprocessing\nimport warnings\nimport datetime\nwarnings.filterwarnings(\"ignore\")\nimport gc\nfrom tqdm import tqdm\n\nfrom scipy.stats import describe\n%matplotlib inline\n\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import mean_squared_error\nimport xgboost as xgb\n\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","collapsed":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"markdown","source":"### Read the files "},{"metadata":{"trusted":true,"_uuid":"e8bd8dbeb11955469ba2286f909c9c4f3697f3dc"},"cell_type":"code","source":"train = pd.read_csv(\"../input/train.csv\", parse_dates=[\"first_active_month\"])\ntest = pd.read_csv(\"../input/test.csv\", parse_dates=[\"first_active_month\"])\nprint(\"{} observations and {} features in train set.\".format(train.shape[0],train.shape[1]))\nprint(\"{} observations and {} features in test set.\".format(test.shape[0],test.shape[1]))\n\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"525f2d7d692146641cd33fa314f9d8d54c5bee73"},"cell_type":"code","source":"train.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"92e66d8fe2c248ef8f1f38078bccc9112ff4b618"},"cell_type":"code","source":"train[\"month\"] = train[\"first_active_month\"].dt.month\ntest[\"month\"] = test[\"first_active_month\"].dt.month\ntrain[\"year\"] = train[\"first_active_month\"].dt.year\ntest[\"year\"] = test[\"first_active_month\"].dt.year\ntrain['elapsed_time'] = (datetime.date(2018, 2, 1) - train['first_active_month'].dt.date).dt.days\ntest['elapsed_time'] = (datetime.date(2018, 2, 1) - test['first_active_month'].dt.date).dt.days\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d6b26d064c41e87c8439e567d821dba19a209bd5"},"cell_type":"markdown","source":"Let's now read the transactions file"},{"metadata":{"trusted":true,"_uuid":"53bd854b8ff8c494951d223ad79d182e9863ea1a"},"cell_type":"code","source":"hist_trans = pd.read_csv(\"../input/historical_transactions.csv\")\nhist_trans.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"02ea4275ae4573a68a43411656bf8faff0b0cc35"},"cell_type":"code","source":"print(\"{} transactions and {} columns in trans set.\".format(hist_trans.shape[0],hist_trans.shape[1]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"afb82d0659c700102fb78418b54d0f6b0cdd57a1"},"cell_type":"code","source":"new_trans = pd.read_csv(\"../input/new_merchant_transactions.csv\")\nnew_trans.head()\nprint(\"{} transactions and {} columns in new merchant trans set.\".format(new_trans.shape[0],new_trans.shape[1]))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"440f9258b1d2ecd9d02af71b94e9e792d5e954bd"},"cell_type":"markdown","source":"### **Exploratory Analysis and feature engineering** \n\n#### 1. Train dataset"},{"metadata":{"trusted":true,"_uuid":"040616b5cf60756eee4f6be184a0cf6981850bbc"},"cell_type":"code","source":"#Target variable\nplt.figure(figsize=(12, 5))\nplt.hist(train.target.values, bins=100)\nplt.title('Target counts')\nplt.xlabel('N')\nplt.ylabel('Target')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ccbcabb10132a6b4fef27ed77c89878d13989788"},"cell_type":"markdown","source":"The target variable is well distributed normally. There are some outliers but that can be handled if necessary later "},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"57f8fc7d03092a2fe359bb251ff7a32f737e000c"},"cell_type":"code","source":"# Feature 1\nplt.figure(figsize=(12, 5))\nplt.hist(train.feature_1.values, bins=100)\nplt.title('Histogram feature_1 counts')\nplt.xlabel('Count')\nplt.ylabel('Target')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b0a4413f9011d6b559b2a06160973ee25b601964"},"cell_type":"markdown","source":"Looks like most records are distributed to 3 and 2"},{"metadata":{"trusted":true,"_uuid":"6b5f3d6ed14a28ecb9b454fb4d641295658d463f"},"cell_type":"code","source":"#Feature 2\nplt.figure(figsize=(12, 5))\nplt.hist(train.feature_2.values, bins=100)\nplt.title('Histogram feature_2 counts')\nplt.xlabel('Count')\nplt.ylabel('Target')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"496abd228d053b3fbd1646d91f2161fa52e118fc"},"cell_type":"markdown","source":"Looks like all records are spread through 1 and 2"},{"metadata":{"trusted":true,"_uuid":"0854a1d59f1faace4a05ac67cd8759aa22f1740a"},"cell_type":"code","source":"#Feature3\nplt.figure(figsize=(12, 5))\nplt.hist(train.feature_3.values, bins=100)\nplt.title('Histogram feature_3 counts')\nplt.xlabel('Count')\nplt.ylabel('Target')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"93e60fecca80a6066fc6e902b56b0f863bc741d8"},"cell_type":"markdown","source":"* Feature 3 seems to be spread between 1s and 2s.\n\n#### Lets now look at the date fields to see some insights. We will also ensure the test and train have similar date ranges"},{"metadata":{"trusted":true,"_uuid":"073da5825ad6bc46847165a55c1a96de9b3f8ec3"},"cell_type":"code","source":"train_date_sum = train['first_active_month'].dt.date.value_counts()\ntrain_date_sum = train_date_sum.sort_index()\nplt.figure(figsize=(14,8))\nsns.barplot(train_date_sum.index,train_date_sum.values,color='red')\nplt.xticks(rotation='vertical')\nplt.xlabel('first_active_month')\nplt.ylabel('No.of records')\nplt.title(' Training data - First active month')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d2e900099c6b792dc3174eb90e611932ad4104d1"},"cell_type":"code","source":"test_date_sum = test['first_active_month'].dt.date.value_counts()\ntest_date_sum = test_date_sum.sort_index()\nplt.figure(figsize=(14,8))\nsns.barplot(test_date_sum.index,test_date_sum.values,color='red')\nplt.xticks(rotation='vertical')\nplt.xlabel('first_active_month')\nplt.ylabel('No.of records')\nplt.title(' Test data - First active month')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"355df7a028cf323ecd1923f51c31bdf6b4982290"},"cell_type":"markdown","source":"Date ranges seem pretty similar."},{"metadata":{"_uuid":"59c914356ecb05079a34f741971f4ba874e5f8e5"},"cell_type":"markdown","source":"### **2. Transaction file** "},{"metadata":{"_uuid":"3689bb3cd21e935e0714fb201570b9101122ebac"},"cell_type":"markdown","source":"### The field descriptions are as follows:\n\n* card_id - Card identifier\n* month_lag - month lag to reference date\n* purchase_date - Purchase date\n* authorized_flag - 'Y' if approved, 'N' if denied\n* category_3 - anonymized category\n* installments - number of installments of purchase\n* category_1 - anonymized category\n* merchant_category_id - Merchant category identifier (anonymized )\n* subsector_id - Merchant category group identifier (anonymized )\n* merchant_id - Merchant identifier (anonymized)\n* purchase_amount - Normalized purchase amount\n* city_id - City identifier (anonymized )\n* state_id - State identifier (anonymized )\n* category_2 - anonymized category"},{"metadata":{"trusted":true,"_uuid":"291c77b4c45febbbe795960dc84caf03a26e3385"},"cell_type":"code","source":"hist_trans.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9e288923c6ae5aed5cf6e3240064c2b02567ed9a"},"cell_type":"markdown","source":"Get Count of transactions by card"},{"metadata":{"trusted":true,"_uuid":"444aaed4a9651ac23c76c4d2e883545808c563f5"},"cell_type":"code","source":"trans_count = hist_trans.groupby(\"card_id\")\ntrans_count = trans_count[\"purchase_amount\"].size().reset_index()\ntrans_count.columns = [\"card_id\", \"num_trans\"]\n\ntrain = pd.merge(train, trans_count, on=\"card_id\", how=\"left\")\ntest = pd.merge(test, trans_count, on=\"card_id\", how=\"left\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"468b877b936dc022b2ec941da02ece3c5f80104e"},"cell_type":"markdown","source":"Get transaction features by card"},{"metadata":{"trusted":true,"_uuid":"e382500fd9327007eba2e4e52f64001e1970174a"},"cell_type":"code","source":"trans_summ = hist_trans.groupby(\"card_id\")\ntrans_summ = trans_summ[\"purchase_amount\"].agg(['sum', 'mean', 'std', 'min', 'max']).reset_index()\ntrans_summ.columns = [\"card_id\",\"sum_trans_amt\",\"mean_trans_amt\",\"std_trans_amt\",\"min_trans_amt\",\"max_trans_amt\"]\n\ntrain = pd.merge(train, trans_summ, on=\"card_id\", how=\"left\")\ntest = pd.merge(test, trans_summ, on=\"card_id\", how=\"left\")","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0e9877be594f2037b314bdad27313ecbffd70690"},"cell_type":"markdown","source":"Now that we have decent set of features at a card_id level, let's explore and see how the target score stack-up against the variables"},{"metadata":{"trusted":true,"_uuid":"b18e3b5538f6c632715956c7fa8ccf92e48388aa"},"cell_type":"code","source":"bins = [10,20,50,100,200,500,1000,5000,10000]\ntrain[\"num_trans_bin\"] = pd.cut(train[\"num_trans\"],bins)\n#bin_summ = train.groupby(\"num_trans_bin\")[\"target\"].mean()\n\nfig = plt.figure(figsize=(14,7))\nsns.boxplot(x = \"num_trans_bin\", y = \"target\", data = train,showfliers=False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"27b713e73916666342eeab6d2afb08404fe5cd9d"},"cell_type":"markdown","source":"As the number of transactions increase, we see the spread of the score narrowing. Let's look at the avg transaction value at each of these bins"},{"metadata":{"trusted":true,"_uuid":"134533cf3ea85f711688ed4389fd0b21fa6960b2"},"cell_type":"code","source":"bins = np.percentile(train[\"sum_trans_amt\"],range(0,101,10))\ntrain['sum_trans_amt_bin'] = pd.cut(train['sum_trans_amt'], bins)\n\nfig = plt.figure(figsize=(14,7))\nsns.boxplot(x = \"sum_trans_amt_bin\", y = \"target\", data = train,showfliers=False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"4ffcec0819754e6673578d4ed6fd1b575f7fe38d"},"cell_type":"markdown","source":"The loyalty score seem to increase with the \"sum of historical transaction value\". This logically makes sense"},{"metadata":{"_uuid":"92f2ca5d787fe7d45b17cb53e2c2a41af31416c7"},"cell_type":"markdown","source":"### **3. New Merchant transactions**"},{"metadata":{"trusted":true,"_uuid":"ea710766c5b60d8c7bcb58cb6a0319dda7f008c4"},"cell_type":"code","source":"new_trans.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0f4a2ca1c5e0a8c9c8038ac57d25a9a7a9c7d874"},"cell_type":"markdown","source":"## Let us explore all the summaries as we did for train"},{"metadata":{"trusted":true,"_uuid":"e583934c5b756b0e9226c40991969d9dbf0321c3"},"cell_type":"code","source":"trans_count = new_trans.groupby(\"card_id\")\ntrans_count = trans_count[\"purchase_amount\"].size().reset_index()\ntrans_count.columns = [\"card_id\", \"new_merch_trans\"]\n\ntrain = pd.merge(train, trans_count, on=\"card_id\", how=\"left\")\ntest = pd.merge(test, trans_count, on=\"card_id\", how=\"left\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2409bd6094acb2b882fda6d84767b276d233cc62"},"cell_type":"code","source":"trans_summ = new_trans.groupby(\"card_id\")\ntrans_summ = trans_summ[\"purchase_amount\"].agg(['sum', 'mean', 'std', 'min', 'max']).reset_index()\ntrans_summ.columns = [\"card_id\",\"new_merch_sum_trans_amt\",\"new_merch_mean_trans_amt\",\"new_merch_std_trans_amt\",\"new_merch_min_trans_amt\",\"new_merch_max_trans_amt\"]\n\ntrain = pd.merge(train, trans_summ, on=\"card_id\", how=\"left\")\ntest = pd.merge(test, trans_summ, on=\"card_id\", how=\"left\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d387ab7fdd847ab2cf2fc9374b4763c5be530921"},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"73f2ca42c3fe0eaeda2c41fdbf8f2cea5e62725e"},"cell_type":"code","source":"bins = np.nanpercentile(train[\"new_merch_sum_trans_amt\"],range(0,101,10))\ntrain['new_merch_sum_trans_amt_bin'] = pd.cut(train['new_merch_sum_trans_amt'], bins)\n\nfig = plt.figure(figsize=(14,7))\nsns.boxplot(x = \"new_merch_sum_trans_amt_bin\", y = \"target\", data = train,showfliers=False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6bbbc7c96bb98ee871511e90a170675afa103124"},"cell_type":"markdown","source":"Loyalty scores seem to increase with the increase in the sum of new merchant transaction values but for the last bin."},{"metadata":{"trusted":true,"_uuid":"0556e8343cb8243434cf3a00f425c67a3c375b7b"},"cell_type":"code","source":"bins = [10,20,50,100,200,500,1000,5000,10000]\ntrain[\"new_merch_trans_bin\"] = pd.cut(train[\"new_merch_trans\"],bins)\n#bin_summ = train.groupby(\"num_trans_bin\")[\"target\"].mean()\n\nfig = plt.figure(figsize=(14,7))\nsns.boxplot(x = \"new_merch_trans_bin\", y = \"target\", data = train,showfliers=False)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"_uuid":"02d102e70e6a2cd654f732879aa5b74d89d0ef4d"},"cell_type":"markdown","source":"Loyalty score seem to decrease as the number of new merchant transactions increases except for the last bin."},{"metadata":{"_uuid":"713038afe47f6b7f93e9d8166ee54abb3e5cf6fd"},"cell_type":"markdown","source":"## **Modeling**\n\nNow we have decent number of features and datapoints to create our first cut model."},{"metadata":{"trusted":true,"_uuid":"84087685714fe7bcae871bdb5dd38ee0bce204cb"},"cell_type":"code","source":"train.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"24265e3cd3fdd8651682edf52662989443049480"},"cell_type":"code","source":"print(test.columns)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"97a5bf0065ea7417b8d4edc53b55375cfe6baed9"},"cell_type":"markdown","source":"The below code is from @SRK's repository - Simple LGB"},{"metadata":{"trusted":true,"_uuid":"21a4d1dd12eceeca60eeae1588aa323c71e10e9c"},"cell_type":"code","source":"from sklearn import model_selection, preprocessing, metrics\nimport lightgbm as lgb\n\nfrom sklearn.ensemble import *\nimport xgboost as xgb","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9a6abd215df0cf934471220d91ebe742e82642b7"},"cell_type":"code","source":"cols = [ 'feature_1', 'feature_2', 'feature_3',\n       'month', 'year', 'elapsed_time', 'num_trans', 'sum_trans_amt',\n       'mean_trans_amt', 'std_trans_amt', 'min_trans_amt', 'max_trans_amt',\n       'new_merch_trans', 'new_merch_sum_trans_amt',\n       'new_merch_mean_trans_amt', 'new_merch_std_trans_amt',\n       'new_merch_min_trans_amt', 'new_merch_max_trans_amt']\n\ntarget_col = ['target']\n\n\ndef run_basemodel(train_X, train_y, val_X, val_y, test_X):\n    params = {\n        \"objective\" : \"regression\",\n        \"metric\" : \"rmse\",\n        \"num_leaves\" : 30,\n        \"min_child_weight\" : 50,\n        \"learning_rate\" : 0.05,\n        \"bagging_fraction\" : 0.7,\n        \"feature_fraction\" : 0.7,\n        \"bagging_frequency\" : 5,\n        \"bagging_seed\" : 2018,\n        \"verbosity\" : -1\n    }\n    \n    lgtrain = lgb.Dataset(train_X, label=train_y)\n    lgval = lgb.Dataset(val_X, label=val_y)\n    evals_result = {}\n    model = lgb.train(params, lgtrain, 1000, valid_sets=[lgval], early_stopping_rounds=100, verbose_eval=100, evals_result=evals_result)\n    \n    pred_test_y = model.predict(test_X, num_iteration=model.best_iteration)\n    return pred_test_y, model, evals_result\n\n\ntrain_X = train[cols]\ntest_X = test[cols]\ntrain_y = train[target_col].values\ntrain_y = train_y.ravel()\n\npred_test = 0\nkf = model_selection.KFold(n_splits=5, random_state=2018, shuffle=True)\nfor dev_index, val_index in kf.split(train):\n    dev_X, val_X = train_X.loc[dev_index,:], train_X.loc[val_index,:]\n    dev_y, val_y = train_y[dev_index], train_y[val_index]\n    #print(val_X)\n    \n    pred_test_tmp, model, evals_result = run_basemodel(dev_X, dev_y, val_X, val_y, test_X)\n    pred_test += pred_test_tmp\npred_test /= 5.\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7d529dce9e7921cbbee95d9a0c78b0c6ab5ffed2"},"cell_type":"markdown","source":"Print the variable importances"},{"metadata":{"trusted":true,"_uuid":"237b65d58fbe53417d46539cc4169d82cc710f98"},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(12,10))\nlgb.plot_importance(model, max_num_features=50, height=0.8, ax=ax)\nax.grid(False)\nplt.title(\"LightGBM - Feature Importance\", fontsize=15)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b6057931029203c0ed4e1222c0ae4380a55290d4"},"cell_type":"code","source":"sub_df = pd.DataFrame({\"card_id\":test[\"card_id\"].values})\nsub_df[\"target\"] = pred_test\nsub_df.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ba7323254383873bd8144b4f227a2a61be3ce1b2"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}