{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":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)\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'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\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":"import gc\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nimport lightgbm as lgb\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import KFold","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"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 save_models(models):\n    i=0\n    for model in models:\n        model.save_model(f'model_{i}.txt')\n        i+=1\n\ndef load_models():\n    models = []\n    for i in range(3):\n        model = lgb.Booster(model_file=f'../input/modelst2/model_{i}.txt')\n        models.append(model)\n    return models","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Hour of T max by site_id\nhtmax = [19,14,0,19,0,12,20,0,19,21,0,0,14,0,20,20]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"holidays = [\"2016-01-01\", \"2016-01-18\", \"2016-02-15\", \"2016-05-30\", \"2016-07-04\",\n            \"2016-09-05\", \"2016-10-10\", \"2016-11-11\", \"2016-11-24\", \"2016-12-26\",\n            \"2017-01-01\", \"2017-01-16\", \"2017-02-20\", \"2017-05-29\", \"2017-07-04\",\n            \"2017-09-04\", \"2017-10-09\", \"2017-11-10\", \"2017-11-23\", \"2017-12-25\",\n            \"2018-01-01\", \"2018-01-15\", \"2018-02-19\", \"2018-05-28\", \"2018-07-04\",\n            \"2018-09-03\", \"2018-10-08\", \"2018-11-12\", \"2018-11-22\", \"2018-12-25\",\n            \"2019-01-01\"]","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"","_uuid":"","trusted":true},"cell_type":"code","source":"building_metadata = pd.read_csv(\"../input/ashrae-energy-prediction/building_metadata.csv\")\nbuilding_metadata = reduce_mem_usage(building_metadata)\n\ntrain = pd.read_csv(\"../input/ashrae-energy-prediction/train.csv\",parse_dates=['timestamp'])\ntrain = reduce_mem_usage(train)\n\nweather_train = pd.read_csv(\"../input/ashrae-energy-prediction/weather_train.csv\",parse_dates=['timestamp'])\nweather_train = reduce_mem_usage(weather_train)\n\ntest = pd.read_csv(\"../input/ashrae-energy-prediction/test.csv\",parse_dates=['timestamp'])\ntest = reduce_mem_usage(test)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Data Cleaning"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = train.query('not (building_id <= 104 & meter == 0 & timestamp <= \"2016-05-20\")')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Feature Engineering (train)"},{"metadata":{"trusted":true},"cell_type":"code","source":"building_metadata[\"year_built_fe\"] = building_metadata[\"year_built\"].fillna(1960) - 1900\nbuilding_metadata[\"year_built_fe\"] = building_metadata[\"year_built_fe\"] // 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"building_metadata['square_feet'] =  np.log1p(building_metadata['square_feet'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"default_floor = pd.DataFrame( [2,1,1,1,8,2,1,1,1,1,1,1,1,4,2,1],\n                              columns=[\"floor\"],\n                              index=[\"Education\",\n                                     \"Entertainment/public assembly\",\n                                     \"Food sales and service\",\n                                     \"Healthcare\",\n                                     \"Lodging/residential\",\n                                     \"Manufacturing/industrial\",\n                                     \"Office\",\n                                     \"Other\",\n                                     \"Parking\",\n                                     \"Public services\",\n                                     \"Religious worship\",\n                                     \"Retail\",\n                                     \"Services\",\n                                     \"Technology/science\",\n                                     \"Utility\",\n                                     \"Warehouse/storage\"])\n\nbuilding_metadata['floor_count'] = building_metadata.apply(lambda x: \n                                                           default_floor.loc[x['primary_use']].floor if np.isnan(x['floor_count']) else x['floor_count'],\n                                                           axis = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"w = pd.concat([train,test])\npivot = w.pivot_table(values='meter_reading', index=['building_id'], columns=['meter'])\n\nbuilding_metadata[\"has_0_meter\"] = pivot[:][0].apply(lambda x: np.isfinite(x))\nbuilding_metadata[\"has_1_meter\"] = pivot[:][1].apply(lambda x: np.isfinite(x))\nbuilding_metadata[\"has_2_meter\"] = pivot[:][2].apply(lambda x: np.isfinite(x))\nbuilding_metadata[\"has_3_meter\"] = pivot[:][3].apply(lambda x: np.isfinite(x))\n\ndel w, pivot","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"le = LabelEncoder()\nbuilding_metadata[\"primary_use\"] = le.fit_transform(building_metadata[\"primary_use\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_train['air_temperature'] = weather_train['air_temperature'].interpolate(method ='linear', limit_direction ='both')\nweather_train['dew_temperature'] = weather_train['dew_temperature'].interpolate(method ='linear', limit_direction ='both')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_train[\"Q_cumulated\"] = weather_train.air_temperature.add(273).rolling(24*7,min_periods=1).sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"t = train.merge(building_metadata, on='building_id', how='left')\nt = t.merge(weather_train, on=['site_id', 'timestamp'], how='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"t['week']    = t['timestamp'].dt.week\nt['weekday'] = t['timestamp'].dt.weekday\nt[\"hour\"]    = t[\"timestamp\"].dt.hour\nt[\"htmax\"]   = t.site_id.apply (lambda x: htmax[x])\nt[\"w_htmax\"] = t.hour.sub(t.htmax).abs()\nt[\"w_htmax\"] = t.w_htmax.apply(lambda x: (12 - x) if x<12 else (x%12))\nt[\"is_holiday\"] = (t.timestamp.dt.date.astype(\"str\").isin(holidays)).astype(int)\n\ndel t[\"htmax\"]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### LGBM fit"},{"metadata":{"trusted":true},"cell_type":"code","source":"cat_features  = ['building_id', 'meter', 'site_id', 'primary_use', \n                 'week', 'weekday', 'hour', 'is_holiday',\n                 'year_built_fe',\n                 'has_0_meter', 'has_1_meter', 'has_2_meter', 'has_3_meter' ]\n\ncont_features = ['square_feet', 'floor_count', \n                 'air_temperature', 'dew_temperature', 'Q_cumulated',\n                 # -- 'cloud_coverage', 'precip_depth_1_hr', \n                 # -- 'sea_level_pressure', 'wind_direction', 'wind_speed', \n                 'w_htmax' ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for c in cat_features:\n    t[c] = t[c].astype('category')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = t[cat_features + cont_features]\ny = np.log1p(t['meter_reading'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"params = {\n            'boosting_type': 'gbdt',\n            'objective': 'regression',\n            'metric': 'rmse',\n            'num_leaves': 1280,\n            'learning_rate': 0.07,\n            'feature_fraction': 0.85,\n            'reg_lambda': 2\n          }","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del t\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"kf = KFold(n_splits=3)\n\nmodels = []\nevals_results = []\n\nfor train_index,test_index in kf.split(x):\n    train_features = x.loc[train_index]\n    train_target = y.loc[train_index]\n    \n    test_features = x.loc[test_index]\n    test_target = y.loc[test_index]\n    \n    d_training = lgb.Dataset(train_features, label=train_target, categorical_feature=cat_features, free_raw_data=False)\n    d_test     = lgb.Dataset(test_features,  label=test_target,  categorical_feature=cat_features, free_raw_data=False)\n    \n    evals_result = {}  # to record eval results for plotting\n\n    model = lgb.train(params, \n                      train_set=d_training, \n                      num_boost_round=1000, \n                      valid_sets=[d_training,d_test], \n                      verbose_eval=25, \n                      early_stopping_rounds=50,\n                      evals_result = evals_result)\n    \n    models.append(model)\n    evals_results.append(evals_result)\n    \n    del train_features, train_target, test_features, test_target, d_training, d_test\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for model, evals_result in zip(models, evals_results):\n    f, (ax1, ax2) = plt.subplots(nrows = 1, ncols = 2, figsize=(15, 6))\n    lgb.plot_importance(model, ax=ax1)\n    lgb.plot_metric(evals_result, metric='rmse', ax=ax2)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"save_models(models)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Feature Engineering (test)"},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_test = pd.read_csv(\"../input/ashrae-energy-prediction/weather_test.csv\",parse_dates=['timestamp'])\nweather_test = reduce_mem_usage(weather_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_test['air_temperature'] = weather_test['air_temperature'].interpolate(method ='linear', limit_direction ='both')\nweather_test['dew_temperature'] = weather_test['dew_temperature'].interpolate(method ='linear', limit_direction ='both')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"weather_test[\"Q_cumulated\"] = weather_test.air_temperature.add(273).rolling(24*7,min_periods=1).sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tt = test.merge(building_metadata, on='building_id', how='left')\ntt = tt.merge(weather_test, on=['site_id', 'timestamp'], how='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tt['week']    = tt['timestamp'].dt.week\ntt['weekday'] = tt['timestamp'].dt.weekday\ntt[\"hour\"]    = tt[\"timestamp\"].dt.hour\ntt[\"htmax\"]   = tt.site_id.apply (lambda x: htmax[x])\ntt[\"w_htmax\"] = tt.hour.sub(tt.htmax).abs()\ntt[\"w_htmax\"] = tt.w_htmax.apply(lambda x: (12 - x) if x<12 else (x%12))\ntt[\"is_holiday\"] = (tt.timestamp.dt.date.astype(\"str\").isin(holidays)).astype(int)\n\n\ndel tt[\"htmax\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for c in cat_features:\n    tt[c] = tt[c].astype('category')\n\nx = tt[cat_features + cont_features]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del weather_train, weather_test, building_metadata\ndel y\ndel train, test, tt\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### LGBM predict"},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm\n\nstep_size = 100000\nres = []\ni = 0\nfor j in tqdm(range(int(np.ceil(x.shape[0]/step_size)))):\n    r = np.zeros(x.iloc[i:i+step_size].shape[0])\n    for model in models:\n        r += np.expm1(model.predict(x.iloc[i:i+step_size], num_iteration=model.best_iteration)) / len(models)\n    res = np.append(res,r)\n    i += step_size\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv(\"../input/ashrae-energy-prediction/sample_submission.csv\")\nsubmission['meter_reading'] = res\n\ncheck = submission.loc[submission['meter_reading']<0, 'meter_reading']\ncheck.head()\n\nsubmission.loc[submission['meter_reading']<0, 'meter_reading'] = 0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('ASHRAE-LGBM-T2-16.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}