MatCod commited on
Commit
e5b3bea
·
verified ·
1 Parent(s): 7c2c429

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +361 -0
app.py ADDED
@@ -0,0 +1,361 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import pickle
4
+ import pandas as pd
5
+ import numpy as np
6
+ from datetime import datetime
7
+ import os
8
+
9
+ class EnergyMLPredictor:
10
+ def __init__(self):
11
+ self.rf_model = None
12
+ self.rf_preprocessor = None
13
+ self.xgb_model = None
14
+ self.xgb_encoders = None
15
+ self.threshold_model_83 = None
16
+ self.threshold_model_90 = None
17
+ self.threshold_preprocessor = None
18
+ self.models_loaded = False
19
+
20
+ def load_models(self):
21
+ """Load all models from pickle files"""
22
+ try:
23
+ # Load Random Forest Energy Model
24
+ if os.path.exists('rf_energy_model.pkl'):
25
+ with open('rf_energy_model.pkl', 'rb') as f:
26
+ rf_data = pickle.load(f)
27
+ self.rf_model = rf_data['model']
28
+ self.rf_preprocessor = rf_data['preprocessor']
29
+
30
+ # Load XGBoost Energy Model
31
+ if os.path.exists('xgboost_energy_model.pkl'):
32
+ with open('xgboost_energy_model.pkl', 'rb') as f:
33
+ xgb_data = pickle.load(f)
34
+ self.xgb_model = xgb_data['model']
35
+ self.xgb_encoders = xgb_data['label_encoders']
36
+
37
+ # Load Threshold Models
38
+ if os.path.exists('threshold_model_83.pkl'):
39
+ with open('threshold_model_83.pkl', 'rb') as f:
40
+ threshold_data = pickle.load(f)
41
+ self.threshold_model_83 = threshold_data['model']
42
+ self.threshold_preprocessor = threshold_data['preprocessor']
43
+
44
+ if os.path.exists('threshold_model_90.pkl'):
45
+ with open('threshold_model_90.pkl', 'rb') as f:
46
+ threshold_data = pickle.load(f)
47
+ self.threshold_model_90 = threshold_data['model']
48
+
49
+ self.models_loaded = True
50
+ return "Models loaded successfully"
51
+
52
+ except Exception as e:
53
+ return f"Error loading models: {str(e)}"
54
+
55
+ def predict_threshold(self, json_input):
56
+ """Predict threshold exceedance"""
57
+ try:
58
+ if not self.models_loaded:
59
+ return "Error: Models not loaded"
60
+
61
+ if not self.threshold_model_83 or not self.threshold_model_90:
62
+ return "Error: Threshold models not available"
63
+
64
+ data = json.loads(json_input)
65
+
66
+ # Parse input data
67
+ date_obj = datetime.strptime(data['data'], '%Y-%m-%d')
68
+
69
+ # Color mapping
70
+ color_mapping = {0: 'incolor', 1: 'verde', 2: 'cinza', 3: 'bronze'}
71
+ cor_str = color_mapping.get(data['cor'], 'incolor')
72
+
73
+ # Create input features
74
+ input_data = {
75
+ 'boosting': data['pot_boost'],
76
+ 'espessura': data['espessura'],
77
+ 'extracao_forno': data['extracao_forno'],
78
+ 'porcentagem_caco': data['porcentagem_caco'],
79
+ 'cor': cor_str,
80
+ 'prod_e': data['Prod_E'],
81
+ 'prod_l': data['Prod_L'],
82
+ 'week_day': date_obj.weekday(),
83
+ 'month': date_obj.month,
84
+ 'quarter': (date_obj.month - 1) // 3 + 1,
85
+ 'is_weekend': int(date_obj.weekday() >= 5),
86
+ 'week_of_year': date_obj.isocalendar()[1],
87
+ 'day_of_month': date_obj.day,
88
+ 'day_of_year': date_obj.timetuple().tm_yday
89
+ }
90
+
91
+ # Convert to DataFrame
92
+ input_df = pd.DataFrame([input_data])
93
+
94
+ # Preprocess
95
+ X_processed = self.threshold_preprocessor.transform(input_df)
96
+
97
+ # Make predictions
98
+ prob_83 = self.threshold_model_83.predict_proba(X_processed)[0][1] if len(self.threshold_model_83.classes_) > 1 else 0.0
99
+ pred_83 = int(prob_83 > 0.5)
100
+
101
+ prob_90 = self.threshold_model_90.predict_proba(X_processed)[0][1] if len(self.threshold_model_90.classes_) > 1 else 0.0
102
+ pred_90 = int(prob_90 > 0.5)
103
+
104
+ # Format response
105
+ next_date = (date_obj + pd.Timedelta(days=1)).strftime('%Y-%m-%d')
106
+
107
+ result = {
108
+ "predictions": {
109
+ "prediction_1": [
110
+ {
111
+ "datetime": data['data'],
112
+ "probabilidade_de_estouro": float(prob_83),
113
+ "estouro_previsto": pred_83
114
+ },
115
+ {
116
+ "datetime": next_date,
117
+ "probabilidade_de_estouro": float(prob_83 * 0.98),
118
+ "estouro_previsto": int(prob_83 * 0.98 > 0.5)
119
+ }
120
+ ],
121
+ "prediction_2": [
122
+ {
123
+ "datetime": data['data'],
124
+ "probabilidade_de_estouro": float(prob_90),
125
+ "estouro_previsto": pred_90
126
+ },
127
+ {
128
+ "datetime": next_date,
129
+ "probabilidade_de_estouro": float(prob_90 * 0.99),
130
+ "estouro_previsto": int(prob_90 * 0.99 > 0.5)
131
+ }
132
+ ]
133
+ }
134
+ }
135
+
136
+ return json.dumps(result, indent=2)
137
+
138
+ except json.JSONDecodeError:
139
+ return "Error: Invalid JSON format"
140
+ except Exception as e:
141
+ return f"Error: {str(e)}"
142
+
143
+ def predict_energy_rf(self, json_input):
144
+ """Predict energy using Random Forest"""
145
+ try:
146
+ if not self.models_loaded or not self.rf_model:
147
+ return "Error: Random Forest model not available"
148
+
149
+ data = json.loads(json_input)
150
+ if not isinstance(data, list):
151
+ data = [data]
152
+
153
+ results = []
154
+
155
+ for item in data:
156
+ # Parse input
157
+ date_obj = datetime.strptime(item['data'], '%Y-%m-%d')
158
+ boosting_val = float(item['boosting'].replace(',', '.'))
159
+ extracao_val = float(item['extracao_forno'].replace(',', '.'))
160
+
161
+ # Create features
162
+ input_data = {
163
+ 'boosting': boosting_val,
164
+ 'espessura': item['espessura'],
165
+ 'extracao_forno': extracao_val,
166
+ 'porcentagem_caco': item['porcentagem_caco'],
167
+ 'cor': item['cor'].lower(),
168
+ 'prod_e': 1,
169
+ 'prod_l': 1,
170
+ 'autoclave': 1,
171
+ 'week_day': date_obj.weekday(),
172
+ 'month': date_obj.month,
173
+ 'quarter': (date_obj.month - 1) // 3 + 1,
174
+ 'is_weekend': int(date_obj.weekday() >= 5),
175
+ 'week_of_year': date_obj.isocalendar()[1],
176
+ 'day_of_month': date_obj.day,
177
+ 'day_of_year': date_obj.timetuple().tm_yday
178
+ }
179
+
180
+ # Predict
181
+ input_df = pd.DataFrame([input_data])
182
+ X_processed = self.rf_preprocessor.transform(input_df)
183
+ prediction = self.rf_model.predict(X_processed)[0]
184
+
185
+ results.append({
186
+ "data": date_obj.strftime('%d-%m-%Y'),
187
+ "predictions": float(prediction)
188
+ })
189
+
190
+ return json.dumps(results, indent=2)
191
+
192
+ except json.JSONDecodeError:
193
+ return "Error: Invalid JSON format"
194
+ except Exception as e:
195
+ return f"Error: {str(e)}"
196
+
197
+ def predict_energy_xgb(self, json_input):
198
+ """Predict energy using XGBoost"""
199
+ try:
200
+ if not self.models_loaded or not self.xgb_model:
201
+ return "Error: XGBoost model not available"
202
+
203
+ data = json.loads(json_input)
204
+ if not isinstance(data, list):
205
+ data = [data]
206
+
207
+ results = []
208
+
209
+ for item in data:
210
+ # Parse input
211
+ date_obj = datetime.strptime(item['data'], '%Y-%m-%d')
212
+ boosting_val = float(item['boosting'].replace(',', '.'))
213
+ extracao_val = float(item['extracao_forno'].replace(',', '.'))
214
+
215
+ # Create features
216
+ input_data = {
217
+ 'boosting': boosting_val,
218
+ 'espessura': item['espessura'],
219
+ 'extracao_forno': extracao_val,
220
+ 'porcentagem_caco': item['porcentagem_caco'],
221
+ 'cor': item['cor'].lower(),
222
+ 'prod_e': 1,
223
+ 'prod_l': 1,
224
+ 'autoclave': 1,
225
+ 'week_day': date_obj.weekday(),
226
+ 'month': date_obj.month,
227
+ 'quarter': (date_obj.month - 1) // 3 + 1,
228
+ 'is_weekend': int(date_obj.weekday() >= 5),
229
+ 'week_of_year': date_obj.isocalendar()[1],
230
+ 'day_of_month': date_obj.day,
231
+ 'day_of_year': date_obj.timetuple().tm_yday
232
+ }
233
+
234
+ # Encode categorical features
235
+ input_df = pd.DataFrame([input_data])
236
+
237
+ for col in input_df.columns:
238
+ if col in self.xgb_encoders:
239
+ try:
240
+ input_df[col] = self.xgb_encoders[col].transform(input_df[col].astype(str))
241
+ except ValueError:
242
+ # Handle unknown categories
243
+ input_df[col] = 0
244
+
245
+ # Predict
246
+ prediction = self.xgb_model.predict(input_df.values)[0]
247
+
248
+ results.append({
249
+ "data": date_obj.strftime('%d-%m-%Y'),
250
+ "predictions": float(prediction)
251
+ })
252
+
253
+ return json.dumps(results, indent=2)
254
+
255
+ except json.JSONDecodeError:
256
+ return "Error: Invalid JSON format"
257
+ except Exception as e:
258
+ return f"Error: {str(e)}"
259
+
260
+ # Initialize predictor
261
+ predictor = EnergyMLPredictor()
262
+
263
+ def make_prediction(model_choice, json_input):
264
+ """Make prediction based on model choice"""
265
+ if not predictor.models_loaded:
266
+ load_msg = predictor.load_models()
267
+ if "Error" in load_msg:
268
+ return load_msg
269
+
270
+ if model_choice == "Threshold Detection":
271
+ return predictor.predict_threshold(json_input)
272
+ elif model_choice == "Energy Prediction (Random Forest)":
273
+ return predictor.predict_energy_rf(json_input)
274
+ elif model_choice == "Energy Prediction (XGBoost)":
275
+ return predictor.predict_energy_xgb(json_input)
276
+ else:
277
+ return "Error: Please select a model"
278
+
279
+ # Default examples
280
+ threshold_example = """{
281
+ "data": "2023-01-01",
282
+ "cor": 0,
283
+ "espessura": 8.0,
284
+ "ext_boosting": 65.0,
285
+ "extracao_forno": 851.1,
286
+ "porcentagem_caco": 15.0,
287
+ "pot_boost": 3.0,
288
+ "Prod_E": 1,
289
+ "Prod_L": 1
290
+ }"""
291
+
292
+ energy_example = """[
293
+ {
294
+ "data": "2023-01-01",
295
+ "boosting": "0,0",
296
+ "cor": "incolor",
297
+ "espessura": 10,
298
+ "extracao_forno": "651,6",
299
+ "porcentagem_caco": 10.0
300
+ }
301
+ ]"""
302
+
303
+ # Create Gradio interface
304
+ with gr.Blocks(title="Energy ML Cloud", theme=gr.themes.Default()) as app:
305
+
306
+ gr.Markdown("# Energy ML Prediction System")
307
+ gr.Markdown("Cloud deployment with embedded models")
308
+
309
+ with gr.Row():
310
+ with gr.Column():
311
+ model_choice = gr.Radio(
312
+ choices=[
313
+ "Threshold Detection",
314
+ "Energy Prediction (Random Forest)",
315
+ "Energy Prediction (XGBoost)"
316
+ ],
317
+ label="Select Model",
318
+ value="Threshold Detection"
319
+ )
320
+
321
+ json_input = gr.Textbox(
322
+ label="JSON Input",
323
+ placeholder="Enter JSON data here...",
324
+ lines=15,
325
+ value=threshold_example
326
+ )
327
+
328
+ predict_btn = gr.Button("Make Prediction", variant="primary")
329
+
330
+ with gr.Column():
331
+ output = gr.Textbox(
332
+ label="Prediction Result",
333
+ lines=20,
334
+ interactive=False
335
+ )
336
+
337
+ def update_example(choice):
338
+ if "Threshold" in choice:
339
+ return threshold_example
340
+ else:
341
+ return energy_example
342
+
343
+ model_choice.change(update_example, inputs=[model_choice], outputs=[json_input])
344
+ predict_btn.click(make_prediction, inputs=[model_choice, json_input], outputs=[output])
345
+
346
+ with gr.Accordion("Model Information", open=False):
347
+ gr.Markdown("""
348
+ ## Available Models
349
+ - **Threshold Detection**: Predict probability of exceeding 8.3 and 9.0 MWh
350
+ - **Random Forest**: Energy consumption prediction (R² = 0.72)
351
+ - **XGBoost**: Energy consumption prediction (R² = 0.56, winner model)
352
+
353
+ ## Input Formats
354
+ See examples that change when you select different models.
355
+ """)
356
+
357
+ if __name__ == "__main__":
358
+ app.launch(
359
+ auth=("admin", "energy123"),
360
+ share=True
361
+ )