jung-ming commited on
Commit
9f9d078
·
verified ·
1 Parent(s): 64a56de

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +86 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 建立 .streamlit/config.toml 避免 Hugging Face 權限錯誤
2
+ import os
3
+ os.makedirs(".streamlit", exist_ok=True)
4
+ with open(".streamlit/config.toml", "w") as f:
5
+ f.write("""
6
+ [server]
7
+ headless = true
8
+ port = 7860
9
+ enableCORS = false
10
+ """)
11
+
12
+ # 主程式開始
13
+ import streamlit as st
14
+ import joblib
15
+ import pandas as pd
16
+ import requests
17
+ import io
18
+ import shap
19
+ import matplotlib.pyplot as plt
20
+ import platform
21
+ from huggingface_hub import hf_hub_download
22
+
23
+ # 跨平台字型設定
24
+ if platform.system() == 'Windows':
25
+ plt.rcParams['font.family'] = 'Microsoft JhengHei'
26
+ elif platform.system() == 'Darwin': # macOS
27
+ plt.rcParams['font.family'] = 'AppleGothic'
28
+ else:
29
+ plt.rcParams['font.family'] = 'Noto Sans CJK TC' # Linux
30
+
31
+ plt.rcParams['axes.unicode_minus'] = False # 負號使用 ASCII 減號
32
+
33
+ @st.cache_resource
34
+ def load_explainer():
35
+ url = "https://huggingface.co/jung-ming/Ocean-Meets-Forest/resolve/main/explainer.pkl"
36
+ r = requests.get(url)
37
+ return joblib.load(io.BytesIO(r.content))
38
+
39
+ explainer = load_explainer()
40
+
41
+ # 載入模型與 LabelEncoder(從 Model Repo 抓)
42
+ model_path = hf_hub_download(
43
+ repo_id="jung-ming/Ocean-Meets-Forest",
44
+ filename="rf_model_with_encoder.pkl",
45
+ repo_type="model"
46
+ )
47
+ bundle = joblib.load(model_path)
48
+ model = bundle["model"]
49
+ le = bundle["label_encoder"]
50
+
51
+ # 建立映射
52
+ ship_type_to_code = dict(zip(le.classes_, le.transform(le.classes_)))
53
+
54
+ # Streamlit UI
55
+ st.title("🚢 台中港艘次預測系統")
56
+ st.markdown("請輸入以下資訊,模型將預測該月艘次數")
57
+
58
+ port_count = st.selectbox("航線組合數", list(range(1, 100)))
59
+ year = st.selectbox("年", [2020, 2021, 2022, 2023, 2024, 2025])
60
+ month = st.selectbox("月", list(range(1, 13)))
61
+ ship_type = st.selectbox("船舶種類", list(ship_type_to_code.keys()))
62
+
63
+ if st.button("🔮 開始預測"):
64
+ ship_type_encoded = ship_type_to_code[ship_type]
65
+ input_df = pd.DataFrame({
66
+ "航線組合數": [port_count],
67
+ "年": [year],
68
+ "月": [month],
69
+ "船舶種類_編碼": [ship_type_encoded]
70
+ })
71
+ pred = model.predict(input_df)[0]
72
+ st.success(f"預測結果:🚢 約為 {pred:.2f} 艘次")
73
+
74
+ st.subheader("🧠 模型決策解釋圖(SHAP Waterfall)")
75
+
76
+ shap_values = explainer(input_df)
77
+ fig, ax = plt.subplots(figsize=(8, 4))
78
+ shap.plots.waterfall(shap_values[0], show=False)
79
+
80
+ for text in ax.texts:
81
+ if text.get_text().startswith('\u2212'):
82
+ new_text = text.get_text().replace('\u2212', '-')
83
+ text.set_text(new_text)
84
+
85
+ st.pyplot(fig)
86
+ plt.close(fig)
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ joblib
4
+ matplotlib
5
+ shap
6
+ scikit-learn
7
+ huggingface_hub
8
+ requests
9
+