{"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":30822,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:25:59.543086Z","iopub.execute_input":"2025-01-17T14:25:59.543523Z","iopub.status.idle":"2025-01-17T14:26:02.056883Z","shell.execute_reply.started":"2025-01-17T14:25:59.543486Z","shell.execute_reply":"2025-01-17T14:26:02.055808Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\n\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\npaths = []\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n        paths.append(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:26:02.058328Z","iopub.execute_input":"2025-01-17T14:26:02.058826Z","iopub.status.idle":"2025-01-17T14:26:02.068882Z","shell.execute_reply.started":"2025-01-17T14:26:02.058788Z","shell.execute_reply":"2025-01-17T14:26:02.067585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:26:05.901580Z","iopub.execute_input":"2025-01-17T14:26:05.901979Z","iopub.status.idle":"2025-01-17T14:26:20.674934Z","shell.execute_reply.started":"2025-01-17T14:26:05.901952Z","shell.execute_reply":"2025-01-17T14:26:20.673466Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import py7zr\nfor filenames in paths:\n    with py7zr.SevenZipFile(filenames, mode='r') as z_ref:\n        z_ref.extractall(path='/kaggle/working')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:02:37.026615Z","iopub.execute_input":"2025-01-17T14:02:37.027104Z","iopub.status.idle":"2025-01-17T14:04:05.852262Z","shell.execute_reply.started":"2025-01-17T14:02:37.027052Z","shell.execute_reply":"2025-01-17T14:04:05.851028Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Corporación Favorita Grocery Sales Forecasting\n\nPlease read data description: https://www.kaggle.com/c/favorita-grocery-sales-forecasting","metadata":{}},{"cell_type":"markdown","source":"## Splitting Data into Training and Test Sets\nThe data you are working with splited into **training** and **test** sets and stored in the following files:\n\n- **`/kaggle/working/train_data.csv`** – the training dataset used for model training.\n- **`/kaggle/working/test_data.csv`** – the test dataset used to evaluate the model's performance.","metadata":{}},{"cell_type":"code","source":"%%time\ndata = pd.read_csv(\"/kaggle/working/train.csv\")\ndata[\"date\"] =  pd.to_datetime(data[\"date\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:26:20.676963Z","iopub.execute_input":"2025-01-17T14:26:20.678901Z","iopub.status.idle":"2025-01-17T14:28:42.122747Z","shell.execute_reply.started":"2025-01-17T14:26:20.678757Z","shell.execute_reply":"2025-01-17T14:28:42.121532Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monthly_counts_data = data['date'].dt.to_period('M').value_counts().sort_index()\n\nplt.figure(figsize=(12, 6))\nmonthly_counts_data.plot(kind='bar', color='skyblue')\nplt.title('Count of Data for Each Month for All data', fontsize=14)\nplt.xlabel('Month', fontsize=12)\nplt.ylabel('Count', fontsize=12)\nplt.xticks(rotation=45)\nplt.grid(axis='y', linestyle='--', alpha=0.7)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:05:44.812047Z","iopub.execute_input":"2025-01-17T14:05:44.812512Z","iopub.status.idle":"2025-01-17T14:05:52.398756Z","shell.execute_reply.started":"2025-01-17T14:05:44.812478Z","shell.execute_reply":"2025-01-17T14:05:52.397642Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\nTHRESHOLD_TRAIN_DATE = pd.to_datetime(\"2017-07-01\")\nTHRESHOLD_TEST_DATE = pd.to_datetime(\"2017-08-01\")\n\ndata[data[\"date\"] < THRESHOLD_TRAIN_DATE].to_csv(\"/kaggle/working/train_data.csv\")\ndata[(data[\"date\"] >= THRESHOLD_TRAIN_DATE)&(data[\"date\"] < THRESHOLD_TEST_DATE)].to_csv(\"/kaggle/working/test_data.csv\")\n\n%xdel data","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:28:42.125118Z","iopub.execute_input":"2025-01-17T14:28:42.125484Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\ndf = pd.read_csv(\"/kaggle/working/train_data.csv\")\ntest_df = pd.read_csv(\"/kaggle/working/test_data.csv\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df[\"date\"] = pd.to_datetime(df[\"date\"])\ntest_df[\"date\"] = pd.to_datetime(test_df[\"date\"])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monthly_counts = df['date'].dt.to_period('M').value_counts().sort_index().reset_index()\nmonthly_counts_test = test_df['date'].dt.to_period('M').value_counts().sort_index().reset_index()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"monthly_counts['type'] = 'Train'\nmonthly_counts_test['type'] = 'Test'\ncombined = pd.concat([monthly_counts, monthly_counts_test])\n\nplt.figure(figsize=(12, 6))\nsns.barplot(data=combined, x='date', y='count', hue='type', palette=['blue', 'red'])\nplt.title('Count of Data for Each Month (Train vs Test)', fontsize=14)\nplt.xlabel('Month', fontsize=12)\nplt.ylabel('Count', fontsize=12)\nplt.xticks(rotation=45)\nplt.legend(title='Dataset')\nplt.grid(axis='y', linestyle='--', alpha=0.7)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:27.811230Z","iopub.execute_input":"2025-01-17T14:15:27.811648Z","iopub.status.idle":"2025-01-17T14:15:29.191139Z","shell.execute_reply.started":"2025-01-17T14:15:27.811608Z","shell.execute_reply":"2025-01-17T14:15:29.189554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:29.192761Z","iopub.execute_input":"2025-01-17T14:15:29.193185Z","iopub.status.idle":"2025-01-17T14:15:29.212915Z","shell.execute_reply.started":"2025-01-17T14:15:29.193145Z","shell.execute_reply":"2025-01-17T14:15:29.211506Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Additional Data\n\n\nTo make more effective use of the data, you also have access to several auxiliary datasets containing contextual information:\n\n#### 1. **`holidays_events.csv`**\n   - **Description**:\n     Contains information about holidays and events that may influence sales.\n   - **Useful Columns**:\n     - `date`: The date of the holiday or event.\n     - `type`: The type of event (national, regional, local).\n     - `locale`: The level of impact (national, regional, local).\n     - `description`: A description of the event.\n   - **How to Use**:\n     - Add a flag indicating whether a date is a holiday to the training and test sets.\n     - Categorize holidays by their `type` and consider their impact on sales.\n     - Use the `locale` column to analyze regional effects.","metadata":{"execution":{"iopub.status.busy":"2024-12-22T19:12:02.31896Z","iopub.execute_input":"2024-12-22T19:12:02.319553Z","iopub.status.idle":"2024-12-22T19:12:02.32548Z","shell.execute_reply.started":"2024-12-22T19:12:02.319516Z","shell.execute_reply":"2024-12-22T19:12:02.323891Z"}}},{"cell_type":"code","source":"holiday_events = pd.read_csv(\"/kaggle/working/holidays_events.csv\")\nprint(holiday_events.shape)\nholiday_events.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:29.214021Z","iopub.execute_input":"2025-01-17T14:15:29.214382Z","iopub.status.idle":"2025-01-17T14:15:29.237825Z","shell.execute_reply.started":"2025-01-17T14:15:29.214349Z","shell.execute_reply":"2025-01-17T14:15:29.236918Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 2. **`items.csv`**\n   - **Description**:\n     Contains information about the items being sold.\n   - **Useful Columns**:\n     - `item_nbr`: Unique identifier for each item.\n     - `family`: The category or family the item belongs to (e.g., \"Beverages\").\n     - `class`: A finer categorization of items.\n     - `perishable`: A binary indicator for whether the item is perishable (1 for perishable, 0 otherwise).\n   - **How to Use**:\n     - Use `family` and `class` to group items and analyze trends across categories.\n     - Include the `perishable` indicator to weight predictions for perishable items.","metadata":{}},{"cell_type":"code","source":"items = pd.read_csv(\"/kaggle/working/items.csv\")\nprint(items.shape)\nitems.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:29.238870Z","iopub.execute_input":"2025-01-17T14:15:29.239138Z","iopub.status.idle":"2025-01-17T14:15:29.267476Z","shell.execute_reply.started":"2025-01-17T14:15:29.239115Z","shell.execute_reply":"2025-01-17T14:15:29.266286Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 3. **`oil.csv`**\n   - **Description**:\n     Contains daily oil price data, which can serve as an external economic indicator.\n   - **Useful Columns**:\n     - `date`: The date corresponding to the oil price.\n     - `dcoilwtico`: The daily oil price.\n   - **How to Use**:\n     - Join this dataset with the training and test sets on the `date` column to include oil price as a feature.\n     - Analyze the correlation between oil price fluctuations and sales trends.","metadata":{}},{"cell_type":"code","source":"oil = pd.read_csv(\"/kaggle/working/oil.csv\")\nprint(oil.shape)\noil.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:29.268833Z","iopub.execute_input":"2025-01-17T14:15:29.269257Z","iopub.status.idle":"2025-01-17T14:15:29.290158Z","shell.execute_reply.started":"2025-01-17T14:15:29.269184Z","shell.execute_reply":"2025-01-17T14:15:29.288494Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### 4. **`stores.csv`**\n   - **Description**:\n     Contains information about the stores where items are sold.\n   - **Useful Columns**:\n     - `store_nbr`: Unique identifier for each store.\n     - `city`: The city where the store is located.\n     - `state`: The state where the store is located.\n     - `type`: The store type.\n     - `cluster`: A grouping of similar stores based on sales patterns.\n   - **How to Use**:\n     - Use `city` and `state` for regional analysis of sales trends.\n     - Incorporate `type` and `cluster` to identify patterns and group stores with similar behavior.\n","metadata":{}},{"cell_type":"code","source":"stores = pd.read_csv(\"/kaggle/working/stores.csv\")\nprint(stores.shape)\nstores.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-17T14:15:29.291390Z","iopub.execute_input":"2025-01-17T14:15:29.291698Z","iopub.status.idle":"2025-01-17T14:15:29.309142Z","shell.execute_reply.started":"2025-01-17T14:15:29.291658Z","shell.execute_reply":"2025-01-17T14:15:29.307827Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**[READ DATA DESCRIPTION CAREFULY](https://www.kaggle.com/competitions/favorita-grocery-sales-forecasting) !!!!** \n\n## Exploratory Data Analysis and Model Training\n\n### 1. Baseline Model\n- Consider which model would be suitable as `DummyModel` for this task, then create, train, and use its predictions as a baseline.\n\n### 2. Feature Engineering\n- Generate new features by incorporating data from additional datasets to enhance the model's predictive capabilities.\n\n### 3. Model Training and Optimization\n- Utilize advanced regression models, such as **LGBM Regression** or **CatBoost Regression**, to achieve the best results. Focus on hyperparameter tuning and evaluation metrics to optimize performance. **Use foremention Normalized Weighted Root Mean Squared Logarithmic Error**.  \n\n### Thats All :-)\n","metadata":{}},{"cell_type":"code","source":"from sklearn.dummy import DummyRegressor\ndummy_model = DummyRegressor(strategy=\"mean\")\nX_train = df.drop(columns=[\"unit_sales\", \"date\"]) \ny_train = df[\"unit_sales\"]\ndummy_model.fit(X_train, y_train)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_df = test_df.merge(items[['item_nbr', 'perishable']], on='item_nbr', how='left')\ntest_df['weight'] = test_df['perishable'].apply(lambda x: 1.25 if x == 1 else 1.00)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = test_df.drop(columns=[\"unit_sales\", \"date\"]) \ny_test = test_df[\"unit_sales\"]  \n\ny_pred = dummy_model.predict(X_test)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_test = np.maximum(y_test, 0)\nvalid_indices = y_test >= 0\ny_test = y_test[valid_indices]\ny_pred = y_pred[valid_indices]\ntest_df = test_df[valid_indices]\n\nlog_error = np.log(y_pred + 1) - np.log(y_test + 1)\nweighted_squared_error = test_df['weight'] * log_error ** 2\n\n# NWRMSLE calculation\nnwrmsle = np.sqrt(weighted_squared_error.sum() / test_df['weight'].sum())\nprint(f\"Baseline Model NWRMSLE: {nwrmsle}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"holidays = pd.read_csv(\"/kaggle/working/holidays_events.csv\")\nholidays['date'] = pd.to_datetime(holidays['date'])\n\ndf = df.merge(holidays[['date', 'type', 'locale']], on='date', how='left')\ntest_df = test_df.merge(holidays[['date', 'type', 'locale']], on='date', how='left')\n\ndf['holiday_flag'] = df['type'].notna().astype(int)\ntest_df['holiday_flag'] = test_df['type'].notna().astype(int)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"items = pd.read_csv(\"/kaggle/working/items.csv\")\ndf = df.merge(items[['item_nbr', 'family', 'class', 'perishable']], on='item_nbr', how='left')\ntest_df = test_df.merge(items[['item_nbr', 'family', 'class', 'perishable']], on='item_nbr', how='left')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"oil = pd.read_csv(\"/kaggle/working/oil.csv\")\noil['date'] = pd.to_datetime(oil['date'])\n\ndf = df.merge(oil[['date', 'dcoilwtico']], on='date', how='left')\ntest_df = test_df.merge(oil[['date', 'dcoilwtico']], on='date', how='left')\ndf['dcoilwtico'].fillna(method='ffill', inplace=True)\ntest_df['dcoilwtico'].fillna(method='ffill', inplace=True)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"stores = pd.read_csv(\"/kaggle/working/stores.csv\")\n\ndf = df.merge(stores, on='store_nbr', how='left')\ntest_df = test_df.merge(stores, on='store_nbr', how='left')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for dataset in [df, test_df]:\n    dataset['day_of_week'] = dataset['date'].dt.dayofweek\n    dataset['month'] = dataset['date'].dt.month\n    dataset['weekend_flag'] = (dataset['day_of_week'] >= 5).astype(int)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.to_csv(\"/kaggle/working/enhanced_train_data.csv\", index=False)\ntest_df.to_csv(\"/kaggle/working/enhanced_test_data.csv\", index=False)\n\nprint(\"Feature engineering complete! Datasets saved for training.\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ndf = pd.read_csv(\"/kaggle/working/enhanced_train_data.csv\")\ntest_df = pd.read_csv(\"/kaggle/working/enhanced_test_data.csv\")\n\nX = df.drop(columns=[\"unit_sales\", \"date\"])\ny = df[\"unit_sales\"]\n\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install lightgbm","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import lightgbm as lgb\nfrom sklearn.metrics import mean_squared_error\nimport numpy as np\n\n# Define dataset for LightGBM\ntrain_data = lgb.Dataset(X_train, label=y_train)\nval_data = lgb.Dataset(X_val, label=y_val, reference=train_data)\n\nparams = {\n    \"objective\": \"regression\",\n    \"metric\": \"rmse\",\n    \"learning_rate\": 0.05,\n    \"num_leaves\": 31,\n    \"min_data_in_leaf\": 20,\n    \"feature_fraction\": 0.8,\n    \"bagging_fraction\": 0.8,\n    \"bagging_freq\": 5,\n    \"verbose\": -1,\n}\n\nlgb_model = lgb.train(\n    params,\n    train_data,\n    valid_sets=[train_data, val_data],\n    num_boost_round=1000,\n    early_stopping_rounds=50,\n    verbose_eval=50,\n)\ny_pred_val = lgb_model.predict(X_val)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ny_pred_val = np.maximum(y_pred_val, 0)\n\nweights = test_df[\"weight\"].iloc[:len(y_pred_val)] \nlog_error = np.log1p(y_pred_val) - np.log1p(y_val)\nweighted_squared_error = weights * log_error**2\nnwrmsle = np.sqrt(weighted_squared_error.sum() / weights.sum())\n\nprint(f\"LGBM Model NWRMSLE: {nwrmsle}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install catboost","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from catboost import CatBoostRegressor\ncat_model = CatBoostRegressor(\n    iterations=1000,\n    learning_rate=0.05,\n    depth=6,\n    eval_metric=\"RMSE\",\n    early_stopping_rounds=50,\n    verbose=50,\n)\ncat_model.fit(X_train, y_train, eval_set=(X_val, y_val), use_best_model=True)\n\ny_pred_cat = cat_model.predict(X_val)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred_cat = np.maximum(y_pred_cat, 0)\nlog_error = np.log1p(y_pred_cat) - np.log1p(y_val)\nweighted_squared_error = weights * log_error**2\nnwrmsle_cat = np.sqrt(weighted_squared_error.sum() / weights.sum())\n\nprint(f\"CatBoost Model NWRMSLE: {nwrmsle_cat}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import optuna\n\ndef objective(trial):\n    params = {\n        \"objective\": \"regression\",\n        \"metric\": \"rmse\",\n        \"learning_rate\": trial.suggest_loguniform(\"learning_rate\", 0.01, 0.1),\n        \"num_leaves\": trial.suggest_int(\"num_leaves\", 20, 100),\n        \"feature_fraction\": trial.suggest_uniform(\"feature_fraction\", 0.6, 1.0),\n        \"bagging_fraction\": trial.suggest_uniform(\"bagging_fraction\", 0.6, 1.0),\n        \"bagging_freq\": trial.suggest_int(\"bagging_freq\", 1, 10),\n    }\n\n    lgb_model = lgb.train(\n        params,\n        train_data,\n        valid_sets=[val_data],\n        num_boost_round=1000,\n        early_stopping_rounds=50,\n        verbose_eval=False,\n    )\n    y_pred = lgb_model.predict(X_val)\n    y_pred = np.maximum(y_pred, 0)\n    log_error = np.log1p(y_pred) - np.log1p(y_val)\n    weighted_squared_error = weights * log_error**2\n    nwrmsle = np.sqrt(weighted_squared_error.sum() / weights.sum())\n    return nwrmsle\n\nstudy = optuna.create_study(direction=\"minimize\")\nstudy.optimize(objective, n_trials=50)\n\nprint(f\"Best parameters: {study.best_params}\")\nprint(f\"Best NWRMSLE: {study.best_value}\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test = test_df.drop(columns=[\"unit_sales\", \"date\"])\ny_test_pred = lgb_model.predict(X_test)\ny_test_pred = np.maximum(y_test_pred, 0)\n\nsubmission = pd.DataFrame({\"id\": test_df[\"id\"], \"unit_sales\": y_test_pred})\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)\nprint(\"Submission saved!\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}