{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd \n", "from datetime import datetime \n", "from datetime import date\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import numpy as np\n", "import pandas as pd\n", "from keras.models import Sequential\n", "from keras.layers import LSTM, Dense\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.preprocessing import MinMaxScaler,StandardScaler\n", "from keras.callbacks import ModelCheckpoint\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datezone_047_hw_valvertu_004_sat_sp_tnzone_047_tempzone_047_fan_spdrtu_004_fltrd_sa_flow_tnrtu_004_sa_temprtu_004_pa_static_stpt_tnrtu_004_oa_flow_tnrtu_004_oadmpr_pct...zone_047_heating_spUnnamed: 47_yhvac_Shp_hws_temparu_001_cwr_temparu_001_cws_fr_gpmaru_001_cws_temparu_001_hwr_temparu_001_hws_fr_gpmaru_001_hws_temp
02018-01-01 00:00:00100.069.067.520.09265.60466.10.060.00000028.0...NaNNaNNaN75.3NaNNaNNaNNaNNaNNaN
12018-01-01 00:01:00100.069.067.520.09265.60466.00.066572.09916228.0...NaNNaNNaN75.3NaNNaNNaNNaNNaNNaN
22018-01-01 00:02:00100.069.067.520.09708.24066.10.067628.83254228.0...NaNNaNNaN75.3NaNNaNNaNNaNNaNNaN
32018-01-01 00:03:00100.069.067.520.09611.63866.10.067710.29461728.0...NaNNaNNaN75.3NaNNaNNaNNaNNaNNaN
42018-01-01 00:04:00100.069.067.520.09215.11066.00.067139.18409028.0...NaNNaNNaN75.3NaNNaNNaNNaNNaNNaN
..................................................................
20721492020-12-31 23:58:00100.068.063.220.018884.83464.40.062938.32000023.4...71.069.023.145000123.856.2554.7156.4123.4261.6122.36
20721502020-12-31 23:58:00100.068.063.220.018884.83464.40.062938.32000023.4...71.069.023.145000123.856.2554.7156.4123.4261.6122.36
20721512020-12-31 23:59:00100.068.063.220.019345.50864.30.063154.39000023.4...71.069.023.145000123.856.2554.7156.4123.4261.6122.36
20721522020-12-31 23:59:00100.068.063.220.019345.50864.30.063154.39000023.4...71.069.023.145000123.856.2554.7156.4123.4261.6122.36
20721532021-01-01 00:00:00100.068.063.220.018650.23264.10.063076.27000022.9...71.069.023.788947123.856.2554.7156.4123.4261.6122.36
\n", "

2072154 rows × 30 columns

\n", "
" ], "text/plain": [ " date zone_047_hw_valve rtu_004_sat_sp_tn \\\n", "0 2018-01-01 00:00:00 100.0 69.0 \n", "1 2018-01-01 00:01:00 100.0 69.0 \n", "2 2018-01-01 00:02:00 100.0 69.0 \n", "3 2018-01-01 00:03:00 100.0 69.0 \n", "4 2018-01-01 00:04:00 100.0 69.0 \n", "... ... ... ... \n", "2072149 2020-12-31 23:58:00 100.0 68.0 \n", "2072150 2020-12-31 23:58:00 100.0 68.0 \n", "2072151 2020-12-31 23:59:00 100.0 68.0 \n", "2072152 2020-12-31 23:59:00 100.0 68.0 \n", "2072153 2021-01-01 00:00:00 100.0 68.0 \n", "\n", " zone_047_temp zone_047_fan_spd rtu_004_fltrd_sa_flow_tn \\\n", "0 67.5 20.0 9265.604 \n", "1 67.5 20.0 9265.604 \n", "2 67.5 20.0 9708.240 \n", "3 67.5 20.0 9611.638 \n", "4 67.5 20.0 9215.110 \n", "... ... ... ... \n", "2072149 63.2 20.0 18884.834 \n", "2072150 63.2 20.0 18884.834 \n", "2072151 63.2 20.0 19345.508 \n", "2072152 63.2 20.0 19345.508 \n", "2072153 63.2 20.0 18650.232 \n", "\n", " rtu_004_sa_temp rtu_004_pa_static_stpt_tn rtu_004_oa_flow_tn \\\n", "0 66.1 0.06 0.000000 \n", "1 66.0 0.06 6572.099162 \n", "2 66.1 0.06 7628.832542 \n", "3 66.1 0.06 7710.294617 \n", "4 66.0 0.06 7139.184090 \n", "... ... ... ... \n", "2072149 64.4 0.06 2938.320000 \n", "2072150 64.4 0.06 2938.320000 \n", "2072151 64.3 0.06 3154.390000 \n", "2072152 64.3 0.06 3154.390000 \n", "2072153 64.1 0.06 3076.270000 \n", "\n", " rtu_004_oadmpr_pct ... zone_047_heating_sp Unnamed: 47_y \\\n", "0 28.0 ... NaN NaN \n", "1 28.0 ... NaN NaN \n", "2 28.0 ... NaN NaN \n", "3 28.0 ... NaN NaN \n", "4 28.0 ... NaN NaN \n", "... ... ... ... ... \n", "2072149 23.4 ... 71.0 69.0 \n", "2072150 23.4 ... 71.0 69.0 \n", "2072151 23.4 ... 71.0 69.0 \n", "2072152 23.4 ... 71.0 69.0 \n", "2072153 22.9 ... 71.0 69.0 \n", "\n", " hvac_S hp_hws_temp aru_001_cwr_temp aru_001_cws_fr_gpm \\\n", "0 NaN 75.3 NaN NaN \n", "1 NaN 75.3 NaN NaN \n", "2 NaN 75.3 NaN NaN \n", "3 NaN 75.3 NaN NaN \n", "4 NaN 75.3 NaN NaN \n", "... ... ... ... ... \n", "2072149 23.145000 123.8 56.25 54.71 \n", "2072150 23.145000 123.8 56.25 54.71 \n", "2072151 23.145000 123.8 56.25 54.71 \n", "2072152 23.145000 123.8 56.25 54.71 \n", "2072153 23.788947 123.8 56.25 54.71 \n", "\n", " aru_001_cws_temp aru_001_hwr_temp aru_001_hws_fr_gpm \\\n", "0 NaN NaN NaN \n", "1 NaN NaN NaN \n", "2 NaN NaN NaN \n", "3 NaN NaN NaN \n", "4 NaN NaN NaN \n", "... ... ... ... \n", "2072149 56.4 123.42 61.6 \n", "2072150 56.4 123.42 61.6 \n", "2072151 56.4 123.42 61.6 \n", "2072152 56.4 123.42 61.6 \n", "2072153 56.4 123.42 61.6 \n", "\n", " aru_001_hws_temp \n", "0 NaN \n", "1 NaN \n", "2 NaN \n", "3 NaN \n", "4 NaN \n", "... ... \n", "2072149 122.36 \n", "2072150 122.36 \n", "2072151 122.36 \n", "2072152 122.36 \n", "2072153 122.36 \n", "\n", "[2072154 rows x 30 columns]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "merged = pd.read_csv(r'C:\\Users\\jerin\\Downloads\\lbnlbldg59\\lbnlbldg59\\lbnlbldg59.processed\\LBNLBLDG59\\clean_Bldg59_2018to2020\\clean data\\long_merge.csv')\n", "\n", "zone = \"47\"\n", "\n", "if zone in [\"36\", \"37\", \"38\", \"39\", \"40\", \"41\", \"42\", \"64\", \"65\", \"66\", \"67\", \"68\", \"69\", \"70\"]:\n", " rtu = \"rtu_001\"\n", " wing = \"hvac_N\"\n", "elif zone in [\"18\", \"25\", \"26\", \"45\", \"48\", \"55\", \"56\", \"61\"]:\n", " rtu = \"rtu_003\"\n", " wing = \"hvac_S\"\n", "elif zone in [\"16\", \"17\", \"21\", \"22\", \"23\", \"24\", \"46\", \"47\", \"51\", \"52\", \"53\", \"54\"]:\n", " rtu = \"rtu_004\"\n", " wing = \"hvac_S\"\n", "else:\n", " rtu = \"rtu_002\"\n", " wing = \"hvac_N\"\n", "#merged is the dataframe\n", "sorted = merged[[\"date\"]+[col for col in merged.columns if zone in col or rtu in col or wing in col]+[\"hp_hws_temp\", \"aru_001_cwr_temp\" , \"aru_001_cws_fr_gpm\" ,\"aru_001_cws_temp\",\"aru_001_hwr_temp\" ,\"aru_001_hws_fr_gpm\" ,\"aru_001_hws_temp\"]]\n", "sorted" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "date 0\n", "zone_047_hw_valve 0\n", "rtu_004_sat_sp_tn 0\n", "zone_047_temp 0\n", "zone_047_fan_spd 0\n", "rtu_004_fltrd_sa_flow_tn 0\n", "rtu_004_sa_temp 0\n", "rtu_004_pa_static_stpt_tn 0\n", "rtu_004_oa_flow_tn 0\n", "rtu_004_oadmpr_pct 0\n", "rtu_004_econ_stpt_tn 0\n", "rtu_004_ra_temp 0\n", "rtu_004_oa_temp 0\n", "rtu_004_ma_temp 0\n", "rtu_004_sf_vfd_spd_fbk_tn 0\n", "rtu_004_rf_vfd_spd_fbk_tn 0\n", "rtu_004_fltrd_gnd_lvl_plenum_press_tn 0\n", "rtu_004_fltrd_lvl2_plenum_press_tn 0\n", "zone_047_cooling_sp 0\n", "Unnamed: 47_x 394570\n", "zone_047_heating_sp 0\n", "Unnamed: 47_y 394570\n", "hvac_S 13035\n", "hp_hws_temp 0\n", "aru_001_cwr_temp 524350\n", "aru_001_cws_fr_gpm 524350\n", "aru_001_cws_temp 524350\n", "aru_001_hwr_temp 299165\n", "aru_001_hws_fr_gpm 299165\n", "aru_001_hws_temp 299165\n", "dtype: int64" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "final_df = sorted.copy()\n", "final_df['date'] = pd.to_datetime(final_df['date'], format = \"%Y-%m-%d %H:%M:%S\")\n", "final_df = final_df[ (final_df.date.dt.date >date(2019, 4, 1)) & (final_df.date.dt.date< date(2020, 2, 15))]\n", "final_df.isna().sum()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "testdataset_df = final_df[(final_df.date.dt.date date(2019, 11, 8))]\n", "\n", "testdataset = testdataset_df[['rtu_004_oa_temp','rtu_004_ra_temp','hp_hws_temp','rtu_004_oa_flow_tn','rtu_004_oadmpr_pct',\n", " 'rtu_004_sat_sp_tn','rtu_004_rf_vfd_spd_fbk_tn','rtu_004_ma_temp','rtu_004_sa_temp','rtu_004_fltrd_sa_flow_tn',\n", " 'rtu_004_sf_vfd_spd_fbk_tn']].values\n", "\n", "\n", "traindataset = traindataset_df[['rtu_004_oa_temp','rtu_004_ra_temp','hp_hws_temp','rtu_004_oa_flow_tn','rtu_004_oadmpr_pct',\n", " 'rtu_004_sat_sp_tn','rtu_004_rf_vfd_spd_fbk_tn','rtu_004_ma_temp','rtu_004_sa_temp','rtu_004_fltrd_sa_flow_tn',\n", " 'rtu_004_sf_vfd_spd_fbk_tn']].values" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "traindataset = traindataset.astype('float32')\n", "testdataset = testdataset.astype('float32')\n", "\n", "\n", "scaler = MinMaxScaler(feature_range=(0, 1))\n", "traindataset = scaler.fit_transform(traindataset)\n", "testdataset = scaler.transform(testdataset)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/10\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\keras\\src\\layers\\rnn\\rnn.py:205: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", " super().__init__(**kwargs)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m2745/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━━━\u001b[0m \u001b[1m6s\u001b[0m 14ms/step - loss: 0.0100" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[6], line 38\u001b[0m\n\u001b[0;32m 36\u001b[0m checkpoint_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlstm2.keras\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 37\u001b[0m checkpoint_callback \u001b[38;5;241m=\u001b[39m ModelCheckpoint(filepath\u001b[38;5;241m=\u001b[39mcheckpoint_path, monitor\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mval_loss\u001b[39m\u001b[38;5;124m'\u001b[39m, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m, save_best_only\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, mode\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmin\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m---> 38\u001b[0m \u001b[43mmodel\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_train\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mvalidation_data\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mX_test\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_test\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mepochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbatch_size\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m64\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\u001b[43mcheckpoint_callback\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\keras\\src\\utils\\traceback_utils.py:118\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 116\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 117\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 118\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 119\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 120\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\keras\\src\\backend\\tensorflow\\trainer.py:323\u001b[0m, in \u001b[0;36mTensorFlowTrainer.fit\u001b[1;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq)\u001b[0m\n\u001b[0;32m 321\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m step, iterator \u001b[38;5;129;01min\u001b[39;00m epoch_iterator\u001b[38;5;241m.\u001b[39menumerate_epoch():\n\u001b[0;32m 322\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_begin(step)\n\u001b[1;32m--> 323\u001b[0m logs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtrain_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43miterator\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 324\u001b[0m callbacks\u001b[38;5;241m.\u001b[39mon_train_batch_end(\n\u001b[0;32m 325\u001b[0m step, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pythonify_logs(logs)\n\u001b[0;32m 326\u001b[0m )\n\u001b[0;32m 327\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstop_training:\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\util\\traceback_utils.py:150\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 148\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 149\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 150\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 151\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 152\u001b[0m filtered_tb \u001b[38;5;241m=\u001b[39m _process_traceback_frames(e\u001b[38;5;241m.\u001b[39m__traceback__)\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\polymorphic_function.py:833\u001b[0m, in \u001b[0;36mFunction.__call__\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 830\u001b[0m compiler \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mxla\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnonXla\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 832\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m OptionalXlaContext(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_jit_compile):\n\u001b[1;32m--> 833\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwds\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 835\u001b[0m new_tracing_count \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mexperimental_get_tracing_count()\n\u001b[0;32m 836\u001b[0m without_tracing \u001b[38;5;241m=\u001b[39m (tracing_count \u001b[38;5;241m==\u001b[39m new_tracing_count)\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\polymorphic_function.py:878\u001b[0m, in \u001b[0;36mFunction._call\u001b[1;34m(self, *args, **kwds)\u001b[0m\n\u001b[0;32m 875\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock\u001b[38;5;241m.\u001b[39mrelease()\n\u001b[0;32m 876\u001b[0m \u001b[38;5;66;03m# In this case we have not created variables on the first call. So we can\u001b[39;00m\n\u001b[0;32m 877\u001b[0m \u001b[38;5;66;03m# run the first trace but we should fail if variables are created.\u001b[39;00m\n\u001b[1;32m--> 878\u001b[0m results \u001b[38;5;241m=\u001b[39m \u001b[43mtracing_compilation\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall_function\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 879\u001b[0m \u001b[43m \u001b[49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwds\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_variable_creation_config\u001b[49m\n\u001b[0;32m 880\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 881\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_created_variables:\n\u001b[0;32m 882\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCreating variables on a non-first call to a function\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 883\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m decorated with tf.function.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\tracing_compilation.py:139\u001b[0m, in \u001b[0;36mcall_function\u001b[1;34m(args, kwargs, tracing_options)\u001b[0m\n\u001b[0;32m 137\u001b[0m bound_args \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mbind(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 138\u001b[0m flat_inputs \u001b[38;5;241m=\u001b[39m function\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39munpack_inputs(bound_args)\n\u001b[1;32m--> 139\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunction\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_flat\u001b[49m\u001b[43m(\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# pylint: disable=protected-access\u001b[39;49;00m\n\u001b[0;32m 140\u001b[0m \u001b[43m \u001b[49m\u001b[43mflat_inputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcaptured_inputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfunction\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcaptured_inputs\u001b[49m\n\u001b[0;32m 141\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\concrete_function.py:1322\u001b[0m, in \u001b[0;36mConcreteFunction._call_flat\u001b[1;34m(self, tensor_inputs, captured_inputs)\u001b[0m\n\u001b[0;32m 1318\u001b[0m possible_gradient_type \u001b[38;5;241m=\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPossibleTapeGradientTypes(args)\n\u001b[0;32m 1319\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (possible_gradient_type \u001b[38;5;241m==\u001b[39m gradients_util\u001b[38;5;241m.\u001b[39mPOSSIBLE_GRADIENT_TYPES_NONE\n\u001b[0;32m 1320\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m executing_eagerly):\n\u001b[0;32m 1321\u001b[0m \u001b[38;5;66;03m# No tape is watching; skip to running the function.\u001b[39;00m\n\u001b[1;32m-> 1322\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_inference_function\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall_preflattened\u001b[49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1323\u001b[0m forward_backward \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_select_forward_and_backward_functions(\n\u001b[0;32m 1324\u001b[0m args,\n\u001b[0;32m 1325\u001b[0m possible_gradient_type,\n\u001b[0;32m 1326\u001b[0m executing_eagerly)\n\u001b[0;32m 1327\u001b[0m forward_function, args_with_tangents \u001b[38;5;241m=\u001b[39m forward_backward\u001b[38;5;241m.\u001b[39mforward()\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\atomic_function.py:216\u001b[0m, in \u001b[0;36mAtomicFunction.call_preflattened\u001b[1;34m(self, args)\u001b[0m\n\u001b[0;32m 214\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcall_preflattened\u001b[39m(\u001b[38;5;28mself\u001b[39m, args: Sequence[core\u001b[38;5;241m.\u001b[39mTensor]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[0;32m 215\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Calls with flattened tensor inputs and returns the structured output.\"\"\"\u001b[39;00m\n\u001b[1;32m--> 216\u001b[0m flat_outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall_flat\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 217\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfunction_type\u001b[38;5;241m.\u001b[39mpack_output(flat_outputs)\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\polymorphic_function\\atomic_function.py:251\u001b[0m, in \u001b[0;36mAtomicFunction.call_flat\u001b[1;34m(self, *args)\u001b[0m\n\u001b[0;32m 249\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m record\u001b[38;5;241m.\u001b[39mstop_recording():\n\u001b[0;32m 250\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bound_context\u001b[38;5;241m.\u001b[39mexecuting_eagerly():\n\u001b[1;32m--> 251\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_bound_context\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcall_function\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 252\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 253\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mlist\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 254\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mlen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfunction_type\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mflat_outputs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 255\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 256\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 257\u001b[0m outputs \u001b[38;5;241m=\u001b[39m make_call_op_in_graph(\n\u001b[0;32m 258\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[0;32m 259\u001b[0m \u001b[38;5;28mlist\u001b[39m(args),\n\u001b[0;32m 260\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_bound_context\u001b[38;5;241m.\u001b[39mfunction_call_options\u001b[38;5;241m.\u001b[39mas_attrs(),\n\u001b[0;32m 261\u001b[0m )\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\context.py:1500\u001b[0m, in \u001b[0;36mContext.call_function\u001b[1;34m(self, name, tensor_inputs, num_outputs)\u001b[0m\n\u001b[0;32m 1498\u001b[0m cancellation_context \u001b[38;5;241m=\u001b[39m cancellation\u001b[38;5;241m.\u001b[39mcontext()\n\u001b[0;32m 1499\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cancellation_context \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m-> 1500\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[43mexecute\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1501\u001b[0m \u001b[43m \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdecode\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mutf-8\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1502\u001b[0m \u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnum_outputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1503\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtensor_inputs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1504\u001b[0m \u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1505\u001b[0m \u001b[43m \u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1506\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1507\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 1508\u001b[0m outputs \u001b[38;5;241m=\u001b[39m execute\u001b[38;5;241m.\u001b[39mexecute_with_cancellation(\n\u001b[0;32m 1509\u001b[0m name\u001b[38;5;241m.\u001b[39mdecode(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mutf-8\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[0;32m 1510\u001b[0m num_outputs\u001b[38;5;241m=\u001b[39mnum_outputs,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 1514\u001b[0m cancellation_manager\u001b[38;5;241m=\u001b[39mcancellation_context,\n\u001b[0;32m 1515\u001b[0m )\n", "File \u001b[1;32mc:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\tensorflow\\python\\eager\\execute.py:53\u001b[0m, in \u001b[0;36mquick_execute\u001b[1;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 52\u001b[0m ctx\u001b[38;5;241m.\u001b[39mensure_initialized()\n\u001b[1;32m---> 53\u001b[0m tensors \u001b[38;5;241m=\u001b[39m \u001b[43mpywrap_tfe\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mTFE_Py_Execute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mctx\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_handle\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdevice_name\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mop_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 54\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mattrs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum_outputs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m core\u001b[38;5;241m.\u001b[39m_NotOkStatusException \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "train,test = traindataset,testdataset\n", "\n", "def create_dataset(dataset,time_step):\n", " x1,x2,x3,x4,x5,x6,x7,x8,x9,Y = [],[],[],[],[],[],[],[],[],[]\n", " for i in range(len(dataset)-time_step-1):\n", " x1.append(dataset[i:(i+time_step), 0])\n", " x2.append(dataset[i:(i+time_step), 1])\n", " x3.append(dataset[i:(i+time_step), 2])\n", " x4.append(dataset[i:(i+time_step), 3])\n", " x5.append(dataset[i:(i+time_step), 4])\n", " x6.append(dataset[i:(i+time_step), 5])\n", " x7.append(dataset[i:(i+time_step), 6])\n", " x8.append(dataset[i:(i+time_step), 7])\n", " # x9.append(dataset[i:(i+time_step), 8])\n", " Y.append([dataset[i + time_step, 7]])\n", " x1,x2,x3,x4,x5,x6,x7,x8 = np.array(x1),np.array(x2),np.array(x3), np.array(x4),np.array(x5),np.array(x6),np.array(x7),np.array(x8)#,np.array(x9)\n", " Y = np.reshape(Y,(len(Y),1))\n", " return np.stack([x1,x2,x3,x4,x5,x6,x7,x8],axis=2),Y\n", "\n", "\n", "\n", "\n", "time_step = 30\n", "X_train, y_train = create_dataset(train, time_step)\n", "X_test, y_test = create_dataset(test, time_step)\n", "\n", "\n", "model = Sequential()\n", "model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\n", "model.add(LSTM(units=50, return_sequences=True))\n", "model.add(LSTM(units=30))\n", "model.add(Dense(units=1))\n", "\n", "model.compile(optimizer='adam', loss='mean_squared_error')\n", "\n", "checkpoint_path = \"lstm2.keras\"\n", "checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=64, verbose=1, callbacks=[checkpoint_callback])\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/5\n", "\u001b[1m3218/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 1.8977e-04\n", "Epoch 1: val_loss improved from inf to 0.01131, saving model to lstm2.keras\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m94s\u001b[0m 29ms/step - loss: 1.8977e-04 - val_loss: 0.0113\n", "Epoch 2/5\n", "\u001b[1m3219/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: 1.7357e-04\n", "Epoch 2: val_loss did not improve from 0.01131\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m91s\u001b[0m 28ms/step - loss: 1.7358e-04 - val_loss: 0.0123\n", "Epoch 3/5\n", "\u001b[1m3219/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: 1.6701e-04\n", "Epoch 3: val_loss did not improve from 0.01131\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m92s\u001b[0m 28ms/step - loss: 1.6701e-04 - val_loss: 0.0127\n", "Epoch 4/5\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 18ms/step - loss: 1.7043e-04\n", "Epoch 4: val_loss did not improve from 0.01131\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m91s\u001b[0m 28ms/step - loss: 1.7043e-04 - val_loss: 0.0131\n", "Epoch 5/5\n", "\u001b[1m3218/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 1.6319e-04\n", "Epoch 5: val_loss did not improve from 0.01131\n", "\u001b[1m3220/3220\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m104s\u001b[0m 32ms/step - loss: 1.6319e-04 - val_loss: 0.0134\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=5, batch_size=64, verbose=1, callbacks=[checkpoint_callback])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m9900/9900\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m34s\u001b[0m 3ms/step\n" ] } ], "source": [ "# train_predict = model.predict(X_train)\n", "test_predict = model.predict(X_test)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib qt\n", "#'rtu_004_ma_temp','rtu_004_sa_temp'\n", "var = 0\n", "plt.plot(testdataset_df['date'][31:],y_test, label='Original Testing Data', color='blue')\n", "plt.plot(testdataset_df['date'][31:],test_predict, label='Predicted Testing Data', color='red',alpha=0.8)\n", "# anomalies = np.where(abs(test_predict[:,var] - y_test[:,var]) > 0.38)[0]\n", "# plt.scatter(anomalies,test_predict[anomalies,var], color='black',marker =\"o\",s=100 )\n", "\n", "\n", "plt.title('Testing Data - Predicted vs Actual')\n", "plt.xlabel('Time')\n", "plt.ylabel('Value')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "from tensorflow.keras.models import load_model\n", "# model.save(\"MA_temp_model.h5\") \n", "# loaded_model = load_model(\"MA_temp_model.h5\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ENERGY DATA" ] }, { "cell_type": "code", "execution_count": 267, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
dateair_temp_set_1air_temp_set_2dew_point_temperature_set_1drelative_humidity_set_1solar_radiation_set_1wifi_third_southwifi_fourth_southhvac_Nhvac_S
02018-01-01 00:00:0011.6411.518.179.0786.7NaNNaNNaNNaN
12018-01-01 00:01:0011.6411.518.179.0786.7NaNNaNNaNNaN
\n", "
" ], "text/plain": [ " date air_temp_set_1 air_temp_set_2 \\\n", "0 2018-01-01 00:00:00 11.64 11.51 \n", "1 2018-01-01 00:01:00 11.64 11.51 \n", "\n", " dew_point_temperature_set_1d relative_humidity_set_1 \\\n", "0 8.1 79.07 \n", "1 8.1 79.07 \n", "\n", " solar_radiation_set_1 wifi_third_south wifi_fourth_south hvac_N hvac_S \n", "0 86.7 NaN NaN NaN NaN \n", "1 86.7 NaN NaN NaN NaN " ] }, "execution_count": 267, "metadata": {}, "output_type": "execute_result" } ], "source": [ "zone = [\"18\", \"25\", \"26\", \"45\", \"48\", \"55\", \"56\", \"61\",\"16\", \"17\", \"21\", \"23\", \"24\", \"46\", \"47\", \"51\", \"52\", \"53\", \"54\"]\n", "rtu = [\"rtu_001\",\"rtu_002\",\"rtu_003\",\"rtu_004\"]\n", "wing = [\"hvac_N\",\"hvac_S\"]\n", "env = [\"air_temp_set_1\",\"air_temp_set_2\",\"dew_point_temperature_set_1d\",\"relative_humidity_set_1\",\"solar_radiation_set_1\"]\n", "wifi=[\"wifi_third_south\",\"wifi_fourth_south\"]\n", "# any(sub in col for sub in zone) or\n", "energy_data = merged[[\"date\"]+[col for col in merged.columns if \n", " any(sub in col for sub in env) or any(sub in col for sub in wifi)]+wing]\n", "df_filtered = energy_data[[col for col in energy_data.columns if 'Unnamed' not in col]]\n", "df_filtered = df_filtered[[col for col in df_filtered.columns if 'co2' not in col]]\n", "df_filtered = df_filtered[[col for col in df_filtered.columns if 'templogger' not in col]]\n", "# df_filtered = df_filtered.dropna()\n", "df_filtered.head(2)" ] }, { "cell_type": "code", "execution_count": 268, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There are NA values in the DataFrame columns.\n" ] } ], "source": [ "df_filtered['date'] = pd.to_datetime(df_filtered['date'], format = \"%Y-%m-%d %H:%M:%S\")\n", "df_filtered = df_filtered[ (df_filtered.date.dt.date >date(2019, 4, 1)) & (df_filtered.date.dt.date< date(2020, 2, 15))]\n", "# df_filtered.isna().sum()\n", "if df_filtered.isna().any().any():\n", " print(\"There are NA values in the DataFrame columns.\")" ] }, { "cell_type": "code", "execution_count": 269, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 269, "metadata": {}, "output_type": "execute_result" } ], "source": [ "testdataset_df = df_filtered[(df_filtered.date.dt.date date(2019, 11, 8))]\n", "\n", "testdataset = testdataset_df.drop(columns=[\"date\"]).values\n", "\n", "traindataset = traindataset_df.drop(columns=[\"date\"]).values\n", "\n", "columns_with_na = traindataset_df.columns[traindataset_df.isna().any()].tolist()\n", "columns_with_na" ] }, { "cell_type": "code", "execution_count": 270, "metadata": {}, "outputs": [], "source": [ "traindataset = traindataset.astype('float32')\n", "testdataset = testdataset.astype('float32')\n", "\n", "scaler = MinMaxScaler(feature_range=(0, 1))\n", "traindataset = scaler.fit_transform(traindataset)\n", "testdataset = scaler.transform(testdataset)" ] }, { "cell_type": "code", "execution_count": 271, "metadata": {}, "outputs": [], "source": [ "train,test = traindataset,testdataset\n", "\n", "def create_dataset(dataset,time_step):\n", " x = [[] for _ in range(9)] \n", " Y = []\n", " for i in range(len(dataset) - time_step - 1):\n", " for j in range(9):\n", " x[j].append(dataset[i:(i + time_step), j])\n", " Y.append([dataset[i + time_step, 7],dataset[i + time_step, 8]])\n", " x= [np.array(feature_list) for feature_list in x]\n", " Y = np.reshape(Y,(len(Y),2))\n", " return np.stack(x,axis=2),Y\n", "\n", "time_step = 30\n", "X_train, y_train = create_dataset(train, time_step)\n", "X_test, y_test = create_dataset(test, time_step)\n", "\n", "\n", "model = Sequential()\n", "model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\n", "model.add(LSTM(units=50, return_sequences=True))\n", "model.add(LSTM(units=30))\n", "model.add(Dense(units=2))\n", "\n", "model.compile(optimizer='adam', loss='mean_squared_error')\n", "\n", "checkpoint_path = \"lstm_energy_01.keras\"\n", "checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=3, batch_size=64, verbose=1, callbacks=[checkpoint_callback])\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "# model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=64, verbose=1, callbacks=[checkpoint_callback])" ] }, { "cell_type": "code", "execution_count": 272, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m6345/6345\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m42s\u001b[0m 6ms/step\n" ] } ], "source": [ "from tensorflow.keras.models import load_model\n", "checkpoint_path = \"lstm_energy_01.keras\"\n", "model = load_model(checkpoint_path)\n", "test_predict1 = model.predict(X_test)\n", "# train_predict1 = model.predict(X_train)" ] }, { "cell_type": "code", "execution_count": 273, "metadata": {}, "outputs": [], "source": [ "%matplotlib qt\n", "var = 1\n", "plt.plot(testdataset_df['date'][31:],y_test[:,1], label='Original Testing Data', color='blue')\n", "plt.plot(testdataset_df['date'][31:],test_predict1[:,1], label='Predicted Testing Data', color='red',alpha=0.8)\n", "# anomalies = np.where(abs(test_predict[:,var] - y_test[:,var]) > 0.38)[0]\n", "# plt.scatter(anomalies,test_predict[anomalies,var], color='black',marker =\"o\",s=100 )\n", "\n", "\n", "plt.title('Testing Data - Predicted vs Actual')\n", "plt.xlabel('Time')\n", "plt.ylabel('Value')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" ] } ], "source": [ "# from tensorflow.keras.models import load_model\n", "# model.save(\"energy_model_01.h5\") " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%matplotlib qt\n", "plt.plot(df_filtered['date'],df_filtered['hvac_S'])\n", "plt.plot(df_filtered['date'],df_filtered['rtu_003_sf_vfd_spd_fbk_tn'])\n", "plt.plot(df_filtered['date'],df_filtered['zone_025_temp'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt.plot(merged['hvac_S'])\n", "plt.plot(testdataset_df['hvac_S'])\n", "plt.plot(traindataset_df['hvac_S'],'r')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt.plot(merged['hvac_N'])\n", "plt.plot(testdataset_df['hvac_N'])\n", "plt.plot(traindataset_df['hvac_N'],'r')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# merged.columns.to_list()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.16.1\n" ] } ], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "LSTM 2.0" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datehp_hws_temprtu_001_sat_sp_tnrtu_002_sat_sp_tnrtu_003_sat_sp_tnrtu_004_sat_sp_tnrtu_001_fltrd_sa_flow_tnrtu_002_fltrd_sa_flow_tnrtu_003_fltrd_sa_flow_tnrtu_004_fltrd_sa_flow_tn...rtu_002_fltrd_lvl2_plenum_press_tnrtu_003_fltrd_lvl2_plenum_press_tnrtu_004_fltrd_lvl2_plenum_press_tnwifi_third_southwifi_fourth_southair_temp_set_1air_temp_set_2dew_point_temperature_set_1drelative_humidity_set_1solar_radiation_set_1
02018-01-01 00:00:0075.368.070.065.069.014131.44913998.75713558.5399265.604...0.050.050.050NaNNaN11.6411.518.179.0786.7
12018-01-01 00:01:0075.368.070.065.069.014164.42914065.25913592.9099265.604...0.050.040.046NaNNaN11.6411.518.179.0786.7
\n", "

2 rows × 65 columns

\n", "
" ], "text/plain": [ " date hp_hws_temp rtu_001_sat_sp_tn rtu_002_sat_sp_tn \\\n", "0 2018-01-01 00:00:00 75.3 68.0 70.0 \n", "1 2018-01-01 00:01:00 75.3 68.0 70.0 \n", "\n", " rtu_003_sat_sp_tn rtu_004_sat_sp_tn rtu_001_fltrd_sa_flow_tn \\\n", "0 65.0 69.0 14131.449 \n", "1 65.0 69.0 14164.429 \n", "\n", " rtu_002_fltrd_sa_flow_tn rtu_003_fltrd_sa_flow_tn \\\n", "0 13998.757 13558.539 \n", "1 14065.259 13592.909 \n", "\n", " rtu_004_fltrd_sa_flow_tn ... rtu_002_fltrd_lvl2_plenum_press_tn \\\n", "0 9265.604 ... 0.05 \n", "1 9265.604 ... 0.05 \n", "\n", " rtu_003_fltrd_lvl2_plenum_press_tn rtu_004_fltrd_lvl2_plenum_press_tn \\\n", "0 0.05 0.050 \n", "1 0.04 0.046 \n", "\n", " wifi_third_south wifi_fourth_south air_temp_set_1 air_temp_set_2 \\\n", "0 NaN NaN 11.64 11.51 \n", "1 NaN NaN 11.64 11.51 \n", "\n", " dew_point_temperature_set_1d relative_humidity_set_1 \\\n", "0 8.1 79.07 \n", "1 8.1 79.07 \n", "\n", " solar_radiation_set_1 \n", "0 86.7 \n", "1 86.7 \n", "\n", "[2 rows x 65 columns]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rtu = [\"rtu_003\",\"rtu_004\",\"rtu_001\",\"rtu_002\"]\n", "# wing = [\"hvac_N\",\"hvac_S\"]\n", "env = [\"air_temp_set_1\",\"air_temp_set_2\",\"dew_point_temperature_set_1d\",\"relative_humidity_set_1\",\"solar_radiation_set_1\"]\n", "wifi=[\"wifi_third_south\",\"wifi_fourth_south\"]\n", "# any(sub in col for sub in zone) or\n", "energy_data = merged[[\"date\",\"hp_hws_temp\"]+[col for col in merged.columns if \n", " any(sub in col for sub in rtu) or any(sub in col for sub in wifi)]+env]\n", "df_filtered = energy_data[[col for col in energy_data.columns if 'Unnamed' not in col]]\n", "df_filtered = df_filtered[[col for col in df_filtered.columns if 'co2' not in col]]\n", "df_filtered = df_filtered[[col for col in df_filtered.columns if 'templogger' not in col]]\n", "# df_filtered = df_filtered.dropna()\n", "df_filtered.head(2)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There are NA values in the DataFrame columns. [0, 0, 0, 0, 0, 0, 27872, 36554, 15482, 39222, 30748, 37389, 18791, 36175, 31546, 36586, 16271, 36346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23177, 23177, 0, 0, 0, 0, 0]\n" ] } ], "source": [ "df_filtered['date'] = pd.to_datetime(df_filtered['date'], format = \"%Y-%m-%d %H:%M:%S\")\n", "df_filtered = df_filtered[ (df_filtered.date.dt.date >date(2018, 5, 1)) & (df_filtered.date.dt.date< date(2020, 5, 1))] #(2018, 5, 1)\n", "# df_filtered.isna().sum()\n", "if df_filtered.isna().any().any():\n", " print(\"There are NA values in the DataFrame columns.\",df_filtered.isna().sum().tolist())" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plt.plot(df_filtered['rtu_002_rf_vfd_spd_fbk_tn'])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# df_filtered = df_filtered.loc[:,['date','hp_hws_temp',\n", "# 'rtu_003_sa_temp',\n", "# 'rtu_003_oadmpr_pct',\n", "# 'rtu_003_ra_temp',\n", "# 'rtu_003_oa_temp',\n", "# 'rtu_003_ma_temp',\n", "# 'rtu_003_sf_vfd_spd_fbk_tn',\n", "# 'rtu_003_rf_vfd_spd_fbk_tn',\n", "# 'air_temp_set_1',\n", "# 'air_temp_set_2',\n", "# 'dew_point_temperature_set_1d',\n", "# 'relative_humidity_set_1',\n", "# 'solar_radiation_set_1']]\n", "\n", "df_filtered = df_filtered.loc[:,['date','hp_hws_temp',\n", " 'rtu_003_sa_temp',\n", " 'rtu_003_oadmpr_pct',\n", " 'rtu_003_ra_temp',\n", " 'rtu_003_oa_temp',\n", " 'rtu_003_ma_temp',\n", " 'rtu_003_sf_vfd_spd_fbk_tn',\n", " 'rtu_003_rf_vfd_spd_fbk_tn',\n", " 'rtu_004_sa_temp',\n", " 'rtu_004_oadmpr_pct',\n", " 'rtu_004_ra_temp',\n", " 'rtu_004_oa_temp',\n", " 'rtu_004_ma_temp',\n", " 'rtu_004_sf_vfd_spd_fbk_tn',\n", " 'rtu_004_rf_vfd_spd_fbk_tn',\n", "# 'rtu_001_sa_temp',\n", "# 'rtu_001_oadmpr_pct',\n", "# 'rtu_001_ra_temp',\n", "# 'rtu_001_oa_temp',\n", "# 'rtu_001_ma_temp',\n", "# 'rtu_001_sf_vfd_spd_fbk_tn',\n", "# 'rtu_001_rf_vfd_spd_fbk_tn',\n", " \n", "# 'rtu_002_sa_temp',\n", "# 'rtu_002_oadmpr_pct',\n", "# 'rtu_002_ra_temp',\n", "# 'rtu_002_oa_temp',\n", "# 'rtu_002_ma_temp',\n", "# 'rtu_002_sf_vfd_spd_fbk_tn',\n", "# 'rtu_002_rf_vfd_spd_fbk_tn',\n", " \n", " 'rtu_003_sat_sp_tn',\n", " 'rtu_004_sat_sp_tn',\n", "# 'rtu_001_sat_sp_tn',\n", "# 'rtu_002_sat_sp_tn',\n", " 'air_temp_set_1',\n", " 'air_temp_set_2',\n", " 'dew_point_temperature_set_1d',\n", " 'relative_humidity_set_1',\n", " 'solar_radiation_set_1']]" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "df_filtered = df_filtered.dropna()\n", "df_filtered.to_csv(\"sample_test_data.csv\",index=False)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[]\n", "[]\n" ] } ], "source": [ "df_filtered = df_filtered.dropna()\n", "# df_filtered.to_csv(\"sample_data.csv\",index=False)\n", "\n", "#----------------------------------------------------------------------------------\n", "testdataset_df = df_filtered[(df_filtered.date.dt.date >date(2019, 7, 21))]\n", "\n", "traindataset_df = df_filtered[(df_filtered.date.dt.date date(2020, 1, 1))]\n", "\n", "# traindataset_df = df_filtered[(df_filtered.date.dt.date 3,4rtu\n", "# checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "# model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=2, batch_size=64, verbose=1, callbacks=[checkpoint_callback])" ] }, { "cell_type": "code", "execution_count": 340, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\Users\\jerin\\anaconda3\\envs\\smartbuilding\\Lib\\site-packages\\keras\\src\\layers\\rnn\\rnn.py:205: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", " super().__init__(**kwargs)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/5\n", "\u001b[1m7132/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - loss: 0.0395\n", "Epoch 1: val_loss improved from inf to 0.06411, saving model to lstm_4rtu_smooth_04.keras\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m247s\u001b[0m 34ms/step - loss: 0.0395 - val_loss: 0.0641\n", "Epoch 2/5\n", "\u001b[1m7131/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - loss: 0.0012\n", "Epoch 2: val_loss improved from 0.06411 to 0.04068, saving model to lstm_4rtu_smooth_04.keras\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m248s\u001b[0m 35ms/step - loss: 0.0012 - val_loss: 0.0407\n", "Epoch 3/5\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - loss: 7.2848e-04\n", "Epoch 3: val_loss improved from 0.04068 to 0.03509, saving model to lstm_4rtu_smooth_04.keras\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m245s\u001b[0m 34ms/step - loss: 7.2848e-04 - val_loss: 0.0351\n", "Epoch 4/5\n", "\u001b[1m7132/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - loss: 5.7519e-04\n", "Epoch 4: val_loss did not improve from 0.03509\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m245s\u001b[0m 34ms/step - loss: 5.7520e-04 - val_loss: 0.0400\n", "Epoch 5/5\n", "\u001b[1m7132/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 25ms/step - loss: 5.3138e-04\n", "Epoch 5: val_loss did not improve from 0.03509\n", "\u001b[1m7133/7133\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m244s\u001b[0m 34ms/step - loss: 5.3136e-04 - val_loss: 0.0357\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 340, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train,test = traindataset,testdataset\n", "\n", "def create_dataset(dataset,time_step):\n", " x = [[] for _ in range(34)] \n", " Y = []\n", " for i in range(len(dataset) - time_step - 1):\n", " for j in range(34):\n", " x[j].append(dataset[i:(i + time_step), j])\n", " Y.append([dataset[i + time_step, 0],dataset[i + time_step, 1],dataset[i + time_step, 2],dataset[i + time_step, 3],\n", " dataset[i + time_step, 4],dataset[i + time_step, 5],\n", " dataset[i + time_step, 6],dataset[i + time_step, 7],\n", " dataset[i + time_step, 8],dataset[i + time_step, 9],dataset[i + time_step, 10],\n", " dataset[i + time_step, 11],dataset[i + time_step, 12],\n", " dataset[i + time_step, 13],dataset[i + time_step, 14],\n", " dataset[i + time_step, 15],dataset[i + time_step, 16],dataset[i + time_step, 17],\n", " dataset[i + time_step, 18],dataset[i + time_step, 19],\n", " dataset[i + time_step, 20],dataset[i + time_step, 21],\n", " dataset[i + time_step, 22],dataset[i + time_step, 23],dataset[i + time_step, 24],\n", " dataset[i + time_step, 24],dataset[i + time_step, 26],\n", " dataset[i + time_step, 27],dataset[i + time_step, 28]])\n", " x= [np.array(feature_list) for feature_list in x]\n", " Y = np.reshape(Y,(len(Y),29))\n", " return np.stack(x,axis=2),Y\n", "\n", "time_step = 30\n", "X_train, y_train = create_dataset(train, time_step)\n", "X_test, y_test = create_dataset(test, time_step)\n", "\n", "\n", "model = Sequential()\n", "model.add(LSTM(units=80, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\n", "model.add(LSTM(units=60, return_sequences=True))\n", "model.add(LSTM(units=60))\n", "model.add(Dense(units=29))\n", "\n", "model.compile(optimizer='adam', loss='mean_squared_error')\n", "\n", "checkpoint_path = \"lstm_4rtu_smooth_04.keras\"\n", "checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n", "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=5, batch_size=64, verbose=1, callbacks=[checkpoint_callback])" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 1/5\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 8.9528e-04\n", "Epoch 1: val_loss did not improve from 0.19006\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m239s\u001b[0m 30ms/step - loss: 8.9529e-04 - val_loss: 0.2020\n", "Epoch 2/5\n", "\u001b[1m8060/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 8.0121e-04\n", "Epoch 2: val_loss improved from 0.19006 to 0.18934, saving model to lstm_4rtu_smooth_03.keras\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m234s\u001b[0m 29ms/step - loss: 8.0122e-04 - val_loss: 0.1893\n", "Epoch 3/5\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 9.8454e-04\n", "Epoch 3: val_loss did not improve from 0.18934\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m231s\u001b[0m 29ms/step - loss: 9.8453e-04 - val_loss: 0.2004\n", "Epoch 4/5\n", "\u001b[1m8060/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 7.8113e-04\n", "Epoch 4: val_loss did not improve from 0.18934\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m232s\u001b[0m 29ms/step - loss: 7.8114e-04 - val_loss: 0.2031\n", "Epoch 5/5\n", "\u001b[1m8059/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 19ms/step - loss: 8.8365e-04\n", "Epoch 5: val_loss did not improve from 0.18934\n", "\u001b[1m8061/8061\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m234s\u001b[0m 29ms/step - loss: 8.8360e-04 - val_loss: 0.1915\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=5, batch_size=64, verbose=1, callbacks=[checkpoint_callback])" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "from tensorflow.keras.models import load_model\n", "checkpoint_path = \"lstm_2rtu_smooth_03.keras\"\n", "model = load_model(checkpoint_path)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[1m19190/19190\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m80s\u001b[0m 4ms/step\n", "\u001b[1m16134/16134\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m65s\u001b[0m 4ms/step\n" ] } ], "source": [ "test_predict1 = model.predict(X_test)\n", "train_predict1 = model.predict(X_train)" ] }, { "cell_type": "code", "execution_count": 148, "metadata": {}, "outputs": [], "source": [ "%matplotlib qt\n", "var = 5\n", "plt.plot(testdataset_df['date'][31:], y_test[:,var], label='Original Testing Data')\n", "plt.plot(testdataset_df['date'][31:] ,test_predict1[:,var], label='Predicted Testing Data')\n", "\n", "# anomalies = np.where(abs(test_predict1[:,var] - y_test[:,var]) > 0.38)\n", "# plt.scatter(anomalies,test_predict1[anomalies,var], color='black',marker =\"o\",s=100 )\n", "\n", "\n", "plt.title('Testing Data - Predicted vs Actual')\n", "plt.xlabel('Time')\n", "plt.ylabel('Value')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [], "source": [ "params = [\n", " 'rtu_003_sa_temp',\n", " 'rtu_003_oadmpr_pct',\n", " 'rtu_003_ra_temp',\n", " 'rtu_003_oa_temp',\n", " 'rtu_003_ma_temp',\n", " 'rtu_003_sf_vfd_spd_fbk_tn',\n", " 'rtu_003_rf_vfd_spd_fbk_tn']\n", "\n", "idx_2_params = {}\n", "for i, param in enumerate(params):\n", " idx_2_params[i] = param" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{0: 'rtu_003_sa_temp',\n", " 1: 'rtu_003_oadmpr_pct',\n", " 2: 'rtu_003_ra_temp',\n", " 3: 'rtu_003_oa_temp',\n", " 4: 'rtu_003_ma_temp',\n", " 5: 'rtu_003_sf_vfd_spd_fbk_tn',\n", " 6: 'rtu_003_rf_vfd_spd_fbk_tn'}" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idx_2_params" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "KMEANS" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "image/png": "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tvzcn3/+GcMwuPHGG3N8batUqULr1q1zfG0BypYtS+/evS1f/7LLLsNut597v1WrVgDnvsabN28mISGBa6+9NsfzatWqRbdu3SzfR6miTrftlCqCnnjiCdq0acP48eNxOBx89tlnOV40c4uNjWXw4MFMmTKF2rVrc9FFF1G7dm2XYw8ePMi2bdvcnsI7cuQIALt376Z79+40btyY119/nTp16hATE8OyZcu4++678wQV5cuXz3Ot6OjoHOPGjh1LbGwsn332Ge+++y52u50ePXrw4osv0qFDB7efX61atdi6dSvJycnExsa6HecPb7zxBjVq1ODLL7/kxRdfJCYmhn79+vF///d/NGzY0ONzDx48iGmaObbmsqtXr16O9z1tx7qS+2scHR0NcO5r7NxadHX/ypUrs2PHDp/up1RRpcGTUkXUuHHjMAyDcePG4XA4mDZtGhER7v/Jjxw5ksmTJ7N27VqmTZvmdlyFChUoUaJEnpyl7B8H+P7770lOTmbGjBk5ArHVq1fn7xMCIiIiGDNmDGPGjOHEiRP8/vvvPProo/Tr1489e/ZQsmRJl8/r168fs2fP5qeffuK6667L172jo6Nd5v04Aw6n2NhYxo0bx7hx4zh48OC5VagBAwawadMmj/eoUKEChmEwf/78c4FN7jlk5+9aVM7g6uDBg3k+lpCQ4Nd7KRXOdNtOqSLs6aefZty4cXz11VcMGTKE9PR0t2O7dOnCyJEjueKKK7jiiivcjuvfvz///fcf5cuXp0OHDnnenCeynC/s2V/wTdPkgw8+8MvnVqZMGa6++mruvvtujh07du60mis333wzVapU4eGHH2bfvn0ux8yYMcPj/erUqcPatWtzPDZ37lxOnTrl9jmVK1dm+PDhXH/99WzevJmUlBQg74qPk7MO1b59+1x+bd2dmPSXxo0bU6VKFb766qscj+/evZtFixYF9N5KhRNdeVKqiHvyySex2Ww88cQTmKbJ9OnT3a5Affjhh16vN3r0aL799lt69OjB/fffT6tWrXA4HOzevZvZs2fzwAMP0KlTJ/r06UNUVBTXX389Dz/8MGfOnOGdd94pUCHKAQMG0KJFCzp06EDFihXZtWsXEydOpHbt2h63xOLj4/nhhx/o378/bdu2zVEkc+vWrXz22WesWbOGK6+80u01hg4dyhNPPMGTTz5Jz5492bBh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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from sklearn.cluster import KMeans\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from sklearn.decomposition import PCA\n", "\n", "np.random.seed(0)\n", "X1 = train_predict1[:,1:8] - y_train[:,1:8]\n", "X2 = train_predict1[:,8:15] - y_train[:,8:15]\n", "# X3 = train_predict1[:,15:22] - y_train[:,15:22]\n", "# X4 = train_predict1[:,22:29] - y_train[:,22:29]\n", "\n", "k = 1\n", "\n", "pca1 = PCA(n_components=2)\n", "X1 = pca1.fit_transform(X1)\n", "pca2 = PCA(n_components=2)\n", "X2 = pca2.fit_transform(X2)\n", "\n", "kmeans1 = KMeans(n_clusters=k, random_state=10) #2 for without smoothing\n", "kmeans1.fit(X1)\n", "kmeans2 = KMeans(n_clusters=k, random_state=10) #2 for without smoothing\n", "kmeans2.fit(X2)\n", "# kmeans3 = KMeans(n_clusters=k, random_state=10) #2 for without smoothing\n", "# kmeans3.fit(X1)\n", "# kmeans4 = KMeans(n_clusters=k, random_state=10) #2 for without smoothing\n", "# kmeans4.fit(X2)\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "# # # Getting the cluster centers and labels\n", "# centroids = pca.transform(kmeans1.cluster_centers_)\n", "labels = kmeans1.labels_\n", "# print(kmeans1.cluster_centers_)\n", "# # Plotting the data points and cluster centers\n", "plt.scatter(X1[:, 0], X1[:, 1],c=labels, cmap='rainbow')\n", "plt.scatter(kmeans1.cluster_centers_[:, 0], kmeans1.cluster_centers_[:, 1], marker='x', c='red', s=200, linewidths=2)\n", "plt.title('KMeans Clustering')\n", "plt.xlabel('Feature 1')\n", "plt.ylabel('Feature 2')\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['pca_rtu_4.pkl']" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import joblib\n", "joblib.dump(kmeans1, 'kmeans_rtu_3.pkl')\n", "joblib.dump(kmeans2, 'kmeans_rtu_4.pkl')\n", "joblib.dump(pca1, 'pca_rtu_3.pkl')\n", "joblib.dump(pca2, 'pca_rtu_4.pkl')\n" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 132, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# [ params[i] for i in np.flip(np.argsort(abs(kmeans1.cluster_centers_[0])))]\n", "distance1 = np.linalg.norm((pca1.transform(train_predict1[:,1:8]-y_train[:,1:8]))-kmeans1.cluster_centers_[0], ord=2, axis = 1)\n", "plt.plot(y_train[:,7])\n", "plt.plot(abs(distance1)>1,c='r')" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [], "source": [ "XX1 = pca1.transform(test_predict1[:,1:8][300000:]-y_test[:,1:8][300000:])\n", "distance1 = np.linalg.norm(XX1-kmeans1.cluster_centers_[0], ord=2, axis = 1)\n", "plt.scatter(XX1[:, 0], XX1[:, 1],c=abs(distance1)>1, cmap='rainbow',s=2)\n", "plt.scatter(kmeans1.cluster_centers_[:, 0], kmeans1.cluster_centers_[:, 1], marker='x', c='green', s=20, linewidths=2)\n", "plt.title('KMeans Clustering')\n", "plt.xlabel('Feature 1')\n", "plt.ylabel('Feature 2')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [], "source": [ "%matplotlib qt\n", "\n", "distance1 = np.linalg.norm((pca1.transform(test_predict1[:,1:8]-y_test[:,1:8]))-kmeans1.cluster_centers_[0], ord=2, axis = 1)\n", "distance2 = np.linalg.norm((pca2.transform(test_predict1[:,8:15]-y_test[:,8:15]))-kmeans2.cluster_centers_[0], ord=2, axis = 1)\n", "# distance2 = np.linalg.norm((test_predict1[:,8:15]-y_test[:,8:15])-kmeans2.cluster_centers_[0], ord=2, axis = 1)\n", "# distance3 = np.linalg.norm((test_predict1[:,15:22]-y_test[:,15:22])-kmeans3.cluster_centers_[0], ord=2, axis = 1)\n", "# distance4 = np.linalg.norm((test_predict1[:,22:29]-y_test[:,22:29])-kmeans4.cluster_centers_[0], ord=2, axis = 1)\n", "# distance_a = np.linalg.norm(test_predict1[:,8:]-a, ord=2, axis = 1)\n", "# plt.plot(y_test[:,23],alpha=0.6)\n", "# plt.plot(y_test[:,7],alpha=0.6)\n", "# plt.plot(y_test[:,6],alpha=0.6)\n", "plt.plot(testdataset_df['date'][31:] ,y_test[:,7],label='Return air fan speed')\n", "# plt.plot(testdataset_df['date'][31:] ,y_test[:,9],alpha=0.6,label='Damper position')\n", "# plt.plot(test_predict1[:,3],alpha=0.6)\n", "plt.plot(testdataset_df['date'][31:] ,abs(distance1)>1,linewidth=2.5,label='Faults')\n", "# plt.plot(testdataset_df['date'][31:] ,pd.Series((distance1)>3.5).rolling(window=60,min_periods=1).mean()==1,linewidth=2.5,label='Faults')\n", "# plt.plot(abs(distance2)>3.5)\n", "# plt.plot(abs(distance3)>5)\n", "# plt.plot(abs(distance4)>5)\n", "# plt.plot(distance_a>8,c='g')\n", "plt.title('RTU-2 Faults')\n", "plt.xlabel('Time')\n", "plt.ylabel('Value')\n", "plt.legend()\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 277, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 277, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# fault = []\n", "# for i in range(60,len(distance4)):\n", "# if np.mean((abs(distance4)>5)[i-60:i])>0.60 :\n", "# fault.append(1)\n", "# else:\n", "# fault.append(0)\n", "plt.plot(fault,c='r')\n", "plt.plot(abs(distance4)>5,c='b')\n" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 126, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test[:,23]\n", "arr = test[:, 23]\n", "condition = (arr < 5) & (np.arange(len(arr)) < 35000) & (np.arange(len(arr)) > 30000)\n", "arr[condition] = 2\n", "plt.plot(test[:,23])\n" ] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [], "source": [ "distance2 = np.linalg.norm((test_predict1[:,8:15]-y_test[:,8:15])-kmeans2.cluster_centers_[0], ord=2, axis = 1)\n", "X = pca.transform((test_predict1[:,8:15]-y_test[:,8:15])-kmeans2.cluster_centers_[0])\n", "centroids = pca.transform(kmeans2.cluster_centers_)\n", "\n", "plt.scatter(X[:, 0], X[:, 1], c = abs(distance2)>10 ,cmap='viridis', alpha=0.5)\n", "plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', c='red', s=200, linewidths=2)\n", "plt.title('KMeans Clustering')\n", "plt.xlabel('Feature 1')\n", "plt.ylabel('Feature 2')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 155, "metadata": {}, "outputs": [], "source": [ "k = 60\n", "X= test_predict1 - y_test\n", "processed_data = []\n", "feat_df = pd.DataFrame(columns=[\"mean\",\"std\",])\n", "for i in range(0,len(X), 40 ):\n", " mean = X[i:i+k].mean(axis = 0)\n", " std = X[i:i+k].std(axis = 0)\n", " max = X[i:i+k].max(axis = 0)\n", " min = X[i:i+k].min(axis = 0)\n", " iqr = np.percentile(X[i:i+k], 75, axis=0) - np.percentile(X[i:i+k], 25,axis=0)\n", " data = np.concatenate([mean, std, max, min, iqr])\n", " processed_data.append([data])\n", "processed_data = np.concatenate(processed_data,axis=0) " ] }, { "cell_type": "code", "execution_count": 154, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'processed_data' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[154], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m X \u001b[38;5;241m=\u001b[39m \u001b[43mprocessed_data\u001b[49m\n\u001b[0;32m 4\u001b[0m k \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m\n\u001b[0;32m 6\u001b[0m kmeans \u001b[38;5;241m=\u001b[39m KMeans(n_clusters\u001b[38;5;241m=\u001b[39mk,random_state\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m4\u001b[39m)\n", "\u001b[1;31mNameError\u001b[0m: name 'processed_data' is not defined" ] } ], "source": [ "X = processed_data\n", "\n", "\n", "k = 2\n", "\n", "kmeans = KMeans(n_clusters=k,random_state=4)\n", "\n", "kmeans.fit(X)\n", "\n", "pca = PCA(n_components=2)\n", "X = pca.fit_transform(X)\n", "\n", "centroids = pca.transform(kmeans.cluster_centers_)\n", "labels = kmeans.labels_\n", "\n", "# Plotting the data points and cluster centers\n", "plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.5)\n", "plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', c='red', s=200, linewidths=2)\n", "plt.title('KMeans Clustering')\n", "plt.xlabel('Feature 1')\n", "plt.ylabel('Feature 2')\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.76482953e-02, -4.84286715e-03],\n", " [ 2.35918490e+01, 6.47383719e+00]])" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "kmeans.cluster_centers_" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "operands could not be broadcast together with shapes (481579,2) (15,) ", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[123], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m distance \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mlinalg\u001b[38;5;241m.\u001b[39mnorm(\u001b[43mpca\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtransform\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtest_predict1\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m-\u001b[39;49m\u001b[43mkmeans\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcluster_centers_\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m, \u001b[38;5;28mord\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m, axis \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m)\n\u001b[0;32m 2\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(y_test[:,\u001b[38;5;241m6\u001b[39m])\n\u001b[0;32m 3\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(distance\u001b[38;5;241m>\u001b[39m\u001b[38;5;241m50\u001b[39m,c\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mr\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", "\u001b[1;31mValueError\u001b[0m: operands could not be broadcast together with shapes (481579,2) (15,) " ] } ], "source": [ "distance = np.linalg.norm(pca.transform(test_predict1)-kmeans.cluster_centers_[1], ord=2, axis = 1)\n", "plt.plot(y_test[:,6])\n", "plt.plot(distance>50,c='r')" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [], "source": [ "from sklearn.mixture import GaussianMixture\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "X = X1\n", "\n", "\n", "gmm = GaussianMixture(n_components=3,random_state=10)\n", "gmm.fit(X)\n", "labels = gmm.predict(X)\n", "\n", "\n", "plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.5)\n", "plt.title('GMM Clustering')\n", "plt.xlabel('Feature 1')\n", "plt.ylabel('Feature 2')\n", "plt.show()\n" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [], "source": [ "XX1 = pca.transform(test_predict1[:,1:8])-pca.transform(y_test[:,1:8])\n", "labels = gmm.predict(XX1)" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import seaborn as sns\n", "\n", "b = np.linspace(0,len(y_test),len(y_test))\n", "sns.scatterplot(x=b,y=y_test[:,6],palette='bright',hue=labels,size=0.5)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datehp_hws_temprtu_001_sa_temprtu_001_oadmpr_pctrtu_001_ra_temprtu_001_oa_temprtu_001_ma_temprtu_001_sf_vfd_spd_fbk_tnrtu_001_rf_vfd_spd_fbk_tnrtu_002_sa_temp...rtu_002_ma_temprtu_002_sf_vfd_spd_fbk_tnrtu_002_rf_vfd_spd_fbk_tnrtu_001_sat_sp_tnrtu_002_sat_sp_tnair_temp_set_1air_temp_set_2dew_point_temperature_set_1drelative_humidity_set_1solar_radiation_set_1
1558492018-05-02 00:00:0091.568.546.873.463.264.875.563.068.2...69.276.460.368.068.014.914.447.0259.50335.9
1558502018-05-02 00:01:0091.468.746.873.463.464.979.261.769.5...68.979.059.168.068.014.914.447.0259.50335.9
1558512018-05-02 00:02:0091.368.546.873.363.164.775.758.167.9...64.676.355.368.068.014.914.447.0259.50335.9
1558522018-05-02 00:03:0091.268.646.873.463.464.775.663.666.9...65.376.157.068.068.014.914.447.0259.50335.9
1558532018-05-02 00:04:0091.468.746.873.463.165.079.167.667.9...68.479.759.768.068.014.914.447.0259.50335.9
..................................................................
7142402019-07-20 23:55:00122.566.4100.072.368.760.575.365.763.9...64.675.652.666.065.019.515.7211.8361.38604.2
7142412019-07-20 23:56:00123.065.698.272.467.960.075.556.764.6...64.276.056.966.065.019.515.7211.8361.38604.2
7142422019-07-20 23:57:00123.365.198.272.467.359.775.557.664.9...64.676.361.366.065.019.515.7211.8361.38604.2
7142432019-07-20 23:58:00123.265.498.272.467.060.372.852.865.4...65.074.357.466.065.019.515.7211.8361.38604.2
7142442019-07-20 23:59:00123.165.798.272.466.960.775.256.565.5...65.075.453.466.065.019.515.7211.8361.38604.2
\n", "

516309 rows × 23 columns

\n", "
" ], "text/plain": [ " date hp_hws_temp rtu_001_sa_temp rtu_001_oadmpr_pct \\\n", "155849 2018-05-02 00:00:00 91.5 68.5 46.8 \n", "155850 2018-05-02 00:01:00 91.4 68.7 46.8 \n", "155851 2018-05-02 00:02:00 91.3 68.5 46.8 \n", "155852 2018-05-02 00:03:00 91.2 68.6 46.8 \n", "155853 2018-05-02 00:04:00 91.4 68.7 46.8 \n", "... ... ... ... ... \n", "714240 2019-07-20 23:55:00 122.5 66.4 100.0 \n", "714241 2019-07-20 23:56:00 123.0 65.6 98.2 \n", "714242 2019-07-20 23:57:00 123.3 65.1 98.2 \n", "714243 2019-07-20 23:58:00 123.2 65.4 98.2 \n", "714244 2019-07-20 23:59:00 123.1 65.7 98.2 \n", "\n", " rtu_001_ra_temp rtu_001_oa_temp rtu_001_ma_temp \\\n", "155849 73.4 63.2 64.8 \n", "155850 73.4 63.4 64.9 \n", "155851 73.3 63.1 64.7 \n", "155852 73.4 63.4 64.7 \n", "155853 73.4 63.1 65.0 \n", "... ... ... ... \n", "714240 72.3 68.7 60.5 \n", "714241 72.4 67.9 60.0 \n", "714242 72.4 67.3 59.7 \n", "714243 72.4 67.0 60.3 \n", "714244 72.4 66.9 60.7 \n", "\n", " rtu_001_sf_vfd_spd_fbk_tn rtu_001_rf_vfd_spd_fbk_tn rtu_002_sa_temp \\\n", "155849 75.5 63.0 68.2 \n", "155850 79.2 61.7 69.5 \n", "155851 75.7 58.1 67.9 \n", "155852 75.6 63.6 66.9 \n", "155853 79.1 67.6 67.9 \n", "... ... ... ... \n", "714240 75.3 65.7 63.9 \n", "714241 75.5 56.7 64.6 \n", "714242 75.5 57.6 64.9 \n", "714243 72.8 52.8 65.4 \n", "714244 75.2 56.5 65.5 \n", "\n", " ... rtu_002_ma_temp rtu_002_sf_vfd_spd_fbk_tn \\\n", "155849 ... 69.2 76.4 \n", "155850 ... 68.9 79.0 \n", "155851 ... 64.6 76.3 \n", "155852 ... 65.3 76.1 \n", "155853 ... 68.4 79.7 \n", "... ... ... ... \n", "714240 ... 64.6 75.6 \n", "714241 ... 64.2 76.0 \n", "714242 ... 64.6 76.3 \n", "714243 ... 65.0 74.3 \n", "714244 ... 65.0 75.4 \n", "\n", " rtu_002_rf_vfd_spd_fbk_tn rtu_001_sat_sp_tn rtu_002_sat_sp_tn \\\n", "155849 60.3 68.0 68.0 \n", "155850 59.1 68.0 68.0 \n", "155851 55.3 68.0 68.0 \n", "155852 57.0 68.0 68.0 \n", "155853 59.7 68.0 68.0 \n", "... ... ... ... \n", "714240 52.6 66.0 65.0 \n", "714241 56.9 66.0 65.0 \n", "714242 61.3 66.0 65.0 \n", "714243 57.4 66.0 65.0 \n", "714244 53.4 66.0 65.0 \n", "\n", " air_temp_set_1 air_temp_set_2 dew_point_temperature_set_1d \\\n", "155849 14.9 14.44 7.02 \n", "155850 14.9 14.44 7.02 \n", "155851 14.9 14.44 7.02 \n", "155852 14.9 14.44 7.02 \n", "155853 14.9 14.44 7.02 \n", "... ... ... ... \n", "714240 19.5 15.72 11.83 \n", "714241 19.5 15.72 11.83 \n", "714242 19.5 15.72 11.83 \n", "714243 19.5 15.72 11.83 \n", "714244 19.5 15.72 11.83 \n", "\n", " relative_humidity_set_1 solar_radiation_set_1 \n", "155849 59.50 335.9 \n", "155850 59.50 335.9 \n", "155851 59.50 335.9 \n", "155852 59.50 335.9 \n", "155853 59.50 335.9 \n", "... ... ... \n", "714240 61.38 604.2 \n", "714241 61.38 604.2 \n", "714242 61.38 604.2 \n", "714243 61.38 604.2 \n", "714244 61.38 604.2 \n", "\n", "[516309 rows x 23 columns]" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "traindataset_df" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "smartbuilding", "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.11.8" } }, "nbformat": 4, "nbformat_minor": 2 }