# Sharing what helped

It was unfortunate that this competition was plagued by leaks, but it was pretty much a straight-forward energy forecasting problem. I learned a bit about time-series CV, which was my reason for joining. With that said, here are things that I’ve added to my approach. In retrospect, I could have data cleaned better with the non-electricity meters, but live and learn.
weather
Weather is known to be one of the strongest drivers of energy consumption. With that said, typical approaches have been to lag and/or shift weather. Recent literature on energy forecasting have explored exponential weighted moving averages; this helped my model extremely.
trend
Adding a trend feature in forecasting tends to usually help than not. In this case, I added one that mimicked the winning solutions from GEFCOM. Had there been more than one year of data, I would have included an intra-year trend as well.
2-phase CV
I replicated CPMP’s 2-phase for training and predicting.
Some things that I wished I tried:
- partially-escaping seasonality by developing models at different subsets of time; in my work, I develop models by hour. This helps to escape auto-correlation issues.
- data-clean: it was obvious the distributions for non-electricity were skewed due to 0 readings. I saw on the last night of competition that certain meters were 0 imputed while the corresponding day/time were missing in the electricity profile.
- hedge leaks better. I was torn with leveraging leaks because it took away the task of forecasting energy in a real-world setting; imagine trying to explain this method to a public utilities commission. My intent was to learn something to bring back to my job.
With that said, I was still happy with my approach in that most of the methods I used would have passed the PUC sniff test and it placed quite high on the leader board. Given the close spread of the RMSE towards the top, it was good to know that I didn't have to rely much on gimmicky methods to obtain a decent forecast. In this case, domain knowledge came in handy.
I also want to give a huge shout-out to
[@cpmpml](/cpmpml)
. I learned a lot from him over the years in regards to forecasting, and my successes in my job were stemmed from him. Also,
[@mmotoki](/mmotoki)
for pushing me to do better. I never appreciated what it meant to have a rival, but my successes on Kaggle wouldn’t have happened it it weren’t for him. he deserves number 1 given his crazy work ethics; thanks for teaching me to push myself.
UPDATE (for DietHard):
Nothing special:
```
holidays
from datetime import datetime, date, timedelta
from pandas.tseries.holiday import Holiday, AbstractHolidayCalendar, nearest_workday, MO, TU, WE, TH, FR
from pandas.tseries.holiday import USMartinLutherKingJr, USPresidentsDay, GoodFriday, USMemorialDay, USLaborDay, USThanksgivingDay
from pandas import DateOffset, Series, Timestamp, date_range
def daterange(date1, date2):
    for n in range(int ((date2 - date1).days)+1):
        yield date1 + timedelta(n)
class Holiday(AbstractHolidayCalendar):
    rules = [
        Holiday("New Year's Day -1", month=12, day=31),
        Holiday("New Year's Day", month=1, day=1),
USMartinLutherKingJr,
USPresidentsDay,
USMemorialDay,
Holiday('Independence Day', month=7, day=4, observance=nearest_workday),
    USLaborDay,
Holiday("Veteran's Day", month=11, day=11),
USThanksgivingDay,    
    Holiday("Christmas Eve", month=12, day=24),
    Holiday('Christmas', month=12, day=25, observance=nearest_workday),
    Holiday("Boxing Day", month=12, day=26),
]
def create_holidays(year_start, year_end):
cal = Holiday()
    holidays = []
    for i, year in enumerate(range(year_start, year_end+1)):
        # default holidays
        holiday_dates = cal.holidays(start=date(year,1,1), end=date(year,12,31))
        for holiday in holiday_dates:
            holidays.append(holiday.date())
    return holidays
holidays = create_holidays(2016, 2018)
df['is_holiday'] = df['timestamp'].isin(holidays) * 1
exponential weighted moving average
ewma = pd.Series.ewm
weather['air_temperature_ewma_day'] = ewma(weather['air_temperature'], span=24, adjust=True).mean()
weather['air_temperature_ewma_week'] = ewma(weather['air_temperature'], span=24*7, adjust=True).mean()
weather['air_temperature_ewma_month'] = ewma(weather['air_temperature'], span=24*30, adjust=True).mean()
time trend
time_trend = pd.DataFrame({'dt': pd.date_range(config['timeframe']['start'], config['timeframe']['end'], freq='H')})
time_trend['time_trend'] = time_trend["time_trend"] = range(0, 0+len(time_trend))
time_trend_dict = create_dictionary(time_trend["dt"], time_trend['time_trend'])
df['time_trend'] = df['timestamp'].map(time_trend_dict)
df['time_trend'] = df['time_trend'].astype(np.float16)
```