Update app.py
Browse files
app.py
CHANGED
|
@@ -11,7 +11,7 @@ import time
|
|
| 11 |
from sklearn.ensemble import RandomForestRegressor
|
| 12 |
from sklearn.gaussian_process import GaussianProcessRegressor
|
| 13 |
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
|
| 14 |
-
# 關鍵修
|
| 15 |
from xgboost import XGBRegressor
|
| 16 |
|
| 17 |
# --- 1. 定義資料與模型設定 ---
|
|
@@ -20,7 +20,6 @@ FEATURES = ['MW01', 'MW02', 'MW03', 'flux', 'MWA']
|
|
| 20 |
TARGET = 'yield'
|
| 21 |
|
| 22 |
# 檔案名稱用於保存/載入模型和 SHAP 數據
|
| 23 |
-
# 關鍵修改 2: 增加 XGBoost 配置
|
| 24 |
MODEL_CONFIG = {
|
| 25 |
'Random Forest (RF)': {
|
| 26 |
'model_file': "rf_model.joblib",
|
|
@@ -94,14 +93,14 @@ def train_and_save_models():
|
|
| 94 |
for name, config in MODEL_CONFIG.items():
|
| 95 |
print(f"\n--- Processing Model: {name} ---")
|
| 96 |
|
| 97 |
-
# 關鍵修改 3: 增加 XGBoost 訓練邏輯
|
| 98 |
if name == 'Random Forest (RF)':
|
| 99 |
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
| 100 |
elif name == 'Gaussian Process (GP)':
|
| 101 |
kernel = C(1.0, (1e-3, 1e3)) * RBF(10, (1e-2, 1e2))
|
| 102 |
model = GaussianProcessRegressor(kernel=kernel, random_state=42, normalize_y=True)
|
|
|
|
| 103 |
elif name == 'XGBoost (XGB)':
|
| 104 |
-
model =
|
| 105 |
else:
|
| 106 |
continue
|
| 107 |
|
|
@@ -116,7 +115,6 @@ def train_and_save_models():
|
|
| 116 |
print(f"Calculating SHAP values for {name}...")
|
| 117 |
try:
|
| 118 |
if config['explainer_type'] == shap.TreeExplainer:
|
| 119 |
-
# TreeExplainer 適用於 RF 和 XGBoost
|
| 120 |
explainer = shap.TreeExplainer(model)
|
| 121 |
shap_values = explainer.shap_values(X)
|
| 122 |
expected_value = explainer.expected_value
|
|
@@ -157,7 +155,6 @@ def get_model_explainer_and_data(model_name):
|
|
| 157 |
shap_values = shap_data['shap_values']
|
| 158 |
base_value = shap_data['base_value']
|
| 159 |
|
| 160 |
-
# 即時創建 Explainer
|
| 161 |
if config['explainer_type'] == shap.TreeExplainer:
|
| 162 |
explainer = shap.TreeExplainer(model)
|
| 163 |
elif config['explainer_type'] == shap.KernelExplainer:
|
|
@@ -370,10 +367,8 @@ def get_global_decision_plot(model_name):
|
|
| 370 |
X_sample = X.loc[sample_indices]
|
| 371 |
|
| 372 |
try:
|
| 373 |
-
# 使用位置索引
|
| 374 |
shap_values_sample = shap_values_full[sample_indices]
|
| 375 |
except:
|
| 376 |
-
# 如果索引不匹配,重新計算(較慢但安全)
|
| 377 |
if isinstance(explainer, shap.KernelExplainer):
|
| 378 |
shap_values_sample = explainer.shap_values(X_sample.values)
|
| 379 |
else:
|
|
@@ -413,7 +408,7 @@ input_components = [
|
|
| 413 |
gr.Slider(label="MWA", minimum=5, maximum=20, step=5, value=5)
|
| 414 |
]
|
| 415 |
|
| 416 |
-
# A. 局部解釋 (多圖) - 使用 Blocks
|
| 417 |
with gr.Blocks() as local_block:
|
| 418 |
gr.Markdown("## Local Explanation for Single Prediction")
|
| 419 |
|
|
@@ -479,7 +474,7 @@ with gr.Blocks() as local_block:
|
|
| 479 |
)
|
| 480 |
|
| 481 |
|
| 482 |
-
# B. 全域解釋 (Summary + Decision Plot) - 使用 Blocks
|
| 483 |
with gr.Blocks() as global_summary_block:
|
| 484 |
gr.Markdown("## Global Analysis: Feature Importance & Decision Paths")
|
| 485 |
|
|
@@ -517,7 +512,7 @@ with gr.Blocks() as global_summary_block:
|
|
| 517 |
)
|
| 518 |
|
| 519 |
|
| 520 |
-
# C. 依賴圖介面 - 使用 Interface
|
| 521 |
dependence_interface = gr.Interface(
|
| 522 |
fn=get_dependence_plot,
|
| 523 |
inputs=[
|
|
|
|
| 11 |
from sklearn.ensemble import RandomForestRegressor
|
| 12 |
from sklearn.gaussian_process import GaussianProcessRegressor
|
| 13 |
from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C
|
| 14 |
+
# 關鍵修正: 將 XGBoostRegressor 改為 XGBRegressor
|
| 15 |
from xgboost import XGBRegressor
|
| 16 |
|
| 17 |
# --- 1. 定義資料與模型設定 ---
|
|
|
|
| 20 |
TARGET = 'yield'
|
| 21 |
|
| 22 |
# 檔案名稱用於保存/載入模型和 SHAP 數據
|
|
|
|
| 23 |
MODEL_CONFIG = {
|
| 24 |
'Random Forest (RF)': {
|
| 25 |
'model_file': "rf_model.joblib",
|
|
|
|
| 93 |
for name, config in MODEL_CONFIG.items():
|
| 94 |
print(f"\n--- Processing Model: {name} ---")
|
| 95 |
|
|
|
|
| 96 |
if name == 'Random Forest (RF)':
|
| 97 |
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
| 98 |
elif name == 'Gaussian Process (GP)':
|
| 99 |
kernel = C(1.0, (1e-3, 1e3)) * RBF(10, (1e-2, 1e2))
|
| 100 |
model = GaussianProcessRegressor(kernel=kernel, random_state=42, normalize_y=True)
|
| 101 |
+
# 關鍵修正: 使用 XGBRegressor
|
| 102 |
elif name == 'XGBoost (XGB)':
|
| 103 |
+
model = XGBRegressor(n_estimators=100, random_state=42, use_label_encoder=False, eval_metric='rmse')
|
| 104 |
else:
|
| 105 |
continue
|
| 106 |
|
|
|
|
| 115 |
print(f"Calculating SHAP values for {name}...")
|
| 116 |
try:
|
| 117 |
if config['explainer_type'] == shap.TreeExplainer:
|
|
|
|
| 118 |
explainer = shap.TreeExplainer(model)
|
| 119 |
shap_values = explainer.shap_values(X)
|
| 120 |
expected_value = explainer.expected_value
|
|
|
|
| 155 |
shap_values = shap_data['shap_values']
|
| 156 |
base_value = shap_data['base_value']
|
| 157 |
|
|
|
|
| 158 |
if config['explainer_type'] == shap.TreeExplainer:
|
| 159 |
explainer = shap.TreeExplainer(model)
|
| 160 |
elif config['explainer_type'] == shap.KernelExplainer:
|
|
|
|
| 367 |
X_sample = X.loc[sample_indices]
|
| 368 |
|
| 369 |
try:
|
|
|
|
| 370 |
shap_values_sample = shap_values_full[sample_indices]
|
| 371 |
except:
|
|
|
|
| 372 |
if isinstance(explainer, shap.KernelExplainer):
|
| 373 |
shap_values_sample = explainer.shap_values(X_sample.values)
|
| 374 |
else:
|
|
|
|
| 408 |
gr.Slider(label="MWA", minimum=5, maximum=20, step=5, value=5)
|
| 409 |
]
|
| 410 |
|
| 411 |
+
# A. 局部解釋 (多圖) - 使用 Blocks
|
| 412 |
with gr.Blocks() as local_block:
|
| 413 |
gr.Markdown("## Local Explanation for Single Prediction")
|
| 414 |
|
|
|
|
| 474 |
)
|
| 475 |
|
| 476 |
|
| 477 |
+
# B. 全域解釋 (Summary + Decision Plot) - 使用 Blocks
|
| 478 |
with gr.Blocks() as global_summary_block:
|
| 479 |
gr.Markdown("## Global Analysis: Feature Importance & Decision Paths")
|
| 480 |
|
|
|
|
| 512 |
)
|
| 513 |
|
| 514 |
|
| 515 |
+
# C. 依賴圖介面 - 使用 Interface
|
| 516 |
dependence_interface = gr.Interface(
|
| 517 |
fn=get_dependence_plot,
|
| 518 |
inputs=[
|