Spaces:
Sleeping
Sleeping
File size: 7,738 Bytes
0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 0fa83e9 6d2f083 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | # models/regression.py
import pandas as pd
import numpy as np
from typing import Literal, Dict, Any
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
RegressionModelType = Literal['linear', 'xgb', 'mlp']
class LoadLimitRegressor:
"""
Regressor สำหรับหา load limit จาก temperature
พยากรณ์โหลดสูงสุดที่เป็นไปได้จากค่าความร้อน
"""
def __init__(self, model_type: RegressionModelType = 'xgb'):
self.model_type = model_type
self.scaler_X = MinMaxScaler()
self.scaler_y = MinMaxScaler()
self.model = None
self.feature_names = None
def fit(self, df: pd.DataFrame, temp_col: str = 'MaxTemp', load_col: str = 'mw_max'):
"""
เทรน regression model เพื่อหา relationship ระหว่างอุณหภูมิ ➜ โหลดสูงสุด
"""
X = df[[temp_col]].values
y = df[[load_col]].values
X_scaled = self.scaler_X.fit_transform(X)
y_scaled = self.scaler_y.fit_transform(y)
if self.model_type == 'linear':
self.model = LinearRegression()
elif self.model_type == 'xgb':
self.model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3)
elif self.model_type == 'mlp':
self.model = MLPRegressor(hidden_layer_sizes=(64, 32), max_iter=1000)
else:
raise ValueError(f"Unsupported model type: {self.model_type}")
self.model.fit(X_scaled, y_scaled.ravel())
self.feature_names = [temp_col]
def predict(self, max_temp_values: np.ndarray) -> np.ndarray:
"""
พยากรณ์โหลดสูงสุดที่เป็นไปได้ จากค่าความร้อน
"""
X_scaled = self.scaler_X.transform(max_temp_values.reshape(-1, 1))
y_scaled = self.model.predict(X_scaled).reshape(-1, 1)
y = self.scaler_y.inverse_transform(y_scaled)
return y.flatten()
def evaluate(self, df: pd.DataFrame, temp_col: str = 'MaxTemp', load_col: str = 'mw_max') -> Dict[str, float]:
"""
ประเมินผลโมเดล regression
"""
y_true = df[load_col].values
y_pred = self.predict(df[temp_col].values)
return {
'rmse': np.sqrt(mean_squared_error(y_true, y_pred)),
'mae': mean_absolute_error(y_true, y_pred),
'r2': r2_score(y_true, y_pred)
}
class CapacityAnalyzer:
"""
วิเคราะห์ capacity จริง (Real Capacity) เทียบกับทฤษฏี 80%
ใช้ features เพิ่มเติม (TEPR, STRR, temp margin) เพื่อประมาณ capacity จริง
ที่อาจสูงกว่า 80% theoretical
"""
def __init__(self, model_type: RegressionModelType = 'xgb'):
self.model_type = model_type
self.scalers = {}
self.model = None
self.feature_names = None
def fit(self, df: pd.DataFrame,
target_col: str = 'mw_max',
feature_cols: list = None,
calibration_factor: float = 1.0) -> None:
"""
เทรน model สำหรับหา real capacity
Args:
df: DataFrame ที่มีข้อมูล load, temp, measurement
target_col: ชื่อ column เป้าหมาย (load actual)
feature_cols: ชื่อ columns ที่ใช้เป็น features
ถ้า None ใช้ default: ['MaxTemp', 'temp_margin_available', 'tepr_mean', 'strr_mean']
calibration_factor: factor สำหรับ calibrate ผล (default 1.0)
"""
if feature_cols is None:
# Default features
available_cols = df.columns.tolist()
feature_cols = []
if 'MaxTemp' in available_cols:
feature_cols.append('MaxTemp')
if 'temp_margin_available' in available_cols:
feature_cols.append('temp_margin_available')
if 'tepr_mean' in available_cols:
feature_cols.append('tepr_mean')
if 'strr_mean' in available_cols:
feature_cols.append('strr_mean')
# ถ้าไม่มี feature พอ ใช้เฉพาะ MaxTemp
if not feature_cols:
feature_cols = ['MaxTemp']
# ตรวจสอบว่ามี feature ทั้งหมดหรือไม่
available_features = [col for col in feature_cols if col in df.columns]
if not available_features:
raise ValueError(f"❌ ไม่มี features {feature_cols} ใน data!")
X = df[available_features].values
y = df[[target_col]].values
# Normalize each feature
self.scalers = {}
X_scaled = np.zeros_like(X)
for i, col in enumerate(available_features):
scaler = MinMaxScaler()
X_scaled[:, i] = scaler.fit_transform(X[:, i:i+1]).flatten()
self.scalers[col] = scaler
# Train model
if self.model_type == 'linear':
self.model = LinearRegression()
elif self.model_type == 'xgb':
self.model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3)
elif self.model_type == 'mlp':
self.model = MLPRegressor(hidden_layer_sizes=(64, 32), max_iter=1000)
else:
raise ValueError(f"Unsupported model type: {self.model_type}")
# Normalize target
self.scaler_y = MinMaxScaler()
y_scaled = self.scaler_y.fit_transform(y)
self.model.fit(X_scaled, y_scaled.ravel())
self.feature_names = available_features
self.calibration_factor = calibration_factor
def predict_capacity(self, df: pd.DataFrame) -> np.ndarray:
"""
พยากรณ์ real capacity จริง
"""
if self.model is None:
raise ValueError("❌ Model ยังไม่ได้ train! ให้เรียก fit() ก่อน")
# ดึงแต่ features ที่มี
X = df[self.feature_names].values
# Scale features
X_scaled = np.zeros_like(X)
for i, col in enumerate(self.feature_names):
if col in self.scalers:
X_scaled[:, i] = self.scalers[col].transform(X[:, i:i+1]).flatten()
# Predict
y_scaled = self.model.predict(X_scaled).reshape(-1, 1)
y = self.scaler_y.inverse_transform(y_scaled)
# Apply calibration factor
return (y.flatten() * self.calibration_factor)
def evaluate(self, df: pd.DataFrame,
actual_col: str = 'mw_max') -> Dict[str, Any]:
"""
ประเมินผลโมเดล capacity analysis
"""
y_true = df[actual_col].values
y_pred = self.predict_capacity(df)
metrics = {
'rmse': np.sqrt(mean_squared_error(y_true, y_pred)),
'mae': mean_absolute_error(y_true, y_pred),
'r2': r2_score(y_true, y_pred),
'features_used': self.feature_names
}
return metrics
|