{"nbformat_minor": 1, "metadata": {"kernelspec": {"display_name": "Python 3", "name": "python3", "language": "python"}, "language_info": {"codemirror_mode": {"version": 3, "name": "ipython"}, "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "file_extension": ".py", "mimetype": "text/x-python", "version": "3.6.3"}}, "nbformat": 4, "cells": [{"source": ["Essentially a repeat of [my earlier kernel](https://www.kaggle.com/aharless/lgbm-from-prepared-favorita-data), but this one uses the new training data (created [here](https://www.kaggle.com/aharless/preparing-data-ii)) that include items that never sold before the test period.\n", "\n", "It is a 2-step process to implement (now with my new data) (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.  (But it probably needs to be retuned again, since the data are different.  Also, I made some changes to make it run 60 minutes.)"], "cell_type": "markdown", "metadata": {"_cell_guid": "948ad518-b873-456f-a112-22cd68bc630c", "_uuid": "ed827c0b999dea312869e815f9e6ba3db77a0e7a"}}, {"execution_count": null, "source": ["MAX_PRED = 1000  # Maximum sales to predict for any single day-store-item combination\n", "MAX_ROUNDS = 2500"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "c19523b3-b4d5-4223-baee-fa400b0ed188", "collapsed": true, "_uuid": "badcb818fb5e559c94aad01adab9f7bc43d6e4e8"}}, {"execution_count": null, "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\"))"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "f53f34f4-06ac-46ea-8412-2bad0710f22c", "collapsed": true, "_uuid": "046e0b50b88b2cb11452a995223a162530701dbf"}}, {"execution_count": null, "source": ["indir = '../input/preparing-data-ii/'\n", "indir2 = '../input/favorita-grocery-sales-forecasting/'"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "381836fb-7e8e-4d21-aec2-d731254a4d61", "collapsed": true, "_uuid": "763b4194fe1c83167cadec01b501902bca62e6da"}}, {"execution_count": null, "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'] )"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "185e1b29-77de-41c0-9e2c-5343e8c0425d", "collapsed": true, "_uuid": "879f9947603c008293f559aeb20376b4ab4c3c88"}}, {"execution_count": null, "source": ["items = pd.read_csv( indir2 + 'items.csv' ).set_index(\"item_nbr\")\n", "items = items.reindex( stores_items.index.get_level_values(1) )"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "eb672eaf-a9fc-4951-b0dc-4ddac553e12a", "collapsed": true, "_uuid": "f4f13f4fc9fbb3e359f161db551da23935cbfb74"}}, {"execution_count": null, "source": ["params = {\n", "    'num_leaves': 31,\n", "    'objective': 'regression',\n", "    'min_data_in_leaf': 200,\n", "    'learning_rate': 0.027,\n", "    'feature_fraction': 0.8,\n", "    'bagging_fraction': 0.8,\n", "    'bagging_freq': 2,\n", "    'metric': 'l2',\n", "    'num_threads': 4\n", "}"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "f903c6aa-856b-4f04-a674-9389fcc3daa2", "collapsed": true, "_uuid": "dab275674bcc12e6871fb3325ddf4e7a567ac560"}}, {"execution_count": null, "source": ["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=150, verbose_eval=200\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))"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "3d710bb3-f71a-4efe-b2af-cfa3c8da0f09", "collapsed": true, "_uuid": "80e2dd0f0854d6b5cca36230a77834fa28a94d5a"}}, {"source": ["Note: Validation scores may not comparable with earlier versions, since these data include items that were not in the original training set."], "cell_type": "markdown", "metadata": {"_cell_guid": "8fe81a32-d25d-4df8-b24a-87a087e4dc09", "_uuid": "7a6d84e7e81866370dbc341556397640fcd06485"}}, {"execution_count": null, "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.array(val_pred).transpose()) )\n", "print(\"Full validation mse:       \", mean_squared_error(\n", "    y_val, np.array(val_pred).transpose(), sample_weight=weights) )\n", "print(\"'Public' validation mse:   \", mean_squared_error(\n", "    y_val[:,:n_public], np.array(val_pred).transpose()[:,:n_public], sample_weight=weights) )\n", "print(\"'Private' validation mse:  \", mean_squared_error(\n", "    y_val[:,n_public:], np.array(val_pred).transpose()[:,n_public:], sample_weight=weights) )"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "e5f197fd-e893-4f9e-aa46-6e9c64aedbfa", "collapsed": true, "_uuid": "84bdda80ececef1773747520c320632328015c21"}}, {"execution_count": null, "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)"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "fbe3911f-5e47-49ea-8bfc-45c2babdc6bb", "collapsed": true, "_uuid": "29b55e9fa5cac97d51d86610b8ecb6dca5de4ad4"}}, {"execution_count": null, "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_including_unsold.csv', float_format='%.4f', index=None)"], "outputs": [], "cell_type": "code", "metadata": {"_cell_guid": "03e7a9e0-4e7c-4e67-8853-a42c4a09e864", "collapsed": true, "_uuid": "8a355d5ff3af0316614e8d2b659d0724bc7a26ff"}}]}