jerin commited on
Commit
66977cd
1 Parent(s): a3fdea5

add seperate RTU anomalizer

Browse files
mqttpublisher.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
src/main.py CHANGED
@@ -1,5 +1,6 @@
1
  import json
2
- from rtu.RTUAnomalizer import RTUAnomalizer
 
3
  from rtu.RTUPipeline import RTUPipeline
4
  from vav.VAVPipeline import VAVPipeline
5
  from vav.VAVAnomalizer import VAVAnomalizer
@@ -7,32 +8,42 @@ import paho.mqtt.client as mqtt
7
 
8
 
9
  def main():
10
- rtu_data_pipeline = RTUPipeline(scaler_path="src/rtu/models/scaler_1.pkl")
11
- rtu_anomalizer = RTUAnomalizer(
12
- prediction_model_path="src/rtu/models/lstm_4rtu_smooth_02.keras",
 
13
  clustering_model_paths=[
14
- "src/rtu/models/kmeans_model1.pkl",
15
- "src/rtu/models/kmeans_model2.pkl",
16
- "src/rtu/models/kmeans_model3.pkl",
17
- "src/rtu/models/kmeans_model4.pkl",
 
 
 
 
 
 
 
 
18
  ],
19
  num_inputs=rtu_data_pipeline.num_inputs,
20
  num_outputs=rtu_data_pipeline.num_outputs,
21
  )
22
 
23
- vav_pipeline = VAVPipeline(rtu_id=1, scaler_path="src/vav/models/scaler_vav_1.pkl")
24
 
25
- vav_anomalizer = VAVAnomalizer(prediction_model_path="src/vav/models/lstm__vav_01")
26
  # print(vav_pipeline.input_col_names)
27
 
28
  # print(len(vav_pipeline.output_col_names))
29
 
30
  def on_message(client, userdata, message):
31
  # print(json.loads(message.payload.decode()))
32
- df_new, df_trans = rtu_data_pipeline.fit(message)
33
- if not df_new is None and not df_trans is None:
34
- out1,out2,out3,out4 = rtu_anomalizer.pipeline(df_new, df_trans, rtu_data_pipeline.scaler)
35
- print(out3)
 
36
 
37
  broker_address = "localhost"
38
  broker_port = 1883
 
1
  import json
2
+ from rtu.RTUAnomalizer1 import RTUAnomalizer1
3
+ from rtu.RTUAnomalizer2 import RTUAnomalizer2
4
  from rtu.RTUPipeline import RTUPipeline
5
  from vav.VAVPipeline import VAVPipeline
6
  from vav.VAVAnomalizer import VAVAnomalizer
 
8
 
9
 
10
  def main():
11
+ rtu_data_pipeline = RTUPipeline(scaler1_path="src/rtu/models/scaler_rtu_1_2.pkl",scaler2_path="src/rtu/models/scaler_rtu_3_4.pkl")
12
+ #RTU - 1, 2
13
+ rtu_anomalizer1 = RTUAnomalizer1(
14
+ prediction_model_path="src/rtu/models/lstm_2rtu_smooth_04.keras",
15
  clustering_model_paths=[
16
+ "src/rtu/models/kmeans_rtu_1.pkl",
17
+ "src/rtu/models/kmeans_rtu_2.pkl",
18
+ ],
19
+ num_inputs=rtu_data_pipeline.num_inputs,
20
+ num_outputs=rtu_data_pipeline.num_outputs,
21
+ )
22
+ #RTU - 3,4
23
+ rtu_anomalizer2 = RTUAnomalizer2(
24
+ prediction_model_path="src/rtu/models/lstm_2rtu_smooth_03.keras",
25
+ clustering_model_paths=[
26
+ "src/rtu/models/kmeans_rtu_3.pkl",
27
+ "src/rtu/models/kmeans_rtu_4.pkl",
28
  ],
29
  num_inputs=rtu_data_pipeline.num_inputs,
30
  num_outputs=rtu_data_pipeline.num_outputs,
31
  )
32
 
33
+ # vav_pipeline = VAVPipeline(rtu_id=1, scaler_path="src/vav/models/scaler_vav_1.pkl")
34
 
35
+ # vav_anomalizer = VAVAnomalizer(prediction_model_path="src/vav/models/lstm__vav_01")
36
  # print(vav_pipeline.input_col_names)
37
 
38
  # print(len(vav_pipeline.output_col_names))
39
 
40
  def on_message(client, userdata, message):
41
  # print(json.loads(message.payload.decode()))
42
+ df_new1, df_trans1, df_new2, df_trans2 = rtu_data_pipeline.fit(message)
43
+ if not df_new1 is None and not df_trans1 is None and not df_new2 is None and not df_trans2 is None:
44
+ out1,out2,out3,out4 = rtu_anomalizer1.pipeline(df_new1, df_trans1, rtu_data_pipeline.scaler1)
45
+ out5,out6,out7,out8 = rtu_anomalizer2.pipeline(df_new2, df_trans2, rtu_data_pipeline.scaler2)
46
+ print(out2)
47
 
48
  broker_address = "localhost"
49
  broker_port = 1883
src/rtu/{RTUAnomalizer.py → RTUAnomalizer1.py} RENAMED
@@ -3,7 +3,7 @@ from tensorflow.keras.models import load_model
3
  import joblib
4
 
5
 
6
- class RTUAnomalizer:
7
  """
8
  Class for performing anomaly detection on RTU (Roof Top Unit) data.
9
  """
@@ -31,6 +31,7 @@ class RTUAnomalizer:
31
  self.num_outputs = num_outputs
32
  if prediction_model_path is not None and clustering_model_paths is not None:
33
  self.load_models(prediction_model_path, clustering_model_paths)
 
34
 
35
  def initialize_lists(self, size=30):
36
  """
@@ -42,7 +43,7 @@ class RTUAnomalizer:
42
  Returns:
43
  tuple: A tuple containing three lists initialized with zeros.
44
  """
45
- initial_values = [0] * size
46
  return initial_values.copy(), initial_values.copy(), initial_values.copy()
47
 
48
  def load_models(self, prediction_model_path, clustering_model_paths):
@@ -68,7 +69,7 @@ class RTUAnomalizer:
68
  Returns:
69
  array: Predicted values.
70
  """
71
- return self.model.predict(df_new)
72
 
73
  def calculate_residuals(self, df_trans, pred):
74
  """
@@ -120,7 +121,7 @@ class RTUAnomalizer:
120
  actual = scaler.inverse_transform(np.array([df_trans[30, :]]))
121
  return actual, pred
122
 
123
- def update_lists(self, actual_list, pred_list, resid_list, actual, pred, resid):
124
  """
125
  Update the lists of actual, predicted, and residual values.
126
 
@@ -135,13 +136,13 @@ class RTUAnomalizer:
135
  Returns:
136
  tuple: A tuple containing the updated lists of actual, predicted, and residual values.
137
  """
138
- actual_list.pop(0)
139
- pred_list.pop(0)
140
- resid_list.pop(0)
141
- actual_list.append(actual[0, 1])
142
- pred_list.append(pred[0, 1])
143
- resid_list.append(resid[0, 1])
144
- return actual_list, pred_list, resid_list
145
 
146
  def calculate_distances(self, resid):
147
  """
@@ -177,13 +178,12 @@ class RTUAnomalizer:
177
  Returns:
178
  tuple: A tuple containing the lists of actual, predicted, and residual values, and the distances.
179
  """
180
- actual_list, pred_list, resid_list = self.initialize_lists()
181
  pred = self.predict(df_new)
182
  actual, resid = self.calculate_residuals(df_trans, pred)
183
  pred = self.resize_prediction(pred, df_trans)
184
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
185
  actual_list, pred_list, resid_list = self.update_lists(
186
- actual_list, pred_list, resid_list, actual, pred, resid
187
- )
188
  dist = self.calculate_distances(resid)
189
  return actual_list, pred_list, resid_list, dist
 
3
  import joblib
4
 
5
 
6
+ class RTUAnomalizer1:
7
  """
8
  Class for performing anomaly detection on RTU (Roof Top Unit) data.
9
  """
 
31
  self.num_outputs = num_outputs
32
  if prediction_model_path is not None and clustering_model_paths is not None:
33
  self.load_models(prediction_model_path, clustering_model_paths)
34
+ self.actual_list, self.pred_list, self.resid_list = self.initialize_lists()
35
 
36
  def initialize_lists(self, size=30):
37
  """
 
43
  Returns:
44
  tuple: A tuple containing three lists initialized with zeros.
45
  """
46
+ initial_values = [[0]*self.num_outputs] * size
47
  return initial_values.copy(), initial_values.copy(), initial_values.copy()
48
 
49
  def load_models(self, prediction_model_path, clustering_model_paths):
 
69
  Returns:
70
  array: Predicted values.
71
  """
72
+ return self.model.predict(df_new,verbose=0)
73
 
74
  def calculate_residuals(self, df_trans, pred):
75
  """
 
121
  actual = scaler.inverse_transform(np.array([df_trans[30, :]]))
122
  return actual, pred
123
 
124
+ def update_lists(self, actual, pred, resid):
125
  """
126
  Update the lists of actual, predicted, and residual values.
127
 
 
136
  Returns:
137
  tuple: A tuple containing the updated lists of actual, predicted, and residual values.
138
  """
139
+ self.actual_list.pop(0)
140
+ self.pred_list.pop(0)
141
+ self.resid_list.pop(0)
142
+ self.actual_list.append(actual.flatten().tolist())
143
+ self.pred_list.append(pred.flatten().tolist())
144
+ self.resid_list.append(resid.flatten().tolist())
145
+ return self.actual_list, self.pred_list, self.resid_list
146
 
147
  def calculate_distances(self, resid):
148
  """
 
178
  Returns:
179
  tuple: A tuple containing the lists of actual, predicted, and residual values, and the distances.
180
  """
181
+
182
  pred = self.predict(df_new)
183
  actual, resid = self.calculate_residuals(df_trans, pred)
184
  pred = self.resize_prediction(pred, df_trans)
185
  actual, pred = self.inverse_transform(scaler, pred, df_trans)
186
  actual_list, pred_list, resid_list = self.update_lists(
187
+ actual, pred, resid)
 
188
  dist = self.calculate_distances(resid)
189
  return actual_list, pred_list, resid_list, dist
src/rtu/RTUAnomalizer2.py ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from tensorflow.keras.models import load_model
3
+ import joblib
4
+
5
+
6
+ class RTUAnomalizer2:
7
+ """
8
+ Class for performing anomaly detection on RTU (Roof Top Unit) data.
9
+ """
10
+
11
+ model = None
12
+ kmeans_models = []
13
+
14
+ def __init__(
15
+ self,
16
+ prediction_model_path=None,
17
+ clustering_model_paths=None,
18
+ num_inputs=None,
19
+ num_outputs=None,
20
+ ):
21
+ """
22
+ Initialize the RTUAnomalizer object.
23
+
24
+ Args:
25
+ prediction_model_path (str): Path to the prediction model file.
26
+ clustering_model_paths (list): List of paths to the clustering model files.
27
+ num_inputs (int): Number of input features.
28
+ num_outputs (int): Number of output features.
29
+ """
30
+ self.num_inputs = num_inputs
31
+ self.num_outputs = num_outputs
32
+ if prediction_model_path is not None and clustering_model_paths is not None:
33
+ self.load_models(prediction_model_path, clustering_model_paths)
34
+ self.actual_list, self.pred_list, self.resid_list = self.initialize_lists()
35
+
36
+ def initialize_lists(self, size=30):
37
+ """
38
+ Initialize lists for storing actual, predicted, and residual values.
39
+
40
+ Args:
41
+ size (int): Size of the lists.
42
+
43
+ Returns:
44
+ tuple: A tuple containing three lists initialized with zeros.
45
+ """
46
+ initial_values = [[0]*self.num_outputs] * size
47
+ return initial_values.copy(), initial_values.copy(), initial_values.copy()
48
+
49
+ def load_models(self, prediction_model_path, clustering_model_paths):
50
+ """
51
+ Load the prediction and clustering models.
52
+
53
+ Args:
54
+ prediction_model_path (str): Path to the prediction model file.
55
+ clustering_model_paths (list): List of paths to the clustering model files.
56
+ """
57
+ self.model = load_model(prediction_model_path)
58
+
59
+ for path in clustering_model_paths:
60
+ self.kmeans_models.append(joblib.load(path))
61
+
62
+ def predict(self, df_new):
63
+ """
64
+ Make predictions using the prediction model.
65
+
66
+ Args:
67
+ df_new (DataFrame): Input data for prediction.
68
+
69
+ Returns:
70
+ array: Predicted values.
71
+ """
72
+ return self.model.predict(df_new,verbose=0)
73
+
74
+ def calculate_residuals(self, df_trans, pred):
75
+ """
76
+ Calculate the residuals between actual and predicted values.
77
+
78
+ Args:
79
+ df_trans (DataFrame): Transformed input data.
80
+ pred (array): Predicted values.
81
+
82
+ Returns:
83
+ tuple: A tuple containing the actual values and residuals.
84
+ """
85
+ actual = df_trans[30, : self.num_outputs]
86
+ resid = actual - pred
87
+ return actual, resid
88
+
89
+ def resize_prediction(self, pred, df_trans):
90
+ """
91
+ Resize the predicted values to match the shape of the transformed input data.
92
+
93
+ Args:
94
+ pred (array): Predicted values.
95
+ df_trans (DataFrame): Transformed input data.
96
+
97
+ Returns:
98
+ array: Resized predicted values.
99
+ """
100
+ pred = np.resize(
101
+ pred, (pred.shape[0], pred.shape[1] + len(df_trans[30, self.num_outputs :]))
102
+ )
103
+ pred[:, -len(df_trans[30, self.num_outputs :]) :] = df_trans[
104
+ 30, self.num_outputs :
105
+ ]
106
+ return pred
107
+
108
+ def inverse_transform(self, scaler, pred, df_trans):
109
+ """
110
+ Inverse transform the predicted and actual values.
111
+
112
+ Args:
113
+ scaler (object): Scaler object for inverse transformation.
114
+ pred (array): Predicted values.
115
+ df_trans (DataFrame): Transformed input data.
116
+
117
+ Returns:
118
+ tuple: A tuple containing the actual and predicted values after inverse transformation.
119
+ """
120
+ pred = scaler.inverse_transform(np.array(pred))
121
+ actual = scaler.inverse_transform(np.array([df_trans[30, :]]))
122
+ return actual, pred
123
+
124
+ def update_lists(self, actual, pred, resid):
125
+ """
126
+ Update the lists of actual, predicted, and residual values.
127
+
128
+ Args:
129
+ actual_list (list): List of actual values.
130
+ pred_list (list): List of predicted values.
131
+ resid_list (list): List of residual values.
132
+ actual (array): Actual values.
133
+ pred (array): Predicted values.
134
+ resid (array): Residual values.
135
+
136
+ Returns:
137
+ tuple: A tuple containing the updated lists of actual, predicted, and residual values.
138
+ """
139
+ self.actual_list.pop(0)
140
+ self.pred_list.pop(0)
141
+ self.resid_list.pop(0)
142
+ self.actual_list.append(actual.flatten().tolist())
143
+ self.pred_list.append(pred.flatten().tolist())
144
+ self.resid_list.append(resid.flatten().tolist())
145
+ return self.actual_list, self.pred_list, self.resid_list
146
+
147
+ def calculate_distances(self, resid):
148
+ """
149
+ Calculate the distances between residuals and cluster centers.
150
+
151
+ Args:
152
+ resid (array): Residual values.
153
+
154
+ Returns:
155
+ array: Array of distances.
156
+ """
157
+ dist = []
158
+ for i, model in enumerate(self.kmeans_models):
159
+ dist.append(
160
+ np.linalg.norm(
161
+ resid[:, (i * 7) + 1 : (i * 7) + 8] - model.cluster_centers_[0],
162
+ ord=2,
163
+ axis=1,
164
+ )
165
+ )
166
+
167
+ return np.array(dist)
168
+
169
+ def pipeline(self, df_new, df_trans, scaler):
170
+ """
171
+ Perform the anomaly detection pipeline.
172
+
173
+ Args:
174
+ df_new (DataFrame): Input data for prediction.
175
+ df_trans (DataFrame): Transformed input data.
176
+ scaler (object): Scaler object for inverse transformation.
177
+
178
+ Returns:
179
+ tuple: A tuple containing the lists of actual, predicted, and residual values, and the distances.
180
+ """
181
+
182
+ pred = self.predict(df_new)
183
+ actual, resid = self.calculate_residuals(df_trans, pred)
184
+ pred = self.resize_prediction(pred, df_trans)
185
+ actual, pred = self.inverse_transform(scaler, pred, df_trans)
186
+ actual_list, pred_list, resid_list = self.update_lists(
187
+ actual, pred, resid)
188
+ dist = self.calculate_distances(resid)
189
+ return actual_list, pred_list, resid_list, dist
src/rtu/RTUPipeline.py CHANGED
@@ -7,9 +7,10 @@ import numpy as np
7
 
8
 
9
  class RTUPipeline:
10
- scaler = None
 
11
 
12
- def __init__(self, rtus=[1, 2], scaler_path=None):
13
 
14
  outputs = [
15
  "sa_temp",
@@ -27,20 +28,28 @@ class RTUPipeline:
27
  for rtu in rtus:
28
  for output in outputs:
29
  self.output_col_names.append(f"rtu_00{rtu}_{output}")
 
 
 
 
 
30
 
31
- self.input_col_names = [
32
  "air_temp_set_1",
33
  "air_temp_set_2",
34
  "dew_point_temperature_set_1d",
35
  "relative_humidity_set_1",
36
  "solar_radiation_set_1",
37
  ]
38
- self.num_inputs = len(self.input_col_names)
39
- self.num_outputs = len(self.output_col_names)
40
  self.column_names = self.output_col_names + self.input_col_names
41
 
42
- if scaler_path:
43
- self.scaler = self.get_scaler(scaler_path)
 
 
 
44
  self.df = pd.DataFrame(columns=self.column_names)
45
 
46
  def get_scaler(self, scaler_path):
@@ -48,16 +57,20 @@ class RTUPipeline:
48
 
49
  def get_window(self, df):
50
  len_df = len(df)
 
51
  if len_df > 30:
 
52
  return df[len_df - 31 : len_df].astype("float32")
53
  else:
54
  return None
55
 
56
  def transform_window(self, df_window):
57
- return self.scaler.transform(df_window)
 
 
58
 
59
  def prepare_input(self, df_trans):
60
- return df_trans[:30, :].reshape((1, 30, len(self.column_names)))
61
 
62
  def extract_data_from_message(self, message):
63
  payload = json.loads(message.payload.decode())
@@ -74,9 +87,12 @@ class RTUPipeline:
74
  df = self.extract_data_from_message(message)
75
  df_window = self.get_window(df)
76
  if df_window is not None:
77
- df_trans = self.transform_window(df_window)
78
- df_new = self.prepare_input(df_trans)
 
79
  else:
80
- df_new = None
81
- df_trans = None
82
- return df_new, df_trans
 
 
 
7
 
8
 
9
  class RTUPipeline:
10
+ scaler1 = None # RTU 1,2
11
+ scaler2 = None # RTU 3,4
12
 
13
+ def __init__(self, rtus=[1, 2, 3, 4], scaler1_path=None,scaler2_path=None):
14
 
15
  outputs = [
16
  "sa_temp",
 
28
  for rtu in rtus:
29
  for output in outputs:
30
  self.output_col_names.append(f"rtu_00{rtu}_{output}")
31
+
32
+ self.input_col_names = []
33
+
34
+ for rtu in rtus:
35
+ self.input_col_names.append(f"rtu_00{rtu}_sat_sp_tn")
36
 
37
+ self.input_col_names = self.input_col_names + [
38
  "air_temp_set_1",
39
  "air_temp_set_2",
40
  "dew_point_temperature_set_1d",
41
  "relative_humidity_set_1",
42
  "solar_radiation_set_1",
43
  ]
44
+ self.num_inputs = len(self.input_col_names)-2
45
+ self.num_outputs = len(self.output_col_names)-14
46
  self.column_names = self.output_col_names + self.input_col_names
47
 
48
+ if scaler1_path:
49
+ self.scaler1 = self.get_scaler(scaler1_path)
50
+ if scaler2_path:
51
+ self.scaler2 = self.get_scaler(scaler2_path)
52
+
53
  self.df = pd.DataFrame(columns=self.column_names)
54
 
55
  def get_scaler(self, scaler_path):
 
57
 
58
  def get_window(self, df):
59
  len_df = len(df)
60
+ print(len_df)
61
  if len_df > 30:
62
+ df = df.rolling(window=30,min_periods=1).mean()
63
  return df[len_df - 31 : len_df].astype("float32")
64
  else:
65
  return None
66
 
67
  def transform_window(self, df_window):
68
+ columns_scaler1 = [0] + list(range(1,15)) + [29,30] + list(range(33, 38))
69
+ columns_scaler2 = [0] + list(range(15, 29)) + [31,32] + list(range(33, 38))
70
+ return self.scaler1.transform(df_window.iloc[:, columns_scaler1]),self.scaler2.transform(df_window.iloc[:, columns_scaler2])
71
 
72
  def prepare_input(self, df_trans):
73
+ return df_trans[:30, :].reshape((1, 30, len(self.column_names)-16))
74
 
75
  def extract_data_from_message(self, message):
76
  payload = json.loads(message.payload.decode())
 
87
  df = self.extract_data_from_message(message)
88
  df_window = self.get_window(df)
89
  if df_window is not None:
90
+ df_trans1,df_trans2 = self.transform_window(df_window)
91
+ df_new1 = self.prepare_input(df_trans1)
92
+ df_new2 = self.prepare_input(df_trans2)
93
  else:
94
+ df_new1 = None
95
+ df_trans1 = None
96
+ df_new2 = None
97
+ df_trans2 = None
98
+ return df_new1, df_trans1, df_new2, df_trans2
src/rtu/models/kmeans_rtu_1.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:42621b20e5f4048526e82615e92de0031ba42c540fbaba637efe0b4506f13ff4
3
+ size 2065925
src/rtu/models/kmeans_rtu_2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e1c07513633ff899c5b1fa46bdf750420ee95593282f79bc4564db06c2dfb601
3
+ size 2065925
src/rtu/models/kmeans_rtu_3.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:31d6d81362dde61976f0617e51239a67c6962c1ea84f6c301970bafdb8406146
3
+ size 2065881
src/rtu/models/kmeans_rtu_4.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:72a5a1799b4546825815d9833598bcce7fb3241f9c15a3c03c3d0c28e5010b33
3
+ size 2065881
lstm.ipynb → src/rtu/models/lstm.ipynb RENAMED
@@ -2,7 +2,7 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 4,
6
  "metadata": {},
7
  "outputs": [],
8
  "source": [
@@ -22,7 +22,7 @@
22
  },
23
  {
24
  "cell_type": "code",
25
- "execution_count": 5,
26
  "metadata": {},
27
  "outputs": [
28
  {
@@ -434,7 +434,7 @@
434
  "[2072154 rows x 30 columns]"
435
  ]
436
  },
437
- "execution_count": 5,
438
  "metadata": {},
439
  "output_type": "execute_result"
440
  }
@@ -1135,7 +1135,7 @@
1135
  },
1136
  {
1137
  "cell_type": "code",
1138
- "execution_count": 110,
1139
  "metadata": {},
1140
  "outputs": [
1141
  {
@@ -1272,7 +1272,7 @@
1272
  "[2 rows x 65 columns]"
1273
  ]
1274
  },
1275
- "execution_count": 110,
1276
  "metadata": {},
1277
  "output_type": "execute_result"
1278
  }
@@ -1294,7 +1294,7 @@
1294
  },
1295
  {
1296
  "cell_type": "code",
1297
- "execution_count": 111,
1298
  "metadata": {},
1299
  "outputs": [
1300
  {
@@ -1335,7 +1335,7 @@
1335
  },
1336
  {
1337
  "cell_type": "code",
1338
- "execution_count": 112,
1339
  "metadata": {},
1340
  "outputs": [],
1341
  "source": [
@@ -1354,20 +1354,20 @@
1354
  "# 'solar_radiation_set_1']]\n",
1355
  "\n",
1356
  "df_filtered = df_filtered.loc[:,['date','hp_hws_temp',\n",
1357
- "# 'rtu_003_sa_temp',\n",
1358
- "# 'rtu_003_oadmpr_pct',\n",
1359
- "# 'rtu_003_ra_temp',\n",
1360
- "# 'rtu_003_oa_temp',\n",
1361
- "# 'rtu_003_ma_temp',\n",
1362
- "# 'rtu_003_sf_vfd_spd_fbk_tn',\n",
1363
- "# 'rtu_003_rf_vfd_spd_fbk_tn',\n",
1364
- "# 'rtu_004_sa_temp',\n",
1365
- "# 'rtu_004_oadmpr_pct',\n",
1366
- "# 'rtu_004_ra_temp',\n",
1367
- "# 'rtu_004_oa_temp',\n",
1368
- "# 'rtu_004_ma_temp',\n",
1369
- "# 'rtu_004_sf_vfd_spd_fbk_tn',\n",
1370
- "# 'rtu_004_rf_vfd_spd_fbk_tn',\n",
1371
  " 'rtu_001_sa_temp',\n",
1372
  " 'rtu_001_oadmpr_pct',\n",
1373
  " 'rtu_001_ra_temp',\n",
@@ -1375,6 +1375,7 @@
1375
  " 'rtu_001_ma_temp',\n",
1376
  " 'rtu_001_sf_vfd_spd_fbk_tn',\n",
1377
  " 'rtu_001_rf_vfd_spd_fbk_tn',\n",
 
1378
  " 'rtu_002_sa_temp',\n",
1379
  " 'rtu_002_oadmpr_pct',\n",
1380
  " 'rtu_002_ra_temp',\n",
@@ -1382,8 +1383,9 @@
1382
  " 'rtu_002_ma_temp',\n",
1383
  " 'rtu_002_sf_vfd_spd_fbk_tn',\n",
1384
  " 'rtu_002_rf_vfd_spd_fbk_tn',\n",
1385
- "# 'rtu_003_sat_sp_tn',\n",
1386
- "# 'rtu_004_sat_sp_tn',\n",
 
1387
  " 'rtu_001_sat_sp_tn',\n",
1388
  " 'rtu_002_sat_sp_tn',\n",
1389
  " 'air_temp_set_1',\n",
@@ -1395,7 +1397,17 @@
1395
  },
1396
  {
1397
  "cell_type": "code",
1398
- "execution_count": 113,
 
 
 
 
 
 
 
 
 
 
1399
  "metadata": {},
1400
  "outputs": [
1401
  {
@@ -1435,7 +1447,7 @@
1435
  },
1436
  {
1437
  "cell_type": "code",
1438
- "execution_count": 114,
1439
  "metadata": {},
1440
  "outputs": [
1441
  {
@@ -1459,64 +1471,31 @@
1459
  },
1460
  {
1461
  "cell_type": "code",
1462
- "execution_count": 250,
1463
  "metadata": {},
1464
  "outputs": [
1465
  {
1466
  "data": {
1467
  "text/plain": [
1468
- "['scaler_1.pkl']"
1469
  ]
1470
  },
1471
- "execution_count": 250,
1472
  "metadata": {},
1473
  "output_type": "execute_result"
1474
  }
1475
  ],
1476
  "source": [
1477
  "import joblib\n",
1478
- "# joblib.dump(scaler, 'scaler_1.pkl')\n",
1479
  "# loaded_scaler = joblib.load('scaler.pkl')"
1480
  ]
1481
  },
1482
  {
1483
  "cell_type": "code",
1484
- "execution_count": 115,
1485
  "metadata": {},
1486
- "outputs": [
1487
- {
1488
- "name": "stderr",
1489
- "output_type": "stream",
1490
- "text": [
1491
- "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",
1492
- " super().__init__(**kwargs)\n"
1493
- ]
1494
- },
1495
- {
1496
- "name": "stdout",
1497
- "output_type": "stream",
1498
- "text": [
1499
- "Epoch 1/2\n",
1500
- "\u001b[1m8066/8067\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m━\u001b[0m \u001b[1m0s\u001b[0m 14ms/step - loss: 0.0548\n",
1501
- "Epoch 1: val_loss improved from inf to 0.34488, saving model to lstm_2rtu_smooth_04.keras\n",
1502
- "\u001b[1m8067/8067\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m165s\u001b[0m 20ms/step - loss: 0.0548 - val_loss: 0.3449\n",
1503
- "Epoch 2/2\n",
1504
- "\u001b[1m8067/8067\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 14ms/step - loss: 0.0014\n",
1505
- "Epoch 2: val_loss improved from 0.34488 to 0.27523, saving model to lstm_2rtu_smooth_04.keras\n",
1506
- "\u001b[1m8067/8067\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m160s\u001b[0m 20ms/step - loss: 0.0014 - val_loss: 0.2752\n"
1507
- ]
1508
- },
1509
- {
1510
- "data": {
1511
- "text/plain": [
1512
- "<keras.src.callbacks.history.History at 0x207bef58850>"
1513
- ]
1514
- },
1515
- "execution_count": 115,
1516
- "metadata": {},
1517
- "output_type": "execute_result"
1518
- }
1519
- ],
1520
  "source": [
1521
  "#2 rtu model\n",
1522
  "\n",
@@ -1543,17 +1522,17 @@
1543
  "X_test, y_test = create_dataset(test, time_step)\n",
1544
  "\n",
1545
  "\n",
1546
- "model = Sequential()\n",
1547
- "model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\n",
1548
- "model.add(LSTM(units=50, return_sequences=True))\n",
1549
- "model.add(LSTM(units=30))\n",
1550
- "model.add(Dense(units=15))\n",
1551
  "\n",
1552
- "model.compile(optimizer='adam', loss='mean_squared_error')\n",
1553
  "\n",
1554
- "checkpoint_path = \"lstm_2rtu_smooth_04.keras\" #\"lstm_2rtu_smooth_03.keras\"--> 3,4rtu\n",
1555
- "checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n",
1556
- "model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=2, batch_size=64, verbose=1, callbacks=[checkpoint_callback])"
1557
  ]
1558
  },
1559
  {
@@ -1697,7 +1676,7 @@
1697
  },
1698
  {
1699
  "cell_type": "code",
1700
- "execution_count": 89,
1701
  "metadata": {},
1702
  "outputs": [],
1703
  "source": [
@@ -1715,15 +1694,15 @@
1715
  },
1716
  {
1717
  "cell_type": "code",
1718
- "execution_count": 116,
1719
  "metadata": {},
1720
  "outputs": [
1721
  {
1722
  "name": "stdout",
1723
  "output_type": "stream",
1724
  "text": [
1725
- "\u001b[1m19190/19190\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m78s\u001b[0m 4ms/step\n",
1726
- "\u001b[1m16134/16134\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m63s\u001b[0m 4ms/step\n"
1727
  ]
1728
  }
1729
  ],
@@ -1809,16 +1788,425 @@
1809
  },
1810
  {
1811
  "cell_type": "code",
1812
- "execution_count": 150,
1813
  "metadata": {},
1814
  "outputs": [
1815
  {
1816
- "name": "stdout",
1817
- "output_type": "stream",
1818
- "text": [
1819
- "[[ 0.00056891 -0.00128509 0.00987136 -0.00519864 0.01173089 0.00975552\n",
1820
- " 0.01170705]]\n"
1821
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1822
  }
1823
  ],
1824
  "source": [
@@ -1846,44 +2234,45 @@
1846
  "\n",
1847
  "\n",
1848
  "\n",
1849
- "pca = PCA(n_components=2)\n",
1850
- "X = pca.fit_transform(X1)\n",
1851
  "\n",
1852
  "\n",
1853
  "\n",
1854
  "\n",
1855
- "# # Getting the cluster centers and labels\n",
1856
- "centroids = pca.transform(kmeans1.cluster_centers_)\n",
1857
- "labels = kmeans1.labels_\n",
1858
- "print(kmeans1.cluster_centers_)\n",
1859
- "# Plotting the data points and cluster centers\n",
1860
- "plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.5)\n",
1861
- "plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', c='red', s=200, linewidths=2)\n",
1862
- "plt.title('KMeans Clustering')\n",
1863
- "plt.xlabel('Feature 1')\n",
1864
- "plt.ylabel('Feature 2')\n",
1865
- "plt.show()\n"
1866
  ]
1867
  },
1868
  {
1869
  "cell_type": "code",
1870
- "execution_count": 249,
1871
  "metadata": {},
1872
  "outputs": [
1873
  {
1874
  "data": {
1875
  "text/plain": [
1876
- "['kmeans_model4.pkl']"
1877
  ]
1878
  },
1879
- "execution_count": 249,
1880
  "metadata": {},
1881
  "output_type": "execute_result"
1882
  }
1883
  ],
1884
  "source": [
1885
  "import joblib\n",
1886
- "# joblib.dump(kmeans4, 'kmeans_model4.pkl')\n",
 
1887
  "# joblib.dump(pca, 'pca_model.pkl')\n"
1888
  ]
1889
  },
@@ -1915,7 +2304,7 @@
1915
  },
1916
  {
1917
  "cell_type": "code",
1918
- "execution_count": 185,
1919
  "metadata": {},
1920
  "outputs": [],
1921
  "source": [
@@ -2169,38 +2558,6 @@
2169
  "# plt.plot(df_filtered['date'],df_filtered['hp_hws_temp'])"
2170
  ]
2171
  },
2172
- {
2173
- "cell_type": "code",
2174
- "execution_count": null,
2175
- "metadata": {},
2176
- "outputs": [],
2177
- "source": []
2178
- },
2179
- {
2180
- "cell_type": "code",
2181
- "execution_count": 234,
2182
- "metadata": {},
2183
- "outputs": [
2184
- {
2185
- "data": {
2186
- "text/plain": [
2187
- "False"
2188
- ]
2189
- },
2190
- "execution_count": 234,
2191
- "metadata": {},
2192
- "output_type": "execute_result"
2193
- }
2194
- ],
2195
- "source": []
2196
- },
2197
- {
2198
- "cell_type": "code",
2199
- "execution_count": null,
2200
- "metadata": {},
2201
- "outputs": [],
2202
- "source": []
2203
- },
2204
  {
2205
  "cell_type": "code",
2206
  "execution_count": null,
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 3,
6
  "metadata": {},
7
  "outputs": [],
8
  "source": [
 
22
  },
23
  {
24
  "cell_type": "code",
25
+ "execution_count": 4,
26
  "metadata": {},
27
  "outputs": [
28
  {
 
434
  "[2072154 rows x 30 columns]"
435
  ]
436
  },
437
+ "execution_count": 4,
438
  "metadata": {},
439
  "output_type": "execute_result"
440
  }
 
1135
  },
1136
  {
1137
  "cell_type": "code",
1138
+ "execution_count": 5,
1139
  "metadata": {},
1140
  "outputs": [
1141
  {
 
1272
  "[2 rows x 65 columns]"
1273
  ]
1274
  },
1275
+ "execution_count": 5,
1276
  "metadata": {},
1277
  "output_type": "execute_result"
1278
  }
 
1294
  },
1295
  {
1296
  "cell_type": "code",
1297
+ "execution_count": 6,
1298
  "metadata": {},
1299
  "outputs": [
1300
  {
 
1335
  },
1336
  {
1337
  "cell_type": "code",
1338
+ "execution_count": 7,
1339
  "metadata": {},
1340
  "outputs": [],
1341
  "source": [
 
1354
  "# 'solar_radiation_set_1']]\n",
1355
  "\n",
1356
  "df_filtered = df_filtered.loc[:,['date','hp_hws_temp',\n",
1357
+ " 'rtu_003_sa_temp',\n",
1358
+ " 'rtu_003_oadmpr_pct',\n",
1359
+ " 'rtu_003_ra_temp',\n",
1360
+ " 'rtu_003_oa_temp',\n",
1361
+ " 'rtu_003_ma_temp',\n",
1362
+ " 'rtu_003_sf_vfd_spd_fbk_tn',\n",
1363
+ " 'rtu_003_rf_vfd_spd_fbk_tn',\n",
1364
+ " 'rtu_004_sa_temp',\n",
1365
+ " 'rtu_004_oadmpr_pct',\n",
1366
+ " 'rtu_004_ra_temp',\n",
1367
+ " 'rtu_004_oa_temp',\n",
1368
+ " 'rtu_004_ma_temp',\n",
1369
+ " 'rtu_004_sf_vfd_spd_fbk_tn',\n",
1370
+ " 'rtu_004_rf_vfd_spd_fbk_tn',\n",
1371
  " 'rtu_001_sa_temp',\n",
1372
  " 'rtu_001_oadmpr_pct',\n",
1373
  " 'rtu_001_ra_temp',\n",
 
1375
  " 'rtu_001_ma_temp',\n",
1376
  " 'rtu_001_sf_vfd_spd_fbk_tn',\n",
1377
  " 'rtu_001_rf_vfd_spd_fbk_tn',\n",
1378
+ " \n",
1379
  " 'rtu_002_sa_temp',\n",
1380
  " 'rtu_002_oadmpr_pct',\n",
1381
  " 'rtu_002_ra_temp',\n",
 
1383
  " 'rtu_002_ma_temp',\n",
1384
  " 'rtu_002_sf_vfd_spd_fbk_tn',\n",
1385
  " 'rtu_002_rf_vfd_spd_fbk_tn',\n",
1386
+ " \n",
1387
+ " 'rtu_003_sat_sp_tn',\n",
1388
+ " 'rtu_004_sat_sp_tn',\n",
1389
  " 'rtu_001_sat_sp_tn',\n",
1390
  " 'rtu_002_sat_sp_tn',\n",
1391
  " 'air_temp_set_1',\n",
 
1397
  },
1398
  {
1399
  "cell_type": "code",
1400
+ "execution_count": 8,
1401
+ "metadata": {},
1402
+ "outputs": [],
1403
+ "source": [
1404
+ "df_filtered = df_filtered.dropna()\n",
1405
+ "df_filtered.to_csv(\"sample_test_data.csv\",index=False)"
1406
+ ]
1407
+ },
1408
+ {
1409
+ "cell_type": "code",
1410
+ "execution_count": 20,
1411
  "metadata": {},
1412
  "outputs": [
1413
  {
 
1447
  },
1448
  {
1449
  "cell_type": "code",
1450
+ "execution_count": 21,
1451
  "metadata": {},
1452
  "outputs": [
1453
  {
 
1471
  },
1472
  {
1473
  "cell_type": "code",
1474
+ "execution_count": 22,
1475
  "metadata": {},
1476
  "outputs": [
1477
  {
1478
  "data": {
1479
  "text/plain": [
1480
+ "['scaler_rtu_3_4.pkl']"
1481
  ]
1482
  },
1483
+ "execution_count": 22,
1484
  "metadata": {},
1485
  "output_type": "execute_result"
1486
  }
1487
  ],
1488
  "source": [
1489
  "import joblib\n",
1490
+ "joblib.dump(scaler, 'scaler_rtu_3_4.pkl')\n",
1491
  "# loaded_scaler = joblib.load('scaler.pkl')"
1492
  ]
1493
  },
1494
  {
1495
  "cell_type": "code",
1496
+ "execution_count": 23,
1497
  "metadata": {},
1498
+ "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1499
  "source": [
1500
  "#2 rtu model\n",
1501
  "\n",
 
1522
  "X_test, y_test = create_dataset(test, time_step)\n",
1523
  "\n",
1524
  "\n",
1525
+ "# model = Sequential()\n",
1526
+ "# model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], X_train.shape[2])))\n",
1527
+ "# model.add(LSTM(units=50, return_sequences=True))\n",
1528
+ "# model.add(LSTM(units=30))\n",
1529
+ "# model.add(Dense(units=15))\n",
1530
  "\n",
1531
+ "# model.compile(optimizer='adam', loss='mean_squared_error')\n",
1532
  "\n",
1533
+ "# checkpoint_path = \"lstm_2rtu_smooth_04.keras\" #\"lstm_2rtu_smooth_03.keras\"--> 3,4rtu\n",
1534
+ "# checkpoint_callback = ModelCheckpoint(filepath=checkpoint_path, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n",
1535
+ "# model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=2, batch_size=64, verbose=1, callbacks=[checkpoint_callback])"
1536
  ]
1537
  },
1538
  {
 
1676
  },
1677
  {
1678
  "cell_type": "code",
1679
+ "execution_count": 24,
1680
  "metadata": {},
1681
  "outputs": [],
1682
  "source": [
 
1694
  },
1695
  {
1696
  "cell_type": "code",
1697
+ "execution_count": 25,
1698
  "metadata": {},
1699
  "outputs": [
1700
  {
1701
  "name": "stdout",
1702
  "output_type": "stream",
1703
  "text": [
1704
+ "\u001b[1m19190/19190\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m83s\u001b[0m 4ms/step\n",
1705
+ "\u001b[1m16134/16134\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m58s\u001b[0m 4ms/step\n"
1706
  ]
1707
  }
1708
  ],
 
1788
  },
1789
  {
1790
  "cell_type": "code",
1791
+ "execution_count": 26,
1792
  "metadata": {},
1793
  "outputs": [
1794
  {
1795
+ "data": {
1796
+ "text/html": [
1797
+ "<style>#sk-container-id-2 {\n",
1798
+ " /* Definition of color scheme common for light and dark mode */\n",
1799
+ " --sklearn-color-text: black;\n",
1800
+ " --sklearn-color-line: gray;\n",
1801
+ " /* Definition of color scheme for unfitted estimators */\n",
1802
+ " --sklearn-color-unfitted-level-0: #fff5e6;\n",
1803
+ " --sklearn-color-unfitted-level-1: #f6e4d2;\n",
1804
+ " --sklearn-color-unfitted-level-2: #ffe0b3;\n",
1805
+ " --sklearn-color-unfitted-level-3: chocolate;\n",
1806
+ " /* Definition of color scheme for fitted estimators */\n",
1807
+ " --sklearn-color-fitted-level-0: #f0f8ff;\n",
1808
+ " --sklearn-color-fitted-level-1: #d4ebff;\n",
1809
+ " --sklearn-color-fitted-level-2: #b3dbfd;\n",
1810
+ " --sklearn-color-fitted-level-3: cornflowerblue;\n",
1811
+ "\n",
1812
+ " /* Specific color for light theme */\n",
1813
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
1814
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
1815
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
1816
+ " --sklearn-color-icon: #696969;\n",
1817
+ "\n",
1818
+ " @media (prefers-color-scheme: dark) {\n",
1819
+ " /* Redefinition of color scheme for dark theme */\n",
1820
+ " --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
1821
+ " --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
1822
+ " --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
1823
+ " --sklearn-color-icon: #878787;\n",
1824
+ " }\n",
1825
+ "}\n",
1826
+ "\n",
1827
+ "#sk-container-id-2 {\n",
1828
+ " color: var(--sklearn-color-text);\n",
1829
+ "}\n",
1830
+ "\n",
1831
+ "#sk-container-id-2 pre {\n",
1832
+ " padding: 0;\n",
1833
+ "}\n",
1834
+ "\n",
1835
+ "#sk-container-id-2 input.sk-hidden--visually {\n",
1836
+ " border: 0;\n",
1837
+ " clip: rect(1px 1px 1px 1px);\n",
1838
+ " clip: rect(1px, 1px, 1px, 1px);\n",
1839
+ " height: 1px;\n",
1840
+ " margin: -1px;\n",
1841
+ " overflow: hidden;\n",
1842
+ " padding: 0;\n",
1843
+ " position: absolute;\n",
1844
+ " width: 1px;\n",
1845
+ "}\n",
1846
+ "\n",
1847
+ "#sk-container-id-2 div.sk-dashed-wrapped {\n",
1848
+ " border: 1px dashed var(--sklearn-color-line);\n",
1849
+ " margin: 0 0.4em 0.5em 0.4em;\n",
1850
+ " box-sizing: border-box;\n",
1851
+ " padding-bottom: 0.4em;\n",
1852
+ " background-color: var(--sklearn-color-background);\n",
1853
+ "}\n",
1854
+ "\n",
1855
+ "#sk-container-id-2 div.sk-container {\n",
1856
+ " /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
1857
+ " but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
1858
+ " so we also need the `!important` here to be able to override the\n",
1859
+ " default hidden behavior on the sphinx rendered scikit-learn.org.\n",
1860
+ " See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
1861
+ " display: inline-block !important;\n",
1862
+ " position: relative;\n",
1863
+ "}\n",
1864
+ "\n",
1865
+ "#sk-container-id-2 div.sk-text-repr-fallback {\n",
1866
+ " display: none;\n",
1867
+ "}\n",
1868
+ "\n",
1869
+ "div.sk-parallel-item,\n",
1870
+ "div.sk-serial,\n",
1871
+ "div.sk-item {\n",
1872
+ " /* draw centered vertical line to link estimators */\n",
1873
+ " background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
1874
+ " background-size: 2px 100%;\n",
1875
+ " background-repeat: no-repeat;\n",
1876
+ " background-position: center center;\n",
1877
+ "}\n",
1878
+ "\n",
1879
+ "/* Parallel-specific style estimator block */\n",
1880
+ "\n",
1881
+ "#sk-container-id-2 div.sk-parallel-item::after {\n",
1882
+ " content: \"\";\n",
1883
+ " width: 100%;\n",
1884
+ " border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
1885
+ " flex-grow: 1;\n",
1886
+ "}\n",
1887
+ "\n",
1888
+ "#sk-container-id-2 div.sk-parallel {\n",
1889
+ " display: flex;\n",
1890
+ " align-items: stretch;\n",
1891
+ " justify-content: center;\n",
1892
+ " background-color: var(--sklearn-color-background);\n",
1893
+ " position: relative;\n",
1894
+ "}\n",
1895
+ "\n",
1896
+ "#sk-container-id-2 div.sk-parallel-item {\n",
1897
+ " display: flex;\n",
1898
+ " flex-direction: column;\n",
1899
+ "}\n",
1900
+ "\n",
1901
+ "#sk-container-id-2 div.sk-parallel-item:first-child::after {\n",
1902
+ " align-self: flex-end;\n",
1903
+ " width: 50%;\n",
1904
+ "}\n",
1905
+ "\n",
1906
+ "#sk-container-id-2 div.sk-parallel-item:last-child::after {\n",
1907
+ " align-self: flex-start;\n",
1908
+ " width: 50%;\n",
1909
+ "}\n",
1910
+ "\n",
1911
+ "#sk-container-id-2 div.sk-parallel-item:only-child::after {\n",
1912
+ " width: 0;\n",
1913
+ "}\n",
1914
+ "\n",
1915
+ "/* Serial-specific style estimator block */\n",
1916
+ "\n",
1917
+ "#sk-container-id-2 div.sk-serial {\n",
1918
+ " display: flex;\n",
1919
+ " flex-direction: column;\n",
1920
+ " align-items: center;\n",
1921
+ " background-color: var(--sklearn-color-background);\n",
1922
+ " padding-right: 1em;\n",
1923
+ " padding-left: 1em;\n",
1924
+ "}\n",
1925
+ "\n",
1926
+ "\n",
1927
+ "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
1928
+ "clickable and can be expanded/collapsed.\n",
1929
+ "- Pipeline and ColumnTransformer use this feature and define the default style\n",
1930
+ "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
1931
+ "*/\n",
1932
+ "\n",
1933
+ "/* Pipeline and ColumnTransformer style (default) */\n",
1934
+ "\n",
1935
+ "#sk-container-id-2 div.sk-toggleable {\n",
1936
+ " /* Default theme specific background. It is overwritten whether we have a\n",
1937
+ " specific estimator or a Pipeline/ColumnTransformer */\n",
1938
+ " background-color: var(--sklearn-color-background);\n",
1939
+ "}\n",
1940
+ "\n",
1941
+ "/* Toggleable label */\n",
1942
+ "#sk-container-id-2 label.sk-toggleable__label {\n",
1943
+ " cursor: pointer;\n",
1944
+ " display: block;\n",
1945
+ " width: 100%;\n",
1946
+ " margin-bottom: 0;\n",
1947
+ " padding: 0.5em;\n",
1948
+ " box-sizing: border-box;\n",
1949
+ " text-align: center;\n",
1950
+ "}\n",
1951
+ "\n",
1952
+ "#sk-container-id-2 label.sk-toggleable__label-arrow:before {\n",
1953
+ " /* Arrow on the left of the label */\n",
1954
+ " content: \"▸\";\n",
1955
+ " float: left;\n",
1956
+ " margin-right: 0.25em;\n",
1957
+ " color: var(--sklearn-color-icon);\n",
1958
+ "}\n",
1959
+ "\n",
1960
+ "#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {\n",
1961
+ " color: var(--sklearn-color-text);\n",
1962
+ "}\n",
1963
+ "\n",
1964
+ "/* Toggleable content - dropdown */\n",
1965
+ "\n",
1966
+ "#sk-container-id-2 div.sk-toggleable__content {\n",
1967
+ " max-height: 0;\n",
1968
+ " max-width: 0;\n",
1969
+ " overflow: hidden;\n",
1970
+ " text-align: left;\n",
1971
+ " /* unfitted */\n",
1972
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
1973
+ "}\n",
1974
+ "\n",
1975
+ "#sk-container-id-2 div.sk-toggleable__content.fitted {\n",
1976
+ " /* fitted */\n",
1977
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
1978
+ "}\n",
1979
+ "\n",
1980
+ "#sk-container-id-2 div.sk-toggleable__content pre {\n",
1981
+ " margin: 0.2em;\n",
1982
+ " border-radius: 0.25em;\n",
1983
+ " color: var(--sklearn-color-text);\n",
1984
+ " /* unfitted */\n",
1985
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
1986
+ "}\n",
1987
+ "\n",
1988
+ "#sk-container-id-2 div.sk-toggleable__content.fitted pre {\n",
1989
+ " /* unfitted */\n",
1990
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
1991
+ "}\n",
1992
+ "\n",
1993
+ "#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
1994
+ " /* Expand drop-down */\n",
1995
+ " max-height: 200px;\n",
1996
+ " max-width: 100%;\n",
1997
+ " overflow: auto;\n",
1998
+ "}\n",
1999
+ "\n",
2000
+ "#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
2001
+ " content: \"▾\";\n",
2002
+ "}\n",
2003
+ "\n",
2004
+ "/* Pipeline/ColumnTransformer-specific style */\n",
2005
+ "\n",
2006
+ "#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
2007
+ " color: var(--sklearn-color-text);\n",
2008
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
2009
+ "}\n",
2010
+ "\n",
2011
+ "#sk-container-id-2 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
2012
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
2013
+ "}\n",
2014
+ "\n",
2015
+ "/* Estimator-specific style */\n",
2016
+ "\n",
2017
+ "/* Colorize estimator box */\n",
2018
+ "#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
2019
+ " /* unfitted */\n",
2020
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
2021
+ "}\n",
2022
+ "\n",
2023
+ "#sk-container-id-2 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
2024
+ " /* fitted */\n",
2025
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
2026
+ "}\n",
2027
+ "\n",
2028
+ "#sk-container-id-2 div.sk-label label.sk-toggleable__label,\n",
2029
+ "#sk-container-id-2 div.sk-label label {\n",
2030
+ " /* The background is the default theme color */\n",
2031
+ " color: var(--sklearn-color-text-on-default-background);\n",
2032
+ "}\n",
2033
+ "\n",
2034
+ "/* On hover, darken the color of the background */\n",
2035
+ "#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {\n",
2036
+ " color: var(--sklearn-color-text);\n",
2037
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
2038
+ "}\n",
2039
+ "\n",
2040
+ "/* Label box, darken color on hover, fitted */\n",
2041
+ "#sk-container-id-2 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
2042
+ " color: var(--sklearn-color-text);\n",
2043
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
2044
+ "}\n",
2045
+ "\n",
2046
+ "/* Estimator label */\n",
2047
+ "\n",
2048
+ "#sk-container-id-2 div.sk-label label {\n",
2049
+ " font-family: monospace;\n",
2050
+ " font-weight: bold;\n",
2051
+ " display: inline-block;\n",
2052
+ " line-height: 1.2em;\n",
2053
+ "}\n",
2054
+ "\n",
2055
+ "#sk-container-id-2 div.sk-label-container {\n",
2056
+ " text-align: center;\n",
2057
+ "}\n",
2058
+ "\n",
2059
+ "/* Estimator-specific */\n",
2060
+ "#sk-container-id-2 div.sk-estimator {\n",
2061
+ " font-family: monospace;\n",
2062
+ " border: 1px dotted var(--sklearn-color-border-box);\n",
2063
+ " border-radius: 0.25em;\n",
2064
+ " box-sizing: border-box;\n",
2065
+ " margin-bottom: 0.5em;\n",
2066
+ " /* unfitted */\n",
2067
+ " background-color: var(--sklearn-color-unfitted-level-0);\n",
2068
+ "}\n",
2069
+ "\n",
2070
+ "#sk-container-id-2 div.sk-estimator.fitted {\n",
2071
+ " /* fitted */\n",
2072
+ " background-color: var(--sklearn-color-fitted-level-0);\n",
2073
+ "}\n",
2074
+ "\n",
2075
+ "/* on hover */\n",
2076
+ "#sk-container-id-2 div.sk-estimator:hover {\n",
2077
+ " /* unfitted */\n",
2078
+ " background-color: var(--sklearn-color-unfitted-level-2);\n",
2079
+ "}\n",
2080
+ "\n",
2081
+ "#sk-container-id-2 div.sk-estimator.fitted:hover {\n",
2082
+ " /* fitted */\n",
2083
+ " background-color: var(--sklearn-color-fitted-level-2);\n",
2084
+ "}\n",
2085
+ "\n",
2086
+ "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
2087
+ "\n",
2088
+ "/* Common style for \"i\" and \"?\" */\n",
2089
+ "\n",
2090
+ ".sk-estimator-doc-link,\n",
2091
+ "a:link.sk-estimator-doc-link,\n",
2092
+ "a:visited.sk-estimator-doc-link {\n",
2093
+ " float: right;\n",
2094
+ " font-size: smaller;\n",
2095
+ " line-height: 1em;\n",
2096
+ " font-family: monospace;\n",
2097
+ " background-color: var(--sklearn-color-background);\n",
2098
+ " border-radius: 1em;\n",
2099
+ " height: 1em;\n",
2100
+ " width: 1em;\n",
2101
+ " text-decoration: none !important;\n",
2102
+ " margin-left: 1ex;\n",
2103
+ " /* unfitted */\n",
2104
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
2105
+ " color: var(--sklearn-color-unfitted-level-1);\n",
2106
+ "}\n",
2107
+ "\n",
2108
+ ".sk-estimator-doc-link.fitted,\n",
2109
+ "a:link.sk-estimator-doc-link.fitted,\n",
2110
+ "a:visited.sk-estimator-doc-link.fitted {\n",
2111
+ " /* fitted */\n",
2112
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
2113
+ " color: var(--sklearn-color-fitted-level-1);\n",
2114
+ "}\n",
2115
+ "\n",
2116
+ "/* On hover */\n",
2117
+ "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
2118
+ ".sk-estimator-doc-link:hover,\n",
2119
+ "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
2120
+ ".sk-estimator-doc-link:hover {\n",
2121
+ " /* unfitted */\n",
2122
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
2123
+ " color: var(--sklearn-color-background);\n",
2124
+ " text-decoration: none;\n",
2125
+ "}\n",
2126
+ "\n",
2127
+ "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
2128
+ ".sk-estimator-doc-link.fitted:hover,\n",
2129
+ "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
2130
+ ".sk-estimator-doc-link.fitted:hover {\n",
2131
+ " /* fitted */\n",
2132
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
2133
+ " color: var(--sklearn-color-background);\n",
2134
+ " text-decoration: none;\n",
2135
+ "}\n",
2136
+ "\n",
2137
+ "/* Span, style for the box shown on hovering the info icon */\n",
2138
+ ".sk-estimator-doc-link span {\n",
2139
+ " display: none;\n",
2140
+ " z-index: 9999;\n",
2141
+ " position: relative;\n",
2142
+ " font-weight: normal;\n",
2143
+ " right: .2ex;\n",
2144
+ " padding: .5ex;\n",
2145
+ " margin: .5ex;\n",
2146
+ " width: min-content;\n",
2147
+ " min-width: 20ex;\n",
2148
+ " max-width: 50ex;\n",
2149
+ " color: var(--sklearn-color-text);\n",
2150
+ " box-shadow: 2pt 2pt 4pt #999;\n",
2151
+ " /* unfitted */\n",
2152
+ " background: var(--sklearn-color-unfitted-level-0);\n",
2153
+ " border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
2154
+ "}\n",
2155
+ "\n",
2156
+ ".sk-estimator-doc-link.fitted span {\n",
2157
+ " /* fitted */\n",
2158
+ " background: var(--sklearn-color-fitted-level-0);\n",
2159
+ " border: var(--sklearn-color-fitted-level-3);\n",
2160
+ "}\n",
2161
+ "\n",
2162
+ ".sk-estimator-doc-link:hover span {\n",
2163
+ " display: block;\n",
2164
+ "}\n",
2165
+ "\n",
2166
+ "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
2167
+ "\n",
2168
+ "#sk-container-id-2 a.estimator_doc_link {\n",
2169
+ " float: right;\n",
2170
+ " font-size: 1rem;\n",
2171
+ " line-height: 1em;\n",
2172
+ " font-family: monospace;\n",
2173
+ " background-color: var(--sklearn-color-background);\n",
2174
+ " border-radius: 1rem;\n",
2175
+ " height: 1rem;\n",
2176
+ " width: 1rem;\n",
2177
+ " text-decoration: none;\n",
2178
+ " /* unfitted */\n",
2179
+ " color: var(--sklearn-color-unfitted-level-1);\n",
2180
+ " border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
2181
+ "}\n",
2182
+ "\n",
2183
+ "#sk-container-id-2 a.estimator_doc_link.fitted {\n",
2184
+ " /* fitted */\n",
2185
+ " border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
2186
+ " color: var(--sklearn-color-fitted-level-1);\n",
2187
+ "}\n",
2188
+ "\n",
2189
+ "/* On hover */\n",
2190
+ "#sk-container-id-2 a.estimator_doc_link:hover {\n",
2191
+ " /* unfitted */\n",
2192
+ " background-color: var(--sklearn-color-unfitted-level-3);\n",
2193
+ " color: var(--sklearn-color-background);\n",
2194
+ " text-decoration: none;\n",
2195
+ "}\n",
2196
+ "\n",
2197
+ "#sk-container-id-2 a.estimator_doc_link.fitted:hover {\n",
2198
+ " /* fitted */\n",
2199
+ " background-color: var(--sklearn-color-fitted-level-3);\n",
2200
+ "}\n",
2201
+ "</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KMeans(n_clusters=1, random_state=10)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" checked><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KMeans<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.4/modules/generated/sklearn.cluster.KMeans.html\">?<span>Documentation for KMeans</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KMeans(n_clusters=1, random_state=10)</pre></div> </div></div></div></div>"
2202
+ ],
2203
+ "text/plain": [
2204
+ "KMeans(n_clusters=1, random_state=10)"
2205
+ ]
2206
+ },
2207
+ "execution_count": 26,
2208
+ "metadata": {},
2209
+ "output_type": "execute_result"
2210
  }
2211
  ],
2212
  "source": [
 
2234
  "\n",
2235
  "\n",
2236
  "\n",
2237
+ "# pca = PCA(n_components=2)\n",
2238
+ "# X = pca.fit_transform(X1)\n",
2239
  "\n",
2240
  "\n",
2241
  "\n",
2242
  "\n",
2243
+ "# # # Getting the cluster centers and labels\n",
2244
+ "# centroids = pca.transform(kmeans1.cluster_centers_)\n",
2245
+ "# labels = kmeans1.labels_\n",
2246
+ "# print(kmeans1.cluster_centers_)\n",
2247
+ "# # Plotting the data points and cluster centers\n",
2248
+ "# plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.5)\n",
2249
+ "# plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', c='red', s=200, linewidths=2)\n",
2250
+ "# plt.title('KMeans Clustering')\n",
2251
+ "# plt.xlabel('Feature 1')\n",
2252
+ "# plt.ylabel('Feature 2')\n",
2253
+ "# plt.show()\n"
2254
  ]
2255
  },
2256
  {
2257
  "cell_type": "code",
2258
+ "execution_count": 27,
2259
  "metadata": {},
2260
  "outputs": [
2261
  {
2262
  "data": {
2263
  "text/plain": [
2264
+ "['kmeans_rtu_4.pkl']"
2265
  ]
2266
  },
2267
+ "execution_count": 27,
2268
  "metadata": {},
2269
  "output_type": "execute_result"
2270
  }
2271
  ],
2272
  "source": [
2273
  "import joblib\n",
2274
+ "joblib.dump(kmeans1, 'kmeans_rtu_3.pkl')\n",
2275
+ "joblib.dump(kmeans2, 'kmeans_rtu_4.pkl')\n",
2276
  "# joblib.dump(pca, 'pca_model.pkl')\n"
2277
  ]
2278
  },
 
2304
  },
2305
  {
2306
  "cell_type": "code",
2307
+ "execution_count": 16,
2308
  "metadata": {},
2309
  "outputs": [],
2310
  "source": [
 
2558
  "# plt.plot(df_filtered['date'],df_filtered['hp_hws_temp'])"
2559
  ]
2560
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2561
  {
2562
  "cell_type": "code",
2563
  "execution_count": null,
src/rtu/models/lstm_2rtu_smooth_03.keras ADDED
Binary file (575 kB). View file
 
src/rtu/models/lstm_2rtu_smooth_04.keras ADDED
Binary file (575 kB). View file
 
src/rtu/models/scaler_rtu_1_2.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ba51191b0f354f482615235908b9f3934b0986b8b97b3c34ef942c8d4706b5d
3
+ size 1149
src/rtu/models/scaler_rtu_3_4.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:096b8e146b1d09dac40661624f33d902e44eb19c8e2ca33b8854022ce2f77796
3
+ size 1149