{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "convenient-practitioner",
   "metadata": {},
   "outputs": [],
   "source": [
    "#default_exp data.datasets.gefcom2012"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "chubby-cabinet",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style> table {float:left} </style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%%html\n",
    "<style> table {float:left} </style>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cooked-spending",
   "metadata": {},
   "source": [
    "# GEFCom2012\n",
    "\n",
    "> Download the GEFCom2012 dataset.\n",
    "\n",
    "[Tao Hong, Pierre Pinson, Shu Fan, \"Global Energy Forecasting Competition 2012\", International Journal of Forecasting, Volume 30, Issue 2, 2014.](https://www.sciencedirect.com/science/article/pii/S0169207013000745)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "latin-projector",
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "import os\n",
    "import re\n",
    "import logging\n",
    "import zipfile\n",
    "\n",
    "from dataclasses import dataclass\n",
    "from typing import Dict, List, Optional, Tuple, Union\n",
    "from pandas.tseries.holiday import USFederalHolidayCalendar as calendar\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "from nixtlats.data.datasets.utils import (\n",
    "    download_file, \n",
    "    Info, \n",
    "    TimeSeriesDataclass,\n",
    "    create_calendar_variables,\n",
    "    create_us_holiday_distance_variables,\n",
    ")\n",
    "from nixtlats.data.tsdataset import TimeSeriesDataset\n",
    "\n",
    "logging.basicConfig(level=logging.INFO)\n",
    "logger = logging.getLogger(__name__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "yellow-exclusive",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "from matplotlib import rcParams\n",
    "plt.rcParams['font.family'] = 'serif'\n",
    "FONTSIZE = 22"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "viral-photograph",
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class GEFCom2012:\n",
    "    \n",
    "    source_url = 'https://www.dropbox.com/s/epj9b57eivn79j7/GEFCom2012.zip?dl=1'\n",
    "        \n",
    "    @staticmethod\n",
    "    def download(directory: str) -> None:\n",
    "        \"\"\"Downloads GEFCom2012 Dataset.\"\"\"\n",
    "        path = f'{directory}/gefcom2012'\n",
    "        if not os.path.exists(path):\n",
    "            download_file(directory=path, \n",
    "                          source_url=GEFCom2012.source_url,\n",
    "                          decompress=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "beginning-artwork",
   "metadata": {},
   "source": [
    "# GEFCom2012-L\n",
    "\n",
    "The GEFCom2012-L dataset was made available as part of a [kaggle competition](https://www.kaggle.com/c/global-energy-forecasting-competition-2012-load-forecasting). \n",
    "\n",
    "The competition asked for the creation of hierarchical forecasts for 20 zones and the system. For this purpose the sum of zonal loads should be equal to the system load. The evaluation metric was the Weighted Root Mean Square Error (WRMSE).\n",
    "\n",
    "The task was to provide two day ahead hourly forecasts for the power generation of seven wind farms. The dataset contains:\n",
    "- Hourly electricity load history for twenty zones from 2004-01-01 to 2008-06-30 for train.\n",
    "- Hourly temperature history for eleven weather stations from 2004-01-01 to 2008-06-30 for train.\n",
    "- List of US holidays.\n",
    "- Hourly forecast benchmark from 2008-07-01 to 2008-07-07 with evaluation weights.\n",
    "- Hourly electricity load test history for twenty zones from 2011-01-01 to 2012-07-07."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "western-wesley",
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class GEFCom2012_L:\n",
    "    \n",
    "    @staticmethod\n",
    "    def load_Y(directory) -> pd.DataFrame:\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Load'\n",
    "        filepath = f'{path}/Load_history.csv'\n",
    "        Y_df = pd.read_csv(filepath, sep=',', thousands=',')\n",
    "\n",
    "        # Parsing temperature data\n",
    "        Y_df['ds'] = pd.to_datetime(dict(year=Y_df.year, \n",
    "                                         month=Y_df.month, \n",
    "                                         day=Y_df.day))\n",
    "        del Y_df['year'], Y_df['month'], Y_df['day']\n",
    "        Y_df = pd.wide_to_long(Y_df, ['h'], i=['zone_id', 'ds'], j=\"hour\")\n",
    "        Y_df.reset_index(inplace=True)\n",
    "        Y_df['tdelta']   = pd.to_timedelta(Y_df.hour, unit=\"h\")\n",
    "        Y_df['ds']       = Y_df['ds'] + Y_df['tdelta']\n",
    "        del Y_df['tdelta'], Y_df['hour']\n",
    "        Y_df.rename(columns={'zone_id': 'unique_id', 'h': 'y'}, inplace=True)\n",
    "        #Y_df['y'] = pd.to_numeric(Y_df['y'], errors='coerce')\n",
    "        return Y_df\n",
    "    \n",
    "    @staticmethod\n",
    "    def load_X(directory) -> pd.DataFrame:\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Load'\n",
    "        filepath = f'{path}/temperature_history.csv'\n",
    "        X_df = pd.read_csv(filepath, sep=',')\n",
    "\n",
    "        # Parsing temperature data\n",
    "        X_df['ds'] = pd.to_datetime(dict(year=X_df.year, \n",
    "                                         month=X_df.month, \n",
    "                                         day=X_df.day))\n",
    "        del X_df['year'], X_df['month'], X_df['day']\n",
    "        X_df = pd.wide_to_long(X_df, ['h'], i=['station_id', 'ds'], j=\"hour\")\n",
    "        X_df.reset_index(inplace=True)\n",
    "        X_df['tdelta']   = pd.to_timedelta(X_df.hour, unit=\"h\")\n",
    "        X_df['ds']       = X_df['ds'] + X_df['tdelta']\n",
    "        del X_df['tdelta'], X_df['hour']\n",
    "        X_df['station_id'] = 'station_' + X_df['station_id'].astype(str)\n",
    "\n",
    "        X_df = X_df.pivot(index='ds', columns='station_id', values='h').reset_index('ds')\n",
    "        X_df.reset_index(drop=True, inplace=True)\n",
    "        X_df = create_calendar_variables(X_df=X_df)\n",
    "        X_df = create_us_holiday_distance_variables(X_df=X_df)        \n",
    "        return X_df\n",
    "    \n",
    "    @staticmethod\n",
    "    def load_benchmark(directory) -> pd.DataFrame:\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Load'\n",
    "        filepath = f'{path}/Load_benchmark.csv'\n",
    "        benchmark_df = pd.read_csv(filepath, sep=',')\n",
    "        \n",
    "        # Parsing benchmark data\n",
    "        benchmark_df['ds'] = pd.to_datetime(dict(year=benchmark_df.year, \n",
    "                                                 month=benchmark_df.month, \n",
    "                                                 day=benchmark_df.day))\n",
    "        del benchmark_df['year'], benchmark_df['month'], benchmark_df['day'], benchmark_df['id']\n",
    "        benchmark_df.rename(columns={'zone_id': 'unique_id'}, inplace=True)\n",
    "\n",
    "        benchmark_df = pd.wide_to_long(benchmark_df, ['h'], i=['unique_id', 'ds'], j=\"hour\")\n",
    "        benchmark_df.reset_index(inplace=True)\n",
    "\n",
    "        benchmark_df['tdelta']   = pd.to_timedelta(benchmark_df.hour, unit=\"h\")\n",
    "        benchmark_df['ds']       = benchmark_df['ds'] + benchmark_df['tdelta']\n",
    "        del benchmark_df['tdelta'], benchmark_df['hour']\n",
    "        benchmark_df.rename(columns={'h': 'y_hat'}, inplace=True)\n",
    "        return benchmark_df\n",
    "    \n",
    "    @staticmethod\n",
    "    def load(directory) -> Tuple[pd.DataFrame,\n",
    "                                 pd.DataFrame,\n",
    "                                 pd.DataFrame]:\n",
    "        \n",
    "        GEFCom2012.download(directory)\n",
    "        \n",
    "        Y_df = GEFCom2012_L.load_Y(directory)\n",
    "        X_df = GEFCom2012_L.load_X(directory)\n",
    "        benchmark_df = GEFCom2012_L.load_benchmark(directory)\n",
    "        return Y_df, X_df, benchmark_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "suspended-motorcycle",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 11.6M/11.6M [00:00<00:00, 14.1MiB/s]\n",
      "INFO:nixtla.data.datasets.utils:Successfully downloaded GEFCom2012.zip?dl=1, 11630887, bytes.\n",
      "INFO:nixtla.data.datasets.utils:Decompressing zip file...\n",
      "INFO:nixtla.data.datasets.utils:Successfully decompressed data/gefcom2012/GEFCom2012.zip?dl=1\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>unique_id</th>\n",
       "      <th>ds</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>2004-01-01 01:00:00</td>\n",
       "      <td>16853.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2004-01-01 02:00:00</td>\n",
       "      <td>16450.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>2004-01-01 03:00:00</td>\n",
       "      <td>16517.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>2004-01-01 04:00:00</td>\n",
       "      <td>16873.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1</td>\n",
       "      <td>2004-01-01 05:00:00</td>\n",
       "      <td>17064.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   unique_id                  ds        y\n",
       "0          1 2004-01-01 01:00:00  16853.0\n",
       "1          1 2004-01-01 02:00:00  16450.0\n",
       "2          1 2004-01-01 03:00:00  16517.0\n",
       "3          1 2004-01-01 04:00:00  16873.0\n",
       "4          1 2004-01-01 05:00:00  17064.0"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y_df, X_df, benchmark_df = GEFCom2012_L.load('data')\n",
    "Y_df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "economic-syntax",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 57344 characters]\n",
      "text/plain": [
       "<Figure size 1440x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "Y_df, X_df, benchmark_df = GEFCom2012_L.load(directory='data')\n",
    "Y_df = Y_df[Y_df.unique_id==1]\n",
    "\n",
    "ds = Y_df.ds.values[-365:]\n",
    "y_true = Y_df.y.values[-365:]\n",
    "\n",
    "x_plot = Y_df.ds.values\n",
    "x_plot_min = pd.to_datetime(x_plot.min()).strftime('%B %d, %Y')\n",
    "x_plot_max = pd.to_datetime(x_plot.max()).strftime('%B %d, %Y')\n",
    "x_axis_str = f'Hours [{x_plot_min}  to  {x_plot_max}]'\n",
    "y_axis_str = 'Load (MW)'\n",
    "\n",
    "fig = plt.figure(figsize=(20, 4))\n",
    "fig.tight_layout()\n",
    "ax0 = plt.subplot2grid((1,1),(0, 0))\n",
    "axs = [ax0]\n",
    "\n",
    "axs[0].plot(ds, y_true, color='#628793', linewidth=0.4, label='true')\n",
    "axs[0].tick_params(labelsize=FONTSIZE-4)\n",
    "axs[0].set_xlabel(x_axis_str, fontsize=FONTSIZE)\n",
    "axs[0].set_ylabel(y_axis_str, fontsize=FONTSIZE)\n",
    "plt.title('GEFCom2012-W Zone=1', fontsize=FONTSIZE)\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "crazy-developer",
   "metadata": {},
   "source": [
    "# GEFCom2012-W\n",
    "\n",
    "The GEFCom2012-W dataset was made available as part of a [kaggle competition](https://www.kaggle.com/c/GEF2012-wind-forecasting/overview).\n",
    "\n",
    "The task was to provide two day ahead hourly forecasts for the power generation of seven wind farms. The dataset contains:\n",
    "- Hourly wind power history for the seven farms from 2009-07-01 to 2010-12-31 for train.\n",
    "- Two days ahead wind forecasts for the seven farms from 2009-07-01 to 2012-06-26 for train.\n",
    "- Hourly wind power history for the seven farms from 2011-01-01 to 2012-06-28 for test.\n",
    "- Naive forecast benchmark from 2011-01-01 to 2012-06-28."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "endless-roman",
   "metadata": {},
   "outputs": [],
   "source": [
    "#export\n",
    "class GEFCom2012_W:\n",
    "    \n",
    "    train_start = '2009-07-01 00:00:00'\n",
    "    train_end   = '2010-12-31 23:00:00'\n",
    "        \n",
    "    test_start  = '2011-01-01 01:00:00'\n",
    "    test_end    = '2012-06-28 12:00:00'\n",
    "    \n",
    "    @staticmethod\n",
    "    def load_benchmark(directory):\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Wind'\n",
    "        filepath = f'{path}/benchmark.csv'\n",
    "        benchmark_df = pd.read_csv(filepath, sep=',')\n",
    "\n",
    "        benchmark_df['ds'] = pd.to_datetime(benchmark_df.date, format='%Y%m%d%H')\n",
    "        del benchmark_df['date']\n",
    "        benchmark_df = pd.wide_to_long(benchmark_df, ['wp'], i='ds', j=\"unique_id\")\n",
    "        benchmark_df.reset_index(inplace=True)\n",
    "        return benchmark_df    \n",
    "    \n",
    "    @staticmethod\n",
    "    def load_Y(directory):\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Wind'\n",
    "        yfilepath = f'{path}/train.csv'\n",
    "\n",
    "        # Read and parse Y data\n",
    "        Y_df = pd.read_csv(yfilepath, sep='\\t')\n",
    "        Y_df['ds'] = pd.date_range(start=GEFCom2012_W.train_start,\n",
    "                                   end=GEFCom2012_W.train_end, freq='H')\n",
    "        del Y_df['date']\n",
    "        Y_df = pd.wide_to_long(Y_df, ['wp'], i='ds', j=\"unique_id\")\n",
    "        Y_df.reset_index(inplace=True)\n",
    "        return Y_df\n",
    "    \n",
    "    @staticmethod\n",
    "    def load_X_group(directory, group):\n",
    "        # Meta data\n",
    "        path = f'{directory}/gefcom2012/GEFCOM2012_Data/Wind'\n",
    "        xfilepath = f'{path}/windforecasts_wf{group}.csv'\n",
    "        X_df = pd.read_csv(xfilepath, sep=',')\n",
    "\n",
    "        # Create ds associated to each forecast from forecast creation date\n",
    "        X_df['date']     = X_df.date.astype(str)\n",
    "        X_df['fcd']      = pd.to_datetime(X_df.date, format='%Y%m%d%H')\n",
    "        X_df['tdelta']   = pd.to_timedelta(X_df.hors, unit=\"h\")\n",
    "        X_df['ds']       = X_df['fcd'] + X_df['tdelta']\n",
    "\n",
    "        # Separate forecasts by lead time\n",
    "        X_lead12_df = X_df[(X_df.hors>0)  & (X_df.hors<=12)].reset_index(drop=True)\n",
    "        X_lead24_df = X_df[(X_df.hors>12) & (X_df.hors<=24)].reset_index(drop=True)\n",
    "        X_lead36_df = X_df[(X_df.hors>24) & (X_df.hors<=36)].reset_index(drop=True)\n",
    "        X_lead48_df = X_df[(X_df.hors>36) & (X_df.hors<=48)].reset_index(drop=True)\n",
    "        del X_df\n",
    "\n",
    "        # Cleaning auxiliary variables and reconstructing X_df\n",
    "        X_df = pd.DataFrame({'ds': pd.date_range(start='2009-07-01 01:00:00',\n",
    "                                                 end=GEFCom2012_W.test_end, freq='H')})\n",
    "        for lead, df in zip(['_lead12', '_lead24', '_lead36', '_lead48'], \\\n",
    "                            [X_lead12_df, X_lead24_df, X_lead36_df, X_lead48_df]):\n",
    "            df.drop(['fcd', 'tdelta', 'date', 'hors'], axis=1, inplace=True)\n",
    "            df.columns = [f'u{lead}', f'v{lead}', f'ws{lead}', f'wd{lead}', 'ds'] \n",
    "            X_df = X_df.merge(df, on='ds', how='left')\n",
    "\n",
    "        # Removing nans in hierarchical fashion (priority to shorter lead forecasts)\n",
    "        for var in ['u', 'v', 'ws', 'wd']:\n",
    "            X_df[var] = X_df[f'{var}_lead12']\n",
    "            for lead in ['_lead24', '_lead36', '_lead48']:\n",
    "                X_df[var].fillna(X_df[f'{var}{lead}'], inplace=True)\n",
    "\n",
    "        for var in ['u', 'v', 'ws', 'wd']:\n",
    "            for lead in ['_lead12', '_lead24', '_lead36', '_lead48']:\n",
    "                X_df[f'{var}{lead}'].fillna(X_df[var], inplace=True)\n",
    "            del X_df[var]\n",
    "        del X_lead12_df, X_lead24_df, X_lead36_df, X_lead48_df\n",
    "        X_df['unique_id'] = group\n",
    "        return X_df\n",
    "    \n",
    "    @staticmethod\n",
    "    def load(directory: str) -> Tuple[pd.DataFrame,\n",
    "                                      pd.DataFrame,\n",
    "                                      pd.DataFrame]:\n",
    "        GEFCom2012.download(directory)\n",
    "        \n",
    "        Y_df = GEFCom2012_W.load_Y(directory)\n",
    "        X_df_list = [GEFCom2012_W.load_X_group(directory, group) for group in range(1,8)]\n",
    "        X_df = pd.concat(X_df_list)\n",
    "        \n",
    "        benchmark_df = GEFCom2012_W.load_benchmark(directory)\n",
    "        return Y_df, X_df, benchmark_df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "conditional-vegetarian",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 97368 characters]\n",
      "text/plain": [
       "<Figure size 1080x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "Y_df, X_df, benchmark_df = GEFCom2012_W.load(directory='data')\n",
    "Y_df = Y_df[:168]\n",
    "X_df = X_df[:168]\n",
    "\n",
    "fig = plt.figure(figsize=(15, 4))\n",
    "\n",
    "x_plot = Y_df.ds.values\n",
    "x_plot_min = pd.to_datetime(x_plot.min()).strftime('%B %d, %Y')\n",
    "x_plot_max = pd.to_datetime(x_plot.max()).strftime('%B %d, %Y')\n",
    "x_axis_str = f'Hours [{x_plot_min}  to  {x_plot_max}]'\n",
    "y_axis_str = 'U Wind Component'\n",
    "\n",
    "plt.plot(x_plot, X_df.u_lead12, label='12 lead')\n",
    "plt.plot(x_plot, X_df.u_lead24, label='24 lead')\n",
    "plt.plot(x_plot, X_df.u_lead36, label='36 lead')\n",
    "plt.plot(x_plot, X_df.u_lead48, label='48 lead')\n",
    "plt.xlabel(x_axis_str, fontsize=FONTSIZE)\n",
    "plt.ylabel(y_axis_str, fontsize=FONTSIZE)\n",
    "plt.title('GEFCom2014-W', fontsize=FONTSIZE)\n",
    "plt.legend()\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "overhead-glucose",
   "metadata": {},
   "source": [
    "# GEFCom2012-W references\n",
    "Forecasting Method                                                                                | 48H ahead RMSE\n",
    ":-----------------------------------------------------------------------------------------------: | :-------: \n",
    "[ALL-CF](https://ieeexplore.ieee.org/abstract/document/7497013) [3]                               | 0.14564   | \n",
    "[GBM + K-Means + LR](https://www.sciencedirect.com/science/article/abs/pii/S0169207013000836) [2] | 0.14567   |\n",
    "[KNN](https://www.sciencedirect.com/science/article/abs/pii/S0169207013000848) [1]                | 0.1472    |\n",
    "[SGCRF](https://ieeexplore.ieee.org/abstract/document/6760016/) [4]                               | 0.1488    |\n",
    "[LSBRT](https://ieeexplore.ieee.org/abstract/document/7579134/) [5]                               | 0.1518    | \n",
    "[SDAE-m-m](https://ieeexplore.ieee.org/abstract/document/8240639) [6]                             | 0.154     | \n",
    "[S-GP-ENV](https://ieeexplore.ieee.org/abstract/document/7812215) [7]                             | 0.1604    | \n",
    "[GP + NN](https://ieeexplore.ieee.org/abstract/document/6606922/)[8]                              | 0.1752    |\n",
    "Naive Forecast                                                                                    | 0.361     |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "enclosed-effectiveness",
   "metadata": {},
   "source": [
    "1.\t[Mangalova E, Agafonov E. Wind power forecasting using the k-nearest neighbors algorithm. International Journal of Forecasting. 2014; 30:402-406](https://www.sciencedirect.com/science/article/abs/pii/S0169207013000848).\n",
    "2.\t[Silva L. A feature engineering approach to wind power forecasting: GEFCom 2012. International Journal of Forecasting. 2014; 30:395-401](https://www.sciencedirect.com/science/article/abs/pii/S0169207013000836).\n",
    "3.\t[Fang S, Chiang H. A high-accuracy wind power forecasting model. IEEE Transactions on Power Systems. 2016; 32:1589-1590](https://ieeexplore.ieee.org/abstract/document/7497013).\n",
    "4.\t[Wytock M, Kolter Z, \"Large-scale probabilistic forecasting in energy systems using sparse gaussian conditional random fields,\" in 52nd IEEE Conference on Decision and Control, (IEEE, 2013), pp. 1019-1024](https://ieeexplore.ieee.org/abstract/document/6760016/).\n",
    "5.\t[Li G, Chiang H. Toward cost-oriented forecasting of wind power generation. IEEE Transactions on Smart Grid. 2016;9:2508-2517](https://ieeexplore.ieee.org/abstract/document/7579134/).\n",
    "6.\t[Yan J, Zhang H, Liu Y, Han S, Li L, Lu Z. Forecasting the high penetration of wind power on multiple scales using multi-to-multi mapping. IEEE Transactions on Power Systems. 2018;33:3276-3284](https://ieeexplore.ieee.org/abstract/document/8240639).\n",
    "7.\t[Fang S, Chiang H. Improving supervised wind power forecasting models using extended numerical weather variables and unlabelled data. IET Renewable Power Generation. 2016;10:1616-1624](https://ieeexplore.ieee.org/abstract/document/7812215).\n",
    "8.\t[Lee D, Baldick R. Short-term wind power ensemble prediction based on Gaussian processes and neural networks. IEEE Transactions on Smart Grid. 2013;5:501-510](https://ieeexplore.ieee.org/abstract/document/6606922/).\n",
    "9.\t[Landry M, Erlinger TP, Patschke D, Varrichio C. Probabilistic gradient boosting machines for GEFCom2014 wind forecasting. International Journal of Forecasting. 2016; 32:1061-1066.](https://www.sciencedirect.com/science/article/pii/S0169207016000145)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
