{"nbformat_minor": 1, "nbformat": 4, "cells": [{"cell_type": "markdown", "source": ["This is a very rudimentary neural network using the data prepared by [this script](https://www.kaggle.com/aharless/preparing-data-for-lgbm-or-something-else/output).  The data represent the fitting and validation scheme derived from Ceshine's [LGBM starter](https://www.kaggle.com/ceshine/lgbm-starter) script with the additional features created in [Lingzhi's upgraded version](https://www.kaggle.com/vrtjso/lgbm-one-step-ahead).  So far I've made no attempt to preprocess them further for optimal use by the neural network.  (I used [kaggleslayer's code](https://www.kaggle.com/kaggleslayer/grocery-prediction-with-neural-network) as a starting point for the structure of the network itself.)\n"], "metadata": {}}, {"execution_count": null, "cell_type": "code", "source": ["N_EPOCHS = 3  # Should be more, but the network has to run 16 times in a Kaggle kernel"], "outputs": [], "metadata": {"collapsed": true}}, {"execution_count": null, "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 keras.models import Sequential\n", "from keras.layers.core import Dense, Dropout, Activation\n", "from keras import callbacks\n", "from keras.callbacks import ModelCheckpoint\n", "\n", "from subprocess import check_output\n", "print(check_output([\"ls\", \"../input\"]).decode(\"utf8\"))"], "outputs": [], "metadata": {"_cell_guid": "1e632d4a-2fe8-4a4e-bc96-5b7c985ad3a5", "collapsed": true, "_uuid": "8ec47e6264e7a62a2f555101331b5ef20545bb95"}}, {"execution_count": null, "cell_type": "code", "source": ["indir = '../input/preparing-data-for-lgbm-or-something-else/'\n", "indir2 = '../input/favorita-grocery-sales-forecasting/'"], "outputs": [], "metadata": {"_cell_guid": "6ddda393-3bf0-4427-8090-4afd29fed0ae", "collapsed": true, "_uuid": "d87c09bff2d91506fb431c64864c2ca85a1d345c"}}, {"execution_count": null, "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'] )\n", "items = pd.read_csv( indir2 + 'items.csv' ).set_index(\"item_nbr\")\n", "items = items.reindex( stores_items.index.get_level_values(1) )"], "outputs": [], "metadata": {"_cell_guid": "e0a3cdab-1e83-4eac-8a65-9087b1c7bcf1", "collapsed": true, "_uuid": "12b8b208eea67cc7d63b812f7f74ea859c970cb2"}}, {"execution_count": null, "cell_type": "code", "source": ["model = Sequential()\n", "model.add(Dense(32, kernel_initializer='normal', activation='relu', input_shape=(X_train.shape[1],)))\n", "model.add(Dropout(.2))\n", "model.add(Dense(16, kernel_initializer='normal', activation='relu'))\n", "model.add(Dropout(.1))\n", "model.add(Dense(1, kernel_initializer='normal'))\n", "model.compile(loss = 'mse', optimizer='adam', metrics=['mse'])"], "outputs": [], "metadata": {"_cell_guid": "82cf743b-d35b-4d76-bdc0-bef713bd7b95", "collapsed": true, "_uuid": "9bf8c811452e5d4ad2bf4cbbec7d6e38e6a16ca5"}}, {"cell_type": "markdown", "source": ["Note: See this [stack overflow post](https://stackoverflow.com/questions/47802601/nonetype-error-on-saving-model-in-keras) on the problem that led me to comment out the early stopping code in the block below."], "metadata": {"_cell_guid": "228e291b-df30-4c2b-b6b9-1dab7ed8ca8c", "_uuid": "a00783d1c33626026f02c01b0a85f9483abbde37"}}, {"execution_count": null, "cell_type": "code", "source": ["val_pred = []\n", "test_pred = []\n", "# wtpath = 'weights.hdf5'  # To save best epoch. But need Keras bug to be fixed first.\n", "sample_weights=np.array( pd.concat([items[\"perishable\"]] * 6) * 0.25 + 1 )\n", "for i in range(16):\n", "    print(\"=\" * 50)\n", "    print(\"Step %d\" % (i+1))\n", "    print(\"=\" * 50)\n", "    y = y_train[:, i]\n", "    xv = np.array(X_val)\n", "    yv = y_val[:, i]\n", "#    bestepoch = ModelCheckpoint( filepath=wtpath, verbose=1, save_best_only=True )\n", "    model.fit( np.array(X_train), y, batch_size = 32, epochs = N_EPOCHS, verbose=2,\n", "               sample_weight=sample_weights, validation_data=(xv,yv) ) \n", "             #, callbacks=[bestepoch] # bestepoch doesn't work: keras bug\n", "#    model.load_weights( wtpath )\n", "    val_pred.append(model.predict(X_val))\n", "    test_pred.append(model.predict(X_test))"], "outputs": [], "metadata": {"_cell_guid": "d8d0fedb-c005-4c84-821d-38594af832cf", "collapsed": true, "_uuid": "c94a579ef3229e57fe8d01fd066e0ae29f0c1bea"}}, {"execution_count": null, "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.array(val_pred).squeeze(axis=2).transpose()) )\n", "print(\"Full validation mse:       \", mean_squared_error(\n", "    y_val, np.array(val_pred).squeeze(axis=2).transpose(), sample_weight=weights) )\n", "print(\"'Public' validation mse:   \", mean_squared_error(\n", "    y_val[:,:n_public], np.array(val_pred).squeeze(axis=2).transpose()[:,:n_public], \n", "    sample_weight=weights) )\n", "print(\"'Private' validation mse:  \", mean_squared_error(\n", "    y_val[:,n_public:], np.array(val_pred).squeeze(axis=2).transpose()[:,n_public:], \n", "    sample_weight=weights) )"], "outputs": [], "metadata": {"_cell_guid": "2ce03313-40c7-44bf-904e-f60cdc6bd17b", "collapsed": true, "_uuid": "945900465e5c76fed6228c59787041b4b775c6de"}}, {"execution_count": null, "cell_type": "code", "source": ["y_test = np.array(test_pred).squeeze(axis=2).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": [], "metadata": {"_cell_guid": "3dd23e34-fe1b-43f8-a4c8-9e2f775e8220", "collapsed": true, "_uuid": "f66a8fb43fca35e195122ed62ef2eaba9b696f7d"}}, {"execution_count": null, "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, 1000)\n", "submission.to_csv('nn_sub_whatever.csv', float_format='%.4f', index=None)"], "outputs": [], "metadata": {"_cell_guid": "dfa7b3d1-0506-4b49-859d-54152c839a76", "collapsed": true, "_uuid": "96ccc1e0484c7796758e74e98fac428cdcdcd000"}}], "metadata": {"kernelspec": {"language": "python", "display_name": "Python 3", "name": "python3"}, "language_info": {"mimetype": "text/x-python", "codemirror_mode": {"version": 3, "name": "ipython"}, "pygments_lexer": "ipython3", "nbconvert_exporter": "python", "file_extension": ".py", "version": "3.6.3", "name": "python"}}}