{"cells":[{"metadata":{},"cell_type":"markdown","source":"# ASHRAE - Great Energy Predictor III¶\n\nThis notebook contains basic exploration of provided data and creation of recurent neural network model with tensorflow. <br>This it was kept in a simple manner in order to provide base line solution for LSTM.\n<br><br>\n\n_Context_\n\nWith advancements in technology and increasing number of people world wide also the amount of energy is rising. To prevent negative impact of this growth we could find possibilities to optimize the energy consumed by buildings. In order to do that there is required some insights into \"energetic efficiency\" of buildings."},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install tensorflow==2.0.0\n!pip install chart_studio\n\nimport numpy as np \nimport pandas as pd\nimport os\n\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nplt.style.use('fivethirtyeight') \n\n%matplotlib inline\nfrom pylab import rcParams\nfrom plotly import tools\nimport chart_studio.plotly as py\nfrom plotly.offline import init_notebook_mode, iplot\ninit_notebook_mode(connected=True)\nimport plotly.graph_objs as go\nimport plotly.figure_factory as ff\nimport statsmodels.api as sm\n\nimport math\nimport random","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Preprocessing"},{"metadata":{},"cell_type":"markdown","source":"We've following files for exploration."},{"metadata":{"trusted":false},"cell_type":"code","source":"!ls ../input/ashrae-energy-prediction/","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's start analysis from the reading datasets."},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\ntrain_df = pd.read_csv('../input/ashrae-energy-prediction/train.csv')\nweather_train_df = pd.read_csv('../input/ashrae-energy-prediction/weather_train.csv')\ntest_df = pd.read_csv('../input/ashrae-energy-prediction/test.csv')\nweather_test_df = pd.read_csv('../input/ashrae-energy-prediction/weather_test.csv')\nbuilding_meta_df = pd.read_csv('../input/ashrae-energy-prediction/building_metadata.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"weather_train_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"weather_test_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"building_meta_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_df = train_df.merge(building_meta_df, on=\"building_id\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"train_df = train_df.merge(weather_train_df, on=[\"site_id\", \"timestamp\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's take a look at sample rows from combined dataframe."},{"metadata":{"trusted":false},"cell_type":"code","source":"sample_df = train_df.sample(20, random_state=0)\nsample_df","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now let's change the 'primary_use' column to categorical."},{"metadata":{"trusted":false},"cell_type":"code","source":"train_df['primary_use'] = pd.Categorical(train_df['primary_use'])\ntrain_df['primary_use'] = train_df['primary_use'].cat.codes\ntrain_df.head(10)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's check how many 'NaN' values has each column."},{"metadata":{"trusted":false},"cell_type":"code","source":"train_df.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"100 * train_df.isnull().sum() / len(train_df)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As we can see there is quite lot of NaN's in some of the columns. In order to use the this data in neural network we have to change them into numerical values or drop them."},{"metadata":{"trusted":false},"cell_type":"code","source":"del train_df['floor_count']\ndel train_df['year_built']","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Shaping data\nIn order to run LSTM neural network data has to be in three dimentional shape where axis corresponds to following data:\n* x-axis time steps\n* y-axis data examples\n* z-axis features for single point in time\n\n![image.png](attachment:image.png)\n\nThere are fine written resources on the net describing how LSTM networks works and what's their architecture.\n* i.e. [here](http://colah.github.io/posts/2015-08-Understanding-LSTMs/)","attachments":{"image.png":{"image/png":"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xKJFi/DAAw/g888/l81tUzjJIyIiIrmRfeiVl5cjMDAQDz30EDZv3gyLxQK1Wo2RI0eiW7duthspuwoneURERCRXsg+9xMREdO7cGZMmTUJpaSmAP++IsXPnTnTs2BGTJ0+2u/9fa+Mkj4iIiORK9qFXVFSE1NRU5OXl2T1eWVkJlUqFtLQ0l1zVykkeERERyZ3sQ0+uOMkjIiIiuWPoNREneURERCQKhl4T1ZzkxcXFMfKIiIhIthh6jcRJHhEREYmGoddInOQRERGRaBh6DeAkj4iIiETF0GsAJ3lEREQkKoZeHTjJIyIiItEx9OrAffKIiIhIdAy9m9Q2yXPFnTeIiIiIWoqhdxNO8oiIiMhdeFToVVZWQpKkWv+N5+QRERGRu/GY0CstLUV4eDgOHjxYa+zx6loiIiJyNx4TehqNBqNHj8bixYvtQo+TPCIiInJXHh96nOQRERGRu/LY0OMkj4iIiNydx4YeJ3lERETk7jwu9D777DNcuXKFkzwiIiJyex4Xeh988AH8/f05ySMiIiK351Gh9+yzz6Jbt27o27cvNm3ahPz8fGi1WrsX3gWDiIiI3IXHhF5OTg6GDRuGO++8E3379sU//vEPvPjii3YvY8aMwYkTJ1x9qEREREQO4TGhV1VVhQ0bNmDWrFkICgqq9WXz5s0oLCx09aESEREROYTHhB4AWCwWmEwmmM3mWl/4Z1siIiJyJx4VekRERESehKFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERuiqFHRERE5KYYekRERERu6v8BrXIydNxuPccAAAAASUVORK5CYII="}}},{"metadata":{},"cell_type":"markdown","source":"Let's take data for first 10 building_id's and preprocess them for LSTM neural network."},{"metadata":{"trusted":false},"cell_type":"code","source":"def extract_data(building_id):\n    return train_df[train_df['building_id'] == building_id]\n\nextracted_df = {}\nfor i in range(10):\n    df = extract_data(i)\n    sea_lev_pressure_mean = df['sea_level_pressure'].mean()\n    dew_temperature_mean = df['dew_temperature'].mean()\n    air_temperature_mean = df['air_temperature'].mean()\n    precip_depth_1_hr_mean = df['precip_depth_1_hr'].mean()\n    wind_speed_mean = df['wind_speed'].median()\n\n    df['meter'] = pd.to_numeric(df['meter'], errors='coerce').fillna(0).astype(np.float32)\n    df['meter_reading'] = pd.to_numeric(df['meter_reading'], errors='coerce').fillna(0).astype(np.float32)\n    df['site_id'] = pd.to_numeric(df['site_id'], errors='coerce').fillna(0).astype(np.float32)\n    df['primary_use'] = pd.to_numeric(df['primary_use'], errors='coerce').fillna(0).astype(np.float32)\n    df['square_feet'] = pd.to_numeric(df['square_feet'], errors='coerce').fillna(0).astype(np.float32)\n    \n    df['air_temperature'] = df['air_temperature'].fillna(-1)\n    df['cloud_coverage'] = df['cloud_coverage'].fillna(-1)\n    df['sea_level_pressure'] = df['sea_level_pressure'].fillna(sea_lev_pressure_mean)\n    df['dew_temperature'] = df['dew_temperature'].fillna(dew_temperature_mean)\n    df['air_temperature'] = df['air_temperature'].fillna(air_temperature_mean)\n    df['precip_depth_1_hr'] = df['precip_depth_1_hr'].fillna(precip_depth_1_hr_mean)\n    df['wind_direction'] = df['wind_direction'].apply(lambda x: random.random() * 360.0 if (math.isnan(x)) else x)\n    df['wind_speed'] = df['wind_speed'].fillna(wind_speed_mean).astype(np.float32)\n    extracted_df[i] = df\n    \nextracted_df[4]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Dictionary 'extracted_df' contains data for buildings_ids in range \\[0, 10) which have to be reshaped in order to feed them into LSTM neural network."},{"metadata":{"trusted":true},"cell_type":"code","source":"### Building simple LSTM network","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def input_function(x_tr, y_tr, x_d, y_d, x_t, y_t, bs_tr):\n    t_d = tf.data.Dataset.from_tensor_slices((x_tr, y_tr))\n    t_d = t_d.cache().batch(bs_tr).repeat()\n    d_d = tf.data.Dataset.from_tensor_slices((x_d, y_d))\n    d_d = d_d.batch(bs_tr).repeat()\n    v_d = tf.data.Dataset.from_tensor_slices((x_t, y_t))\n    v_d = v_d.batch(1).repeat()\n    return t_d, d_d, v_d","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Splits data according to provided parameters."},{"metadata":{"trusted":false},"cell_type":"code","source":"def split_data(ds, tar, st_ind, en_ind, hs,\n               ts, step):\n    data = []\n    lab = []\n\n    st_ind = st_ind + hs\n    if en_ind is None:\n        en_ind = len(ds) - ts\n\n    for i in range(st_ind, en_ind):\n        indices = range(i - hs, i, step)\n        data.append(ds[indices])\n        lab.append(tar[i + ts])\n\n    return np.array(data), np.array(lab)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Prepares data for three sets of data (train, dev, val) for every 'building_id'."},{"metadata":{"trusted":false},"cell_type":"code","source":"def prepare_data(data, hn, tv_split,\n                 ve_split, tn, step=1, bs=64):\n    ds = {}\n\n    for j in range(10):\n        x_tr, y_tr = split_data(data[j], data[j][:, 3], 0,\n                                          tv_split, hn,\n                                          tn, step)\n        x_d, y_d = split_data(data[j], data[j][:, 3],\n                                      tv_split, ve_split, hn,\n                                      tn, step)\n        x_t, y_t = split_data(data[j], data[j][:, 3],\n                                        ve_split, None, hn,\n                                        tn, step)\n        t_d, d_d, v_d = input_function(x_tr, y_tr, x_d, y_d, x_t, y_t, bs)\n        ds[j] = {}\n        ds[j]['train'] = t_d\n        ds[j]['dev'] = d_d\n        ds[j]['test'] = v_d\n\n    inp_d = x_tr.shape[-2:]\n\n    return inp_d, ds","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Standardize features by removing mean and scaling according to variances."},{"metadata":{"trusted":false},"cell_type":"code","source":"def scale_data(data_dict, fc, fc_n):\n    td = {}\n    norm_param = {}\n\n    for i in range(10):\n        norm_param[i] = {}\n        features = data_dict[i][fc]\n        features.index = data_dict[i]['timestamp']\n        features.head()\n        for j in fc_n:\n            data_mean = features[j].mean(axis=0)\n            data_std = features[j].std(axis=0)\n            features[j] = (features[j] - data_mean) / data_std\n        td[i] = features.values\n    \n    return td, norm_param\n        \n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Fit to every data set with given 'building_id'."},{"metadata":{"trusted":false},"cell_type":"code","source":"def fit_model(ds, model, eval_int, epochs=10, trg='meter'):\n    tm_histories = {}\n    for i in range(10):\n        print(\"Fitting to %s\" % i)\n        tm_histories[i] = model.fit(ds[i][\"train\"],\n                                   validation_data=ds[i][\"dev\"],\n                                   steps_per_epoch=eval_int,\n                                   epochs=epochs,\n                                   validation_steps=1).history\n    return model, tm_histories","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Here we prepare data using previously defined functions"},{"metadata":{"trusted":false},"cell_type":"code","source":"fc = ['meter', 'meter_reading', 'site_id',\n      'primary_use', 'air_temperature', 'cloud_coverage',\n      'dew_temperature', 'precip_depth_1_hr', 'sea_level_pressure',\n      'wind_direction', 'wind_speed']\n\nfc_n = ['meter_reading','air_temperature', 'cloud_coverage',\n       'dew_temperature', 'precip_depth_1_hr', 'sea_level_pressure',\n       'wind_direction', 'wind_speed']\n\ntv_split = int(len(extracted_df[4])* 0.7)\nve_split = int(len(extracted_df[4])* 0.85)\npast = 30\neval_int = 1\n\ntd_set, norm_params = scale_data(extracted_df, fc, fc_n)\n# print(td_set[1][:10])\ninp_d, ds = prepare_data(td_set, past, tv_split, ve_split, 1, step=1, bs=32)\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Bellow we create LSTM model with tensorflow keras. Sample loss function is doesn't complie with the one provided in the task yet."},{"metadata":{"trusted":false},"cell_type":"code","source":"model = tf.keras.models.Sequential()\nmodel.add(tf.keras.layers.LSTM(units=30,\n                               return_sequences=True,\n                               input_shape=inp_d))\nmodel.add(tf.keras.layers.LSTM(units=32, return_sequences=True))\nmodel.add(tf.keras.layers.Dropout(0.8))\nmodel.add(tf.keras.layers.LSTM(units=16, return_sequences=True))\nmodel.add(tf.keras.layers.Dropout(0.8))\nmodel.add(tf.keras.layers.Dense(1))\nmodel.compile(optimizer=tf.keras.optimizers.Adam(clipvalue=1.0), loss='mse')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# model, hist_dict = fit_model(ds, model, eval_int, 500)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Further analysis\nComming soon ..."}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.4"}},"nbformat":4,"nbformat_minor":1}