{"metadata": {"language_info": {"nbconvert_exporter": "python", "mimetype": "text/x-python", "name": "python", "pygments_lexer": "ipython3", "codemirror_mode": {"name": "ipython", "version": 3}, "version": "3.6.3", "file_extension": ".py"}, "kernelspec": {"language": "python", "name": "python3", "display_name": "Python 3"}}, "nbformat": 4, "cells": [{"metadata": {"_cell_guid": "2bd7824d-4501-4724-8b2e-0c2844460353", "_uuid": "146117f38cde91077f74723fc3d11babc5bc69b8"}, "source": ["\n", "Data were prepared by [this script](https://www.kaggle.com/aharless/preparing-data-for-lgbm-or-something-else/output) (originally designed for LightGBM, hence the title, but it turns out to work just as well for other methods).\n", "\n", "This notebook implements [Bojan's XGBoost kernel](https://www.kaggle.com/tunguz/xgboost-one-step-ahead-lb-0-519) using the previously prepared data.  This goes into a little bit more detail about validation results.  Specifically, version 2 of this notebook implements version 8 of Bojan's kernel and, surprisingly, seems to get the same results.  (XGBoost is more reliable than LightGBM and CatBoost, it appears.)\n", "\n", "The data arrangement comes originally from  [Lingzhi's upgraded version](https://www.kaggle.com/vrtjso/lgbm-one-step-ahead) of Ceshine's [LGBM starter](https://www.kaggle.com/ceshine/lgbm-starter) script."], "cell_type": "markdown"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "acc4a2ab-8249-48b9-9208-0318827e0e31", "collapsed": true, "_uuid": "9fbf4db969b3035cde640c651aa4031b8d8440c3"}, "source": ["MAX_PRED = 1000\n", "MAX_ROUNDS = 100"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "1e632d4a-2fe8-4a4e-bc96-5b7c985ad3a5", "collapsed": true, "_uuid": "8ec47e6264e7a62a2f555101331b5ef20545bb95"}, "source": ["from datetime import date, timedelta\n", "import pandas as pd\n", "import numpy as np\n", "from sklearn.metrics import mean_squared_error\n", "import xgboost as xgb\n", "from subprocess import check_output\n", "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "6ddda393-3bf0-4427-8090-4afd29fed0ae", "collapsed": true, "_uuid": "d87c09bff2d91506fb431c64864c2ca85a1d345c"}, "source": ["indir = '../input/preparing-data-for-lgbm-or-something-else/'\n", "indir2 = '../input/favorita-grocery-sales-forecasting/'"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "e0a3cdab-1e83-4eac-8a65-9087b1c7bcf1", "collapsed": true, "_uuid": "12b8b208eea67cc7d63b812f7f74ea859c970cb2"}, "source": ["X_test = pd.read_csv(indir + 'X_test.csv')\n", "X_val = pd.read_csv(indir + 'X_val.csv')\n", "X_train = pd.read_csv(indir + 'X_train.csv')\n", "y_train = np.array(pd.read_csv(indir + 'y_train.csv'))\n", "y_val = np.array(pd.read_csv(indir + 'y_val.csv'))\n", "stores_items = pd.read_csv(indir + 'stores_items.csv', index_col=['store_nbr','item_nbr'])\n", "test_ids = pd.read_csv( indir + 'test_ids.csv',  parse_dates=['date']).set_index(\n", "                        ['store_nbr', 'item_nbr', 'date'] )"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "18fc56fb-2cd4-4a8f-b674-ac69a9be785b", "collapsed": true, "_uuid": "eab98ff74166b8c95d051affc17ff0add8ed5c21"}, "source": ["items = pd.read_csv( indir2 + 'items.csv' ).set_index(\"item_nbr\")\n", "items = items.reindex( stores_items.index.get_level_values(1) )"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "333e446c-5d51-473a-b950-63838ee50de7", "collapsed": true, "_uuid": "45672161c686d522162979538dcc7b22fc9ea832"}, "source": ["param = {}\n", "param['objective'] = 'reg:linear'\n", "param['eta'] = 0.5\n", "param['max_depth'] = 3\n", "param['silent'] = 1\n", "param['eval_metric'] = 'rmse'\n", "param['min_child_weight'] = 4\n", "param['subsample'] = 0.8\n", "param['colsample_bytree'] = 0.7\n", "param['seed'] = 137\n", "plst = list(param.items())"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "d8d0fedb-c005-4c84-821d-38594af832cf", "collapsed": true, "_uuid": "c94a579ef3229e57fe8d01fd066e0ae29f0c1bea"}, "source": ["val_pred = []\n", "test_pred = []\n", "cate_vars = []\n", "dtest = xgb.DMatrix(X_test)\n", "for i in range(16):\n", "    print(\"=\" * 50)\n", "    print(\"Step %d\" % (i+1))\n", "    print(\"=\" * 50)\n", "    dtrain = xgb.DMatrix(\n", "        X_train, label=y_train[:, i],\n", "        weight=pd.concat([items[\"perishable\"]] * 6) * 0.25 + 1\n", "    )\n", "    dval = xgb.DMatrix(\n", "        X_val, label=y_val[:, i],\n", "        weight=items[\"perishable\"] * 0.25 + 1)\n", "        \n", "    watchlist = [ (dtrain,'train'), (dval, 'val') ]\n", "    model = xgb.train(plst, dtrain, MAX_ROUNDS, watchlist, early_stopping_rounds=50, verbose_eval=50)\n", "    \n", "    val_pred.append(model.predict(dval))\n", "    test_pred.append(model.predict(dtest))"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "f36e22b1-cfff-42be-814e-73aaec710506", "collapsed": true, "_uuid": "09220ec904335735d5d135c7e08ccc9b6bfce664"}, "source": ["n_public = 5 # Number of days in public test set\n", "weights=pd.concat([items[\"perishable\"]]) * 0.25 + 1\n", "print(\"Unweighted validation mse: \", mean_squared_error(\n", "    y_val, np.minimum( np.array(val_pred).transpose(), np.log1p(MAX_PRED) ) )   )\n", "mse = mean_squared_error(\n", "    y_val, np.minimum( np.array(val_pred).transpose(), np.log1p(MAX_PRED) ), \n", "    sample_weight=weights)\n", "print(\"Full validation mse:       \", mse )\n", "msepub = mean_squared_error(\n", "    y_val[:,:n_public], \n", "    np.minimum( np.array(val_pred).transpose()[:,:n_public], np.log1p(MAX_PRED) ),\n", "    sample_weight=weights)\n", "print(\"'Public' validation mse:   \",  msepub )\n", "msepriv = mean_squared_error(\n", "    y_val[:,n_public:], \n", "    np.minimum( np.array(val_pred).transpose()[:,n_public:], np.log1p(MAX_PRED) ),\n", "    sample_weight=weights)\n", "print(\"'Private' validation mse:  \",  msepriv )\n", "print('Validation NRMSWLE')\n", "print( \"  Full:    \", np.sqrt(mse) )\n", "print( \"  Public:  \", np.sqrt(msepub) )\n", "print( \"  Private: \", np.sqrt(msepriv) )"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "6725af78-42d4-4979-96ac-72250fa682cb", "collapsed": true, "_uuid": "0e02cd63f6efb3e889fb9e3ba6e2bad3be40c2da"}, "source": ["y_test = np.array(test_pred).transpose()\n", "df_preds = pd.DataFrame(\n", "    y_test, index=stores_items.index,\n", "    columns=pd.date_range(\"2017-08-16\", periods=16)\n", ").stack().to_frame(\"unit_sales\")\n", "df_preds.index.set_names([\"store_nbr\", \"item_nbr\", \"date\"], inplace=True)"], "cell_type": "code"}, {"execution_count": null, "outputs": [], "metadata": {"_cell_guid": "3c7be7e9-df8c-404e-b0f3-e6f0fd7e0719", "collapsed": true, "_uuid": "c4f4dadcd3b7588bb8bb62256ca10d1297efb793"}, "source": ["submission = test_ids.join(df_preds, how=\"left\").fillna(0)\n", "submission[\"unit_sales\"] = np.clip(np.expm1(submission[\"unit_sales\"]), 0, MAX_PRED)\n", "submission.to_csv('xgb_whatever.csv', float_format='%.4f', index=None)"], "cell_type": "code"}], "nbformat_minor": 1}