{"cells": [{"source": ["\n", "Data were prepared by [this script](https://www.kaggle.com/aharless/preparing-data-for-lgbm-or-something-else/output).\n", "\n", "This is essentially a 2-step process to implement (Bojan's [retuning](https://www.kaggle.com/tunguz/lgbm-one-step-ahead-lb-0-514) of) [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.  The results are slightly different, probably because of lost precision (since I only use 6 decimal places in the prepared data) or maybe because there's a bug.\n", "\n", "This is an experiment with the new Kaggle feature that allows you to create kernels directly using the output of another kernel.   If you want to run variations on the model fit (or a completely different model using the same data setup), you don't have to prepare the data again every time.  Turns out it's pretty easy to [run a different kind of model](https://www.kaggle.com/aharless/nn-starter-using-lingzhi-data/) on the same data."], "metadata": {"_uuid": "146117f38cde91077f74723fc3d11babc5bc69b8", "_cell_guid": "2bd7824d-4501-4724-8b2e-0c2844460353"}, "cell_type": "markdown"}, {"execution_count": null, "metadata": {"collapsed": true}, "outputs": [], "cell_type": "code", "source": ["MAX_PRED=1000"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "8ec47e6264e7a62a2f555101331b5ef20545bb95", "_cell_guid": "1e632d4a-2fe8-4a4e-bc96-5b7c985ad3a5"}, "outputs": [], "cell_type": "code", "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 lightgbm as lgb\n", "from subprocess import check_output\n", "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "d87c09bff2d91506fb431c64864c2ca85a1d345c", "_cell_guid": "6ddda393-3bf0-4427-8090-4afd29fed0ae"}, "outputs": [], "cell_type": "code", "source": ["indir = '../input/preparing-data-for-lgbm-or-something-else/'\n", "indir2 = '../input/favorita-grocery-sales-forecasting/'"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "12b8b208eea67cc7d63b812f7f74ea859c970cb2", "_cell_guid": "e0a3cdab-1e83-4eac-8a65-9087b1c7bcf1"}, "outputs": [], "cell_type": "code", "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'] )"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "eab98ff74166b8c95d051affc17ff0add8ed5c21", "_cell_guid": "18fc56fb-2cd4-4a8f-b674-ac69a9be785b"}, "outputs": [], "cell_type": "code", "source": ["items = pd.read_csv( indir2 + 'items.csv' ).set_index(\"item_nbr\")\n", "items = items.reindex( stores_items.index.get_level_values(1) )"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "31f37196a31dfdb7a54ff85c28c0e5505d27e8fc", "_cell_guid": "27adbda7-bbdc-4b8c-925f-a98f13944bea"}, "outputs": [], "cell_type": "code", "source": ["params = {\n", "    'num_leaves': 31,\n", "    'objective': 'regression',\n", "    'min_data_in_leaf': 200,\n", "    'learning_rate': 0.02,\n", "    'feature_fraction': 0.8,\n", "    'bagging_fraction': 0.8,\n", "    'bagging_freq': 2,\n", "    'metric': 'l2',\n", "    'num_threads': 4\n", "}"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "c94a579ef3229e57fe8d01fd066e0ae29f0c1bea", "_cell_guid": "d8d0fedb-c005-4c84-821d-38594af832cf"}, "outputs": [], "cell_type": "code", "source": ["MAX_ROUNDS = 3000\n", "val_pred = []\n", "test_pred = []\n", "cate_vars = []\n", "for i in range(16):\n", "    print(\"=\" * 50)\n", "    print(\"Step %d\" % (i+1))\n", "    print(\"=\" * 50)\n", "    dtrain = lgb.Dataset(\n", "        X_train, label=y_train[:, i],\n", "        categorical_feature=cate_vars,\n", "        weight=pd.concat([items[\"perishable\"]] * 6) * 0.25 + 1\n", "    )\n", "    dval = lgb.Dataset(\n", "        X_val, label=y_val[:, i], reference=dtrain,\n", "        weight=items[\"perishable\"] * 0.25 + 1,\n", "        categorical_feature=cate_vars)\n", "    bst = lgb.train(\n", "        params, dtrain, num_boost_round=MAX_ROUNDS,\n", "        valid_sets=[dtrain, dval], early_stopping_rounds=125, verbose_eval=500\n", "    )\n", "    print(\"\\n\".join((\"%s: %.2f\" % x) for x in sorted(\n", "        zip(X_train.columns, bst.feature_importance(\"gain\")),\n", "        key=lambda x: x[1], reverse=True\n", "    )))\n", "    val_pred.append(bst.predict(\n", "        X_val, num_iteration=bst.best_iteration or MAX_ROUNDS))\n", "    test_pred.append(bst.predict(\n", "        X_test, num_iteration=bst.best_iteration or MAX_ROUNDS))"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "09220ec904335735d5d135c7e08ccc9b6bfce664", "_cell_guid": "f36e22b1-cfff-42be-814e-73aaec710506"}, "outputs": [], "cell_type": "code", "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) )"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "0e02cd63f6efb3e889fb9e3ba6e2bad3be40c2da", "_cell_guid": "6725af78-42d4-4979-96ac-72250fa682cb"}, "outputs": [], "cell_type": "code", "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)"]}, {"execution_count": null, "metadata": {"collapsed": true, "_uuid": "c4f4dadcd3b7588bb8bb62256ca10d1297efb793", "_cell_guid": "3c7be7e9-df8c-404e-b0f3-e6f0fd7e0719"}, "outputs": [], "cell_type": "code", "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('lgb_whatever.csv', float_format='%.4f', index=None)"]}], "nbformat_minor": 1, "metadata": {"language_info": {"codemirror_mode": {"version": 3, "name": "ipython"}, "file_extension": ".py", "name": "python", "version": "3.6.3", "pygments_lexer": "ipython3", "mimetype": "text/x-python", "nbconvert_exporter": "python"}, "kernelspec": {"language": "python", "name": "python3", "display_name": "Python 3"}}, "nbformat": 4}