jung-ming commited on
Commit
1d6070a
·
verified ·
1 Parent(s): f94d706

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -23
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  os.environ["HF_HOME"] = "/tmp/.cache/huggingface"
3
  os.environ["MPLCONFIGDIR"] = "/tmp/.config/matplotlib"
 
4
  import streamlit as st
5
  import joblib
6
  import pandas as pd
@@ -10,26 +11,39 @@ import platform
10
  from huggingface_hub import hf_hub_download
11
  import matplotlib.font_manager as fm
12
 
13
- # 列出可用字型,確認是否有 Noto Sans CJK TC
14
- print([f.name for f in fm.fontManager.ttflist if "Noto" in f.name])
15
-
16
- # 設定字型
17
- plt.rcParams['font.family'] = 'Heiti TC'
18
- plt.rcParams['axes.unicode_minus'] = False
 
 
 
 
 
 
 
 
 
 
19
 
20
- # 跨平台字型設定
21
  if platform.system() == 'Windows':
22
  plt.rcParams['font.family'] = 'Microsoft JhengHei'
23
  elif platform.system() == 'Darwin': # macOS
24
  plt.rcParams['font.family'] = 'AppleGothic'
25
  else:
26
- plt.rcParams['font.family'] = 'Noto Sans CJK TC' # Linux
 
 
 
 
27
 
28
- plt.rcParams['axes.unicode_minus'] = False # 負號使用 ASCII 減號
29
 
30
  @st.cache_resource(show_spinner=True)
31
  def load_model_and_explainer():
32
- # 下載模型與 LabelEncoder
33
  model_path = hf_hub_download(
34
  repo_id="jung-ming/Ocean-Meets-Forest",
35
  filename="rf_model_with_encoder.pkl",
@@ -38,15 +52,11 @@ def load_model_and_explainer():
38
  bundle = joblib.load(model_path)
39
  model = bundle["model"]
40
  le = bundle["label_encoder"]
41
-
42
- # 建立 explainer(避免用 pickle 載入 Numba 編譯物件)
43
  explainer = shap.TreeExplainer(model, feature_perturbation="interventional")
44
-
45
  return model, le, explainer
46
 
47
  model, le, explainer = load_model_and_explainer()
48
 
49
- # 建立映射
50
  ship_type_to_code = dict(zip(le.classes_, le.transform(le.classes_)))
51
 
52
  st.title("🚢 台中港艘次預測系統")
@@ -70,18 +80,16 @@ if st.button("🔮 開始預測"):
70
 
71
  st.subheader("🧠 模型決策解釋圖(SHAP Waterfall plot)")
72
 
73
- # 計算 SHAP 值
74
  shap_values = explainer(input_df)
75
-
76
- # 取得 Axes(shap.plots.waterfall 回傳的是 Axes)
77
  ax = shap.plots.waterfall(shap_values[0], show=False)
78
 
79
- # 設定中文字型
80
- for text in ax.texts:
81
- text.set_fontname("Noto Sans CJK TC")
82
- if text.get_text().startswith('\u2212'):
83
- text.set_text(text.get_text().replace('\u2212', '-'))
 
 
84
 
85
- # 顯示圖表
86
  st.pyplot(ax.figure)
87
  plt.close(ax.figure)
 
1
  import os
2
  os.environ["HF_HOME"] = "/tmp/.cache/huggingface"
3
  os.environ["MPLCONFIGDIR"] = "/tmp/.config/matplotlib"
4
+
5
  import streamlit as st
6
  import joblib
7
  import pandas as pd
 
11
  from huggingface_hub import hf_hub_download
12
  import matplotlib.font_manager as fm
13
 
14
+ # 自訂函數:嘗試找系統中可用的中文字型路徑
15
+ def find_chinese_font():
16
+ for font_path in fm.findSystemFonts(fontext='ttf'):
17
+ # 這裡可依你系統字型名關鍵字調整
18
+ if ("NotoSans" in font_path and ("TC" in font_path or "TraditionalChinese" in font_path)) \
19
+ or "STHeiti" in font_path or "Heiti" in font_path or "LiHei" in font_path:
20
+ return font_path
21
+ return None
22
+
23
+ chinese_font_path = find_chinese_font()
24
+ if chinese_font_path:
25
+ chinese_font_prop = fm.FontProperties(fname=chinese_font_path)
26
+ print(f"使用中文字型檔: {chinese_font_path}")
27
+ else:
28
+ chinese_font_prop = None
29
+ print("找不到適合的中文字型檔,請確認系統已安裝中文字型")
30
 
31
+ # matplotlib 全局字型設定(Fallback用)
32
  if platform.system() == 'Windows':
33
  plt.rcParams['font.family'] = 'Microsoft JhengHei'
34
  elif platform.system() == 'Darwin': # macOS
35
  plt.rcParams['font.family'] = 'AppleGothic'
36
  else:
37
+ # Linux 預設用找到的字型名稱,沒找到就用 DejaVu Sans
38
+ if chinese_font_prop:
39
+ plt.rcParams['font.family'] = chinese_font_prop.get_name()
40
+ else:
41
+ plt.rcParams['font.family'] = 'DejaVu Sans'
42
 
43
+ plt.rcParams['axes.unicode_minus'] = False # 負號用 ASCII 減號
44
 
45
  @st.cache_resource(show_spinner=True)
46
  def load_model_and_explainer():
 
47
  model_path = hf_hub_download(
48
  repo_id="jung-ming/Ocean-Meets-Forest",
49
  filename="rf_model_with_encoder.pkl",
 
52
  bundle = joblib.load(model_path)
53
  model = bundle["model"]
54
  le = bundle["label_encoder"]
 
 
55
  explainer = shap.TreeExplainer(model, feature_perturbation="interventional")
 
56
  return model, le, explainer
57
 
58
  model, le, explainer = load_model_and_explainer()
59
 
 
60
  ship_type_to_code = dict(zip(le.classes_, le.transform(le.classes_)))
61
 
62
  st.title("🚢 台中港艘次預測系統")
 
80
 
81
  st.subheader("🧠 模型決策解釋圖(SHAP Waterfall plot)")
82
 
 
83
  shap_values = explainer(input_df)
 
 
84
  ax = shap.plots.waterfall(shap_values[0], show=False)
85
 
86
+ # 強制為每個文字物件設定中文字型,避免顯示方塊
87
+ if chinese_font_prop:
88
+ for text in ax.texts:
89
+ text.set_fontproperties(chinese_font_prop)
90
+ # 修正負號顯示問題(使用 ASCII 減號)
91
+ if text.get_text().startswith('\u2212'):
92
+ text.set_text(text.get_text().replace('\u2212', '-'))
93
 
 
94
  st.pyplot(ax.figure)
95
  plt.close(ax.figure)