{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":7391,"databundleVersionId":44328,"sourceType":"competition"}],"dockerImageVersionId":30587,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# %% [code]\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\ndf_train = pd.read_csv(\n    '../input/train.csv', 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,\n    'objective': 'regression_l2',\n    'max_depth': 8,\n    'min_data_in_leaf': 50,\n    'learning_rate': 0.05,\n    'feature_fraction': 0.75,\n    'bagging_fraction': 0.75,\n    'bagging_freq': 1,\n    'metric': 'l2',\n    'num_threads': 4\n}\n\nMAX_ROUNDS = 1000\nval_pred = []\ntest_pred = []\ncate_vars = []\nfor 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\"]] * 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)\n","metadata":{"_uuid":"ee7feaa5-0348-4955-9c6a-7128dae408a5","_cell_guid":"a8eef0e3-bf2d-4658-9e9d-74fc056cff7d","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2023-11-28T20:08:50.019977Z","iopub.execute_input":"2023-11-28T20:08:50.020487Z","iopub.status.idle":"2023-11-28T20:08:59.923652Z","shell.execute_reply.started":"2023-11-28T20:08:50.020447Z","shell.execute_reply":"2023-11-28T20:08:59.921177Z"},"trusted":true},"execution_count":null,"outputs":[]}]}