{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"LGBM Starter\n\nThis is watered-down version of one of my earlier scripts. \nOnly very basic features are retained so hopefully it won't ruin the fun for you.\n\"\"\"\nfrom datetime import date, timedelta\n\nimport pandas as pd\nimport numpy as np\nfrom sklearn.metrics import mean_squared_error\nimport lightgbm as lgb\n\n# they don't take the onpromotion column -- they haven't passed it in as a feature\ndf_train = pd.read_csv(\n    '../input/favorita-grocery-sales-forecasting/train.csv.7z', usecols=[1, 2, 3, 4, 5],\n    dtype={'onpromotion': bool},\n    converters={'unit_sales': lambda u: np.log1p(\n        float(u)) if float(u) > 0 else 0},\n    parse_dates=[\"date\"],\n    skiprows=range(1, 66458909)  # 2016-01-01\n)\n\ndf_test = pd.read_csv(\n    \"../input/test.csv\", usecols=[0, 1, 2, 3, 4],\n    dtype={'onpromotion': bool},\n    parse_dates=[\"date\"]  # , date_parser=parser\n).set_index(\n    ['store_nbr', 'item_nbr', 'date']\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9e2d76af-fb87-4872-8ef9-2e9d8b1a391e","_cell_guid":"494183ac-3321-4d24-b20e-12e0a4252900","trusted":true},"cell_type":"code","source":"\n\n\"\"\"LGBM Starter\n\nThis is watered-down version of one of my earlier scripts. \nOnly very basic features are retained so hopefully it won't ruin the fun for you.\n\"\"\"\nfrom datetime import date, timedelta\n\nimport pandas as pd\nimport numpy as np\nfrom sklearn.metrics import mean_squared_error\nimport lightgbm as lgb\n\n\n# they don't take the onpromotion column -- they haven't passed it in as a feature\ndf_train = pd.read_csv(\n    '../input/favorita-grocery-sales-forecasting/train.csv.7z', usecols=[1, 2, 3, 4, 5],\n    dtype={'onpromotion': bool},\n    converters={'unit_sales': lambda u: np.log1p(\n        float(u)) if float(u) > 0 else 0},\n    parse_dates=[\"date\"],\n    skiprows=range(1, 66458909)  # 2016-01-01\n)\n\ndf_test = pd.read_csv(\n    \"../input/test.csv\", usecols=[0, 1, 2, 3, 4],\n    dtype={'onpromotion': bool},\n    parse_dates=[\"date\"]  # , date_parser=parser\n).set_index(\n    ['store_nbr', 'item_nbr', 'date']\n)\n\nitems = pd.read_csv(\n    \"../input/items.csv\",\n).set_index(\"item_nbr\")\n\ndf_2017 = df_train[df_train.date.isin(\n    pd.date_range(\"2017-05-31\", periods=7 * 11))].copy()\ndel df_train\n\npromo_2017_train = df_2017.set_index(\n    [\"store_nbr\", \"item_nbr\", \"date\"])[[\"onpromotion\"]].unstack(\n        level=-1).fillna(False)\npromo_2017_train.columns = promo_2017_train.columns.get_level_values(1)\npromo_2017_test = df_test[[\"onpromotion\"]].unstack(level=-1).fillna(False)\npromo_2017_test.columns = promo_2017_test.columns.get_level_values(1)\npromo_2017_test = promo_2017_test.reindex(promo_2017_train.index).fillna(False)\npromo_2017 = pd.concat([promo_2017_train, promo_2017_test], axis=1)\ndel promo_2017_test, promo_2017_train\n\ndf_2017 = df_2017.set_index(\n    [\"store_nbr\", \"item_nbr\", \"date\"])[[\"unit_sales\"]].unstack(\n        level=-1).fillna(0)\ndf_2017.columns = df_2017.columns.get_level_values(1)\n\nitems = items.reindex(df_2017.index.get_level_values(1))\n\ndef get_timespan(df, dt, minus, periods):\n    return df[\n        pd.date_range(dt - timedelta(days=minus), periods=periods)\n    ]\n\ndef prepare_dataset(t2017, is_train=True):\n    X = pd.DataFrame({\n        \"mean_3_2017\": get_timespan(df_2017, t2017, 3, 3).mean(axis=1).values,\n        \"mean_7_2017\": get_timespan(df_2017, t2017, 7, 7).mean(axis=1).values,\n        \"mean_14_2017\": get_timespan(df_2017, t2017, 14, 14).mean(axis=1).values,\n        \"promo_14_2017\": get_timespan(promo_2017, t2017, 14, 14).sum(axis=1).values\n    })\n    for i in range(16):\n        X[\"promo_{}\".format(i)] = promo_2017[\n            t2017 + timedelta(days=i)].values.astype(np.uint8)\n    if is_train:\n        y = df_2017[\n            pd.date_range(t2017, periods=16)\n        ].values\n        return X, y\n    return X\n\nprint(\"Preparing dataset...\")\nt2017 = date(2017, 6, 21)\nX_l, y_l = [], []\nfor i in range(4):\n    delta = timedelta(days=7 * i)\n    X_tmp, y_tmp = prepare_dataset(\n        t2017 + delta\n    )\n    X_l.append(X_tmp)\n    y_l.append(y_tmp)\nX_train = pd.concat(X_l, axis=0)\ny_train = np.concatenate(y_l, axis=0)\ndel X_l, y_l\nX_val, y_val = prepare_dataset(date(2017, 7, 26))\nX_test = prepare_dataset(date(2017, 8, 16), is_train=False)\n\nprint(\"Training and predicting models...\")\nparams = {\n    'num_leaves': 2**5 - 1, # max number of leaves in a tree\n    'objective': 'regression_l2', # loss function\n    'max_depth': 8, # max depth of a tree, max distance between a leaf and the roof\n    'min_data_in_leaf': 50, # per leaf, there can be 50 samples\n    'learning_rate': 0.05, # shrinkage rate\n    'feature_fraction': 0.75, # takes 75% of features\n    'bagging_fraction': 0.75, # takes 75% of data samples\n    'bagging_freq': 1, # running bagging every k iterations, 1 means always bagging\n    'metric': 'l2', # evaluation metric\n    'num_threads': 4 # for performance\n}\n\nMAX_ROUNDS = 1000\nval_pred = []\ntest_pred = []\ncate_vars = [] # possible categories\nfor i in range(16): # trained 16 models?\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\"]] * 4) * 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=50, verbose_eval=50\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))\n\nprint(\"Validation mse:\", mean_squared_error(\n    y_val, np.array(val_pred).transpose()))\n\nprint(\"Making submission...\")\ny_test = np.array(test_pred).transpose()\ndf_preds = pd.DataFrame(\n    y_test, index=df_2017.index,\n    columns=pd.date_range(\"2017-08-16\", periods=16)\n).stack().to_frame(\"unit_sales\")\ndf_preds.index.set_names([\"store_nbr\", \"item_nbr\", \"date\"], inplace=True)\n\nsubmission = df_test[[\"id\"]].join(df_preds, how=\"left\").fillna(0)\nsubmission[\"unit_sales\"] = np.clip(np.expm1(submission[\"unit_sales\"]), 0, 1000)\nsubmission.to_csv('lgb.csv', float_format='%.4f', index=None)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}