Multiple123 commited on
Commit
0683b82
·
verified ·
1 Parent(s): 60ae188

Upload 4 files

Browse files
Files changed (4) hide show
  1. Gradio.py +141 -0
  2. SVM_pipeline.pkl +3 -0
  3. bg.csv +101 -0
  4. requirements.txt .txt +0 -0
Gradio.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Gradio.py
2
+ import gradio as gr
3
+ import pandas as pd
4
+ import joblib
5
+ import shap
6
+ import numpy as np
7
+ import matplotlib
8
+ matplotlib.use("Agg") # 无交互后端更稳
9
+ import matplotlib.pyplot as plt
10
+ import warnings
11
+ warnings.filterwarnings("ignore")
12
+
13
+ # ====== 路径与特征 ======
14
+ MODEL_PATH = "models/SVM_pipeline.pkl"
15
+ BG_PATH = "data/bg.csv"
16
+ feature_labels = [
17
+ "HGB (g/L)", "HDL-C (mmol/L)", "DBIL (μmol/L)", "AST/ALT", "UA (μmol/L)",
18
+ "GFR (mL/min/1.73 m²)", "PNI", "HALP", "AAPR", "conuts"
19
+ ]
20
+ feature_names = ["HGB","HDL_C","DBIL","AST_ALT","UA","GFR","PNI","HALP","AAPR","conuts"]
21
+
22
+ # ====== 加载模型和背景 ======
23
+ pipeline = joblib.load(MODEL_PATH)
24
+ bg_df = pd.read_csv(BG_PATH)
25
+ bg_array = bg_df[feature_names].to_numpy(dtype=np.float64)
26
+
27
+ # ====== 全局 KernelExplainer(只建一次) ======
28
+ def _predict_proba_nd(x_nd: np.ndarray) -> np.ndarray:
29
+ df = pd.DataFrame(x_nd, columns=feature_names)
30
+ return pipeline.predict_proba(df)
31
+
32
+ explainer = shap.KernelExplainer(_predict_proba_nd, bg_array)
33
+
34
+ def predict_and_shap(HGB, HDL_C, DBIL, AST_ALT, UA, GFR, PNI, HALP, AAPR, conuts, nsamples=200):
35
+ status_msgs = []
36
+ try:
37
+ # 1) 输入与补全
38
+ input_df = pd.DataFrame([[HGB, HDL_C, DBIL, AST_ALT, UA, GFR, PNI, HALP, AAPR, conuts]],
39
+ columns=feature_names).apply(pd.to_numeric, errors="coerce")
40
+ if input_df.isnull().values.any():
41
+ med = pd.Series(np.median(bg_array, axis=0), index=feature_names)
42
+ input_df = input_df.fillna(med)
43
+ status_msgs.append("Missing values filled with background medians.")
44
+
45
+ # 2) 概率
46
+ prob = float(pipeline.predict_proba(input_df)[0, 1])
47
+ status_msgs.append(f"Pred prob computed: {prob:.3f}")
48
+
49
+ # 3) SHAP
50
+ x_row = input_df.to_numpy(dtype=np.float64) # (1, n_features)
51
+ shap_out = explainer.shap_values(x_row, nsamples=int(nsamples))
52
+
53
+ # —— 统一提取“正类”一维向量 (n_features,) ——
54
+ if isinstance(shap_out, list):
55
+ sv = np.asarray(shap_out[1], dtype=np.float64)
56
+ if sv.ndim == 2:
57
+ sv = sv[0, :]
58
+ else:
59
+ sv = np.asarray(shap_out, dtype=np.float64)
60
+ if sv.ndim == 3: # (1, n_features, n_classes)
61
+ sv = sv[0, :, 1] # 正类通道
62
+ elif sv.ndim == 2: # (1, n_features)
63
+ sv = sv[0, :]
64
+ else:
65
+ sv = sv.reshape(-1)
66
+
67
+ x_1d = x_row[0, :].astype(np.float64)
68
+ status_msgs.append(f"SHAP 1D shape: {sv.shape}; features: {x_1d.shape}")
69
+
70
+ # base value 取正类
71
+ ev = explainer.expected_value
72
+ if isinstance(ev, (list, np.ndarray)):
73
+ ev = np.asarray(ev).reshape(-1)
74
+ base_val = float(ev[1] if len(ev) > 1 else ev[0])
75
+ else:
76
+ base_val = float(ev)
77
+
78
+ fnames = [str(f) for f in feature_names]
79
+
80
+ # 4) 力图(关键:不要先建 fig;让 SHAP 画完后用 plt.gcf() 接回真正的 Figure)
81
+ try:
82
+ plt.close('all') # 清理历史句柄,防串扰
83
+ shap.force_plot(base_val, sv, x_1d,
84
+ feature_names=fnames,
85
+ matplotlib=True, show=False)
86
+ fig = plt.gcf() # 取 SHAP 实际绘制的 Figure
87
+ fig.set_size_inches(8, 4) # 调整尺寸
88
+ plt.tight_layout()
89
+ status_msgs.append("Rendered force plot (matplotlib) on current figure.")
90
+ return round(prob, 3), fig, "\n".join(status_msgs)
91
+ except Exception as e_force:
92
+ status_msgs.append(f"Force-plot failed: {repr(e_force)}; fallback=bar")
93
+
94
+ # 5) 条形图兜底(返回实际 fig)
95
+ order = np.argsort(np.abs(sv))[::-1]
96
+ topk = order[:min(10, sv.shape[0])]
97
+ plt.close('all')
98
+ fig = plt.figure(figsize=(8, 5), dpi=160)
99
+ plt.barh(np.array(fnames)[topk], sv[topk])
100
+ plt.xlabel("SHAP value")
101
+ plt.title("Top features (single-sample contribution)")
102
+ plt.gca().invert_yaxis()
103
+ plt.tight_layout()
104
+ status_msgs.append("Rendered bar fallback.")
105
+ return round(prob, 3), fig, "\n".join(status_msgs)
106
+
107
+ except Exception as e:
108
+ return None, None, f"Fatal error: {repr(e)}"
109
+
110
+
111
+ # ====== Blocks 界面 ======
112
+ example_values = [137, 1.76, 8.6, 0.97, 310, 75.4, 44, 60.8, 0.486, 4, 200]
113
+
114
+ with gr.Blocks() as demo:
115
+ gr.Markdown(
116
+ "### SVM Meige Risk Prediction & SHAP Explanation\n"
117
+ "Enter 10 indicators with **units** to predict risk and view an individualized explanation.\n\n"
118
+ "**Example**: HGB=137 g/L, HDL‑C=1.76 mmol/L, DBIL=8.6 μmol/L, AST/ALT=0.97, UA=310 μmol/L, "
119
+ "GFR=75.4 mL/min/1.73 m², PNI=44, HALP=60.8, AAPR=0.486, conuts=4."
120
+ )
121
+ with gr.Row():
122
+ with gr.Column(scale=1):
123
+ num_inputs = [gr.Number(label=feature_labels[i], precision=3) for i in range(10)]
124
+ ns_slider = gr.Slider(100, 400, value=200, step=50, label="SHAP nsamples")
125
+ btn_fill = gr.Button("Fill with Example")
126
+ btn_predict = gr.Button("Predict")
127
+ with gr.Column(scale=1):
128
+ out_prob = gr.Number(label="Predicted Probability")
129
+ out_plot = gr.Plot(label="SHAP Force (fallback: bar)") # 改成 Plot
130
+ out_log = gr.Textbox(label="Status", lines=6)
131
+
132
+ def fill_example():
133
+ return tuple(example_values)
134
+
135
+ fill_evt = btn_fill.click(fn=fill_example, outputs=[*num_inputs, ns_slider])
136
+ fill_evt.then(fn=predict_and_shap, inputs=[*num_inputs, ns_slider], outputs=[out_prob, out_plot, out_log])
137
+ btn_predict.click(fn=predict_and_shap, inputs=[*num_inputs, ns_slider], outputs=[out_prob, out_plot, out_log])
138
+
139
+ if __name__ == "__main__":
140
+ demo.launch() # 不要写 server_port / share
141
+
SVM_pipeline.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:047c40ba33e09d3832be4780fa4c8f01d54fca909e46483f527c78c73193b85f
3
+ size 47609
bg.csv ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ HGB,HDL_C,DBIL,AST_ALT,UA,GFR,PNI,HALP,AAPR,conuts
2
+ 132.0,1.7,3.7,1.13,231.7,90.07,46.55,27.4610869565217,0.540909090909091,3.0
3
+ 129.0,1.19,3.4,1.03,391.6,101.03,50.95,41.8843891050584,0.584931506849315,1.0
4
+ 136.0,1.44,4.8,1.09,315.8,98.86,53.9,58.2750960451977,0.631746031746032,1.0
5
+ 152.0,1.3,5.9,0.97,546.1,106.98,55.05,59.6915165876777,0.643243243243243,1.0
6
+ 137.0,1.44,3.1,1.13,269.0,79.67,53.45,50.2163187250996,0.596825396825397,1.0
7
+ 144.0,1.16,4.0,0.94,470.1,73.81,49.5,55.5957735849057,0.615942028985507,1.0
8
+ 128.0,1.54,3.4,1.05,196.6,102.24,52.65,53.6932080536913,0.533802816901408,1.0
9
+ 118.0,1.45,3.5,1.21,281.4,96.89,50.2,34.6722614840989,0.579411764705882,1.0
10
+ 150.0,1.09,3.4,0.9,369.3,103.36,53.45,77.4636464088398,0.648387096774194,1.0
11
+ 131.0,1.83,3.5,1.25,130.0,95.95,55.3,49.3474222222222,0.594186046511628,1.0
12
+ 146.0,1.02,4.1,0.96,361.3,98.57,54.65,61.7651358024691,0.59672131147541,2.0
13
+ 157.0,0.89,3.4,1.54,463.4,75.78,52.5,290.7954,0.604109589041096,0.0
14
+ 150.0,1.17,3.5,0.74,414.5,102.37,54.7,82.0826086956522,0.658823529411765,1.0
15
+ 130.0,1.53,3.2,1.04,258.9,102.01,55.55,53.6619047619048,0.596825396825397,1.0
16
+ 119.0,1.54,3.7,1.1,301.1,76.37,47.1,26.8027137546468,0.548717948717949,2.0
17
+ 137.0,1.38,5.7,0.95,670.2,65.16,60.1,80.7659803921569,0.589855072463768,1.0
18
+ 142.0,1.26,4.0,1.04,482.1,101.21,53.5,45.2771428571429,0.624324324324324,0.0
19
+ 151.0,1.21,4.6,0.91,426.3,98.18,52.9,51.4008870967742,0.6,1.0
20
+ 134.0,1.3,4.3,1.04,341.3,90.54,47.85,36.4060913705584,0.664406779661017,2.0
21
+ 151.0,1.36,4.6,0.87,351.8,89.86,58.45,108.456652173913,0.48,1.0
22
+ 142.0,1.2,3.9,0.81,333.8,113.95,53.2,52.1544452830189,0.578947368421053,0.0
23
+ 140.0,1.22,4.6,0.95,601.4,92.38,51.4,47.3324074074074,0.437209302325581,2.0
24
+ 163.0,1.09,6.1,0.92,460.2,69.36,70.15,122.7275390625,0.778787878787879,0.0
25
+ 119.0,1.4,3.4,1.08,323.3,103.7,48.7,24.7887240356083,0.53010752688172,2.0
26
+ 127.0,1.58,2.8,0.92,238.9,110.82,49.5,39.8511627906977,0.571264367816092,1.0
27
+ 110.0,1.39,2.7,1.22,183.8,96.86,45.55,27.6332129963899,0.481720430107527,2.0
28
+ 134.0,1.25,5.0,1.41,274.2,99.34,55.2,120.845428571429,0.472151898734177,1.0
29
+ 133.0,1.21,5.4,1.13,366.7,71.27,53.85,55.46675,0.579220779220779,1.0
30
+ 99.0,1.24,6.1,2.0,523.0,98.81,50.95,108.456652173913,0.856603773584906,2.0
31
+ 116.0,1.33,2.8,1.21,330.3,70.26,48.9,38.3033823529412,0.526506024096386,1.0
32
+ 136.0,1.37,4.7,1.38,305.5,85.6,52.9,74.008389261745,0.571264367816092,1.0
33
+ 131.0,1.4,4.4,1.07,310.8,74.19,51.45,49.0450427350427,0.588888888888889,1.0
34
+ 141.0,1.51,4.5,1.26,299.4,95.04,50.5,48.1088612440191,0.480232558139535,1.0
35
+ 114.0,1.45,3.2,1.09,149.3,107.79,47.45,33.2416492890995,0.546575342465753,2.0
36
+ 114.0,1.36,3.2,1.5,218.5,89.02,47.6,31.9235744680851,0.633783783783784,2.0
37
+ 117.0,1.36,3.3,1.12,354.6,99.1,50.0,26.8027137546468,0.577922077922078,1.0
38
+ 134.0,1.47,4.0,1.03,246.4,96.66,50.95,44.2446101694915,0.55,1.0
39
+ 149.0,1.45,4.5,1.13,470.1,86.45,75.5,183.506441314554,0.744615384615385,0.0
40
+ 122.0,1.37,3.3,1.06,299.4,104.48,48.75,36.8510972222222,0.541558441558442,1.0
41
+ 122.0,1.5,4.4,1.17,506.9,71.27,51.15,40.9683116883117,0.486516853932584,1.0
42
+ 137.0,1.27,4.1,0.93,331.9,79.41,54.35,60.4224958677686,0.559322033898305,1.0
43
+ 82.0,1.28,2.1,1.07,293.6,111.34,48.75,15.3354570637119,0.610810810810811,3.0
44
+ 124.0,1.65,3.3,1.21,231.7,95.04,51.1,36.536987654321,0.603896103896104,1.0
45
+ 143.0,1.18,4.2,0.87,506.9,103.95,57.9,73.5057631578947,0.646666666666667,0.0
46
+ 126.0,1.55,3.0,1.27,238.0,96.2,57.4,67.817037037037,0.580769230769231,1.0
47
+ 118.0,1.34,3.9,1.08,408.6,76.84,58.65,85.7889204545454,0.585135135135135,1.0
48
+ 155.0,1.11,6.3,0.87,534.3,101.84,58.95,90.3471627906977,0.646666666666667,1.0
49
+ 131.0,1.45,3.9,1.11,291.4,102.63,53.2,56.9895890410959,0.504,0.0
50
+ 137.0,1.69,3.7,1.1,390.6,77.41,55.0,49.5774193548387,0.778787878787879,1.0
51
+ 127.0,1.49,4.6,1.04,277.9,100.95,55.05,71.6292926829268,0.548717948717949,1.0
52
+ 143.0,1.49,3.5,1.03,277.2,98.91,52.25,41.1708461538462,0.607352941176471,1.0
53
+ 106.0,1.15,3.6,1.0,430.6,68.14,46.1,19.6638412698413,0.380188679245283,3.0
54
+ 123.0,1.32,2.8,1.15,266.2,104.75,49.45,31.7607572016461,0.552439024390244,1.0
55
+ 145.0,1.17,4.0,0.94,448.6,99.93,57.45,73.7326451612903,0.654716981132076,1.0
56
+ 145.0,1.11,4.1,0.93,385.5,98.59,53.45,54.3200561797753,0.636708860759494,1.0
57
+ 142.0,1.1,3.0,0.94,404.7,111.32,52.5,57.8297872340426,0.655384615384615,1.0
58
+ 82.0,1.36,1.8,1.28,189.5,113.95,47.5,21.8946428571429,0.566666666666667,2.0
59
+ 135.0,1.14,3.2,0.91,557.7,75.24,50.7,52.9145755395683,0.595522388059701,1.0
60
+ 158.0,1.1,6.6,0.73,597.5,103.31,58.15,74.008389261745,0.665714285714286,1.0
61
+ 116.0,1.17,2.5,1.47,461.1,82.31,52.45,35.004404494382,0.462222222222222,0.0
62
+ 136.0,1.16,2.9,0.89,535.0,94.38,49.3,20.3062068965517,0.593150684931507,1.0
63
+ 130.0,1.27,4.3,1.04,424.4,87.57,51.35,40.9683116883117,0.588888888888889,1.0
64
+ 126.0,1.44,3.0,1.25,177.9,77.41,47.1,28.8406535947712,0.497802197802198,1.0
65
+ 124.0,1.43,2.5,1.05,309.5,81.86,71.6,173.6,0.631034482758621,1.0
66
+ 122.0,1.32,3.7,1.4,268.5,75.64,51.7,54.3717391304348,0.580769230769231,1.0
67
+ 128.0,1.33,3.6,1.05,371.9,95.8,55.75,57.2821489361702,0.626760563380282,0.0
68
+ 151.0,1.25,5.1,1.07,269.0,107.97,57.75,67.3918937007874,0.544444444444445,0.0
69
+ 122.0,1.18,3.3,1.28,181.3,57.38,62.5,67.6511328671329,0.759322033898305,1.0
70
+ 135.0,1.92,3.9,1.0,175.2,103.08,51.75,106.644214285714,0.380833333333333,1.0
71
+ 133.0,1.62,3.7,1.09,242.4,67.64,52.2,54.4356616915423,0.527027027027027,0.0
72
+ 138.0,0.59,2.8,0.81,601.4,57.35,43.65,71.21628,0.224539877300614,2.0
73
+ 132.0,1.57,4.4,1.15,214.8,102.05,48.9,29.2779180327869,0.697014925373134,1.0
74
+ 124.0,1.59,3.2,1.22,220.2,112.7,48.85,32.8390985915493,0.731818181818182,2.0
75
+ 130.0,1.45,5.1,1.4,351.0,80.67,56.65,92.8677777777778,0.706666666666667,1.0
76
+ 98.0,1.99,2.0,2.0,109.8,110.69,49.5,24.1474427244582,0.679310344827586,1.0
77
+ 132.0,1.5,3.8,1.24,174.8,92.26,55.6,59.5344424778761,0.5375,1.0
78
+ 167.0,1.14,4.2,0.42,189.5,100.63,58.15,71.1265506607929,0.559302325581395,0.0
79
+ 124.0,1.48,3.3,1.03,287.0,96.55,51.55,47.8750222222222,0.521518987341772,1.0
80
+ 132.0,1.16,3.4,1.03,454.9,101.69,51.15,39.8511627906977,0.593150684931507,1.0
81
+ 158.0,1.54,3.4,0.8,293.6,100.56,55.9,88.0431515151515,0.515492957746479,0.0
82
+ 137.0,1.57,4.5,1.32,251.9,78.35,59.05,96.1015580110497,0.658823529411765,1.0
83
+ 124.0,1.37,3.8,1.0,385.1,88.38,48.55,29.1562409638554,0.551162790697674,2.0
84
+ 112.0,1.42,3.5,1.41,212.5,99.38,50.8,53.0095471698113,0.622222222222222,1.0
85
+ 137.0,1.51,3.6,1.0,361.1,94.74,48.95,42.4801390374332,0.55,2.0
86
+ 135.0,1.44,3.8,1.26,323.3,96.89,51.8,40.0811392405063,0.614666666666667,1.0
87
+ 142.0,1.09,2.5,0.63,512.4,103.89,48.65,35.3753720930233,0.68955223880597,1.0
88
+ 117.0,1.44,3.6,1.3,246.4,101.93,48.25,27.3475486381323,0.526506024096386,2.0
89
+ 148.0,1.71,3.9,0.88,398.4,95.82,49.65,119.817384615385,0.524324324324324,1.0
90
+ 132.0,1.55,3.7,1.23,182.8,103.55,52.25,34.0649189189189,0.612,1.0
91
+ 133.0,1.43,3.8,1.08,219.1,89.77,53.85,45.6858396624473,0.540909090909091,1.0
92
+ 103.0,1.55,2.1,1.2,217.8,105.7,47.45,27.5368623853211,0.673529411764706,2.0
93
+ 124.0,1.57,4.2,1.16,255.8,85.85,48.05,32.2556896551724,0.502150537634409,1.0
94
+ 155.0,1.35,4.6,0.91,341.8,103.83,56.2,81.9420689655173,0.584375,0.0
95
+ 116.0,1.41,3.3,1.21,314.5,96.12,50.25,38.2610149253731,0.652542372881356,1.0
96
+ 116.0,1.38,2.8,1.05,203.4,101.7,46.8,31.0153846153846,0.585135135135135,2.0
97
+ 133.0,1.38,3.9,0.97,305.5,104.87,59.85,77.9077894736842,0.595522388059701,0.0
98
+ 152.0,1.3,5.1,1.08,302.0,97.9,54.05,60.8694129353234,0.60126582278481,1.0
99
+ 128.0,1.24,3.5,1.11,342.3,97.97,53.9,53.6932080536913,0.565432098765432,1.0
100
+ 126.0,1.23,1.9,1.0,470.4,103.74,57.25,72.2843137254902,0.634782608695652,1.0
101
+ 138.0,1.4,6.0,1.17,224.1,108.29,50.0,58.0794520547945,0.648387096774194,2.0
requirements.txt .txt ADDED
File without changes