{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":true},"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 in\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport seaborn as sns\nfrom pandas.tseries.holiday import USFederalHolidayCalendar as calendar\nfrom sklearn.preprocessing import LabelEncoder\n\n# Input data files are available in the \"../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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# Just to ignore the unneccesary warnings\nimport sys        \nimport warnings\n\nif not sys.warnoptions:\n    warnings.simplefilter(\"ignore\")\n    \npath = '../input/ashrae-energy-prediction'\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n# unimportant features (see importance below)\nunimportant_cols = ['sea_level_pressure']\ntarget = 'meter_reading'\n\ndef load_data(source='train', path=path):\n    ''' load and merge all tables '''\n    assert source in ['train', 'test']\n    \n    building = pd.read_csv(f'{path}/building_metadata.csv', dtype={'building_id':np.uint16, 'site_id':np.uint8})\n    weather  = pd.read_csv(f'{path}/weather_{source}.csv', parse_dates=['timestamp'],\n                                                           dtype={'site_id':np.uint8, 'air_temperature':np.float16,\n                                                                  'cloud_coverage':np.float16, 'dew_temperature':np.float16,\n                                                                  'precip_depth_1_hr':np.float16},\n                                                           usecols=lambda c: c not in unimportant_cols)\n    df = pd.read_csv(f'{path}/{source}.csv', dtype={'building_id':np.uint16, 'meter':np.uint8}, parse_dates=['timestamp'])\n    df = df.merge(building, on='building_id', how='left')\n    df = df.merge(weather, on=['site_id', 'timestamp'], how='left')\n    return df\n\n# load and display some samples\ntrain = load_data('train')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntest = load_data('test')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # Code from https://www.kaggle.com/caesarlupum/ashrae-start-here-a-gentle-introduction\n# # Function to reduce the DF size\n\n# def reduce_mem_usage(df, verbose=True):\n#     numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']\n#     start_mem = df.memory_usage().sum() / 1024**2    \n#     for col in df.columns:\n#         col_type = df[col].dtypes\n#         if col_type in numerics:\n#             c_min = df[col].min()\n#             c_max = df[col].max()\n#             if str(col_type)[:3] == 'int':\n#                 if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:\n#                     df[col] = df[col].astype(np.int8)\n#                 elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:\n#                     df[col] = df[col].astype(np.int16)\n#                 elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:\n#                     df[col] = df[col].astype(np.int32)\n#                 elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:\n#                     df[col] = df[col].astype(np.int64)  \n#             else:\n#                 if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:\n#                     df[col] = df[col].astype(np.float16)\n#                 elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:\n#                     df[col] = df[col].astype(np.float32)\n#                 else:\n#                     df[col] = df[col].astype(np.float64)    \n#     end_mem = df.memory_usage().sum() / 1024**2\n#     if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.1f}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem))\n#     return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# def average_imputation(df, column_name):\n#     imputation = df.groupby(['timestamp'])[column_name].mean()\n    \n#     df.loc[df[column_name].isnull(), column_name] = df[df[column_name].isnull()][[column_name]].apply(lambda x: imputation[df['timestamp'][x.index]].values)\n#     del imputation\n#     return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-output":true},"cell_type":"code","source":"# average_imputation(train,'wind_speed')\n# average_imputation(train,'wind_direction')\n# average_imputation(train,'dew_temperature')\n# average_imputation(train,'air_temperature')\n# # average_imputation(train,'sea_level_pressure')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# average_imputation(test,'wind_speed')\n# average_imputation(test,'wind_direction')\n# average_imputation(test,'dew_temperature')\n# average_imputation(test,'air_temperature')\n# average_imputation(test,'sea_level_pressure')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Dropping all the columns for creating a baseline"},{"metadata":{"trusted":true},"cell_type":"code","source":"def drop_cols(data):\n    cols_to_drop = []\n    for col in data.columns:\n        if data[col].isna().any():\n            cols_to_drop.append(col)\n    return cols_to_drop\n\ncols_to_drop = drop_cols(train)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"%%time\ntrain = train.drop(cols_to_drop, axis = 1)\ntest = test.drop(cols_to_drop, axis = 1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Feature Engineering"},{"metadata":{"trusted":true},"cell_type":"code","source":"def timestamp_decomposition(df):\n    df['hour'] = np.uint8(df['timestamp'].dt.hour)\n    df['day'] = np.uint8(df['timestamp'].dt.day)\n    df['weekday'] = np.uint8(df['timestamp'].dt.weekday)\n    df['month'] = np.uint8(df['timestamp'].dt.month)\n    df['year'] = np.uint8(df['timestamp'].dt.year-1900)\n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = timestamp_decomposition(train)\ntest = timestamp_decomposition(test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# dates_range = pd.date_range(start='2015-12-31', end='2019-01-01')\n# us_holidays = calendar().holidays(start=dates_range.min(), end=dates_range.max())\n\n# train['is_holiday'] = (train['timestamp'].dt.date.astype('datetime64').isin(us_holidays))\n# test['is_holiday'] = (test['timestamp'].dt.date.astype('datetime64').isin(us_holidays))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### A common method for encoding cyclical data is to transform the data into two dimensions using a sine and consine transformation."},{"metadata":{"trusted":true},"cell_type":"code","source":"def encode_cyclic_feature(df, col, max_vals):\n    df[col + '_sin'] = np.sin(2 * np.pi * df[col]/max_vals)\n    df[col + '_cos'] = np.cos(2 * np.pi * df[col]/max_vals)\n    del df[col]\n    return df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = encode_cyclic_feature(train, 'weekday', 7)\ntrain = encode_cyclic_feature(train, 'hour', 24)\ntrain = encode_cyclic_feature(train, 'day', 31)\ntrain = encode_cyclic_feature(train, 'month', 12)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = encode_cyclic_feature(test, 'weekday', 7)\ntest = encode_cyclic_feature(test, 'hour', 24)\ntest = encode_cyclic_feature(test, 'day', 31)\ntest = encode_cyclic_feature(test, 'month', 12)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"le = LabelEncoder()\ntrain['primary_use'] = le.fit_transform(train['primary_use'])\ntest['primary_use'] = le.fit_transform(test['primary_use'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train['square_feet_log'] = np.log(train['square_feet'])\ntest['square_feet_log'] = np.log(test['square_feet'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"target = np.log1p(train[\"meter_reading\"])\ndel train['timestamp']\ndel train['meter_reading']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del test['row_id']\ndel test['timestamp']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"categorical_feats = ['building_id','meter','primary_use']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 4-Fold Cross-Validation LGBM Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import mean_squared_error\nimport lightgbm as lgb\nfrom sklearn.model_selection import KFold, StratifiedKFold\nfrom tqdm import tqdm\n\nparams = {\n            'boosting_type': 'gbdt',\n            'objective': 'regression',\n            'metric': {'rmse'},\n            'subsample': 0.25,\n            'subsample_freq': 1,\n            'learning_rate': 0.4,\n            'num_leaves': 20,\n            'feature_fraction': 0.9,\n            'lambda_l1': 1,  \n            'lambda_l2': 1\n            }\n\nfolds = 4\nseed = 666\n\nkf = StratifiedKFold(n_splits=folds, shuffle=True, random_state=seed)\n\nmodels = []\nfor train_index, val_index in kf.split(train, train['building_id']):\n    train_X = train.iloc[train_index]\n    val_X = train.iloc[val_index]\n    train_y = target.iloc[train_index]\n    val_y = target.iloc[val_index]\n    lgb_train = lgb.Dataset(train_X, train_y, categorical_feature=categorical_feats)\n    lgb_eval = lgb.Dataset(val_X, val_y, categorical_feature=categorical_feats)\n    gbm = lgb.train(params,\n                lgb_train,\n                num_boost_round=500,\n                valid_sets=(lgb_train, lgb_eval),\n                early_stopping_rounds=100,\n                verbose_eval = 100)\n    models.append(gbm)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"i=0\nres=[]\nstep_size = 50000\nfor j in tqdm(range(int(np.ceil(test.shape[0]/50000)))):\n    res.append(np.expm1(sum([model.predict(test.iloc[i:i+step_size]) for model in models])/folds))\n    i+=step_size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"res = np.concatenate(res)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv('/kaggle/input/ashrae-energy-prediction/sample_submission.csv')\nsubmission['meter_reading'] = res\nsubmission.loc[submission['meter_reading']<0, 'meter_reading'] = 0\nsubmission.to_csv('submission.csv', index=False)","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":1}