如何使用SHAP绘制真实得分为1但预测值偏低的致病基因样本?
解决筛选真实得分1且预测值低于阈值的样本问题
嘿,我知道你现在卡在筛选目标样本的环节了——明明只有1个符合条件的基因,但代码却画出了全部171个样本,这肯定是筛选逻辑或者数据结构出了小问题。咱们一步步来解决:
1. 先确认筛选条件是否真的选中了目标样本
在急着画SHAP图之前,先做个小验证,看看你的筛选条件到底有没有选到正确的样本:
# 打印符合条件的样本数量,应该是1才对 print("符合条件的样本数:", sum(m)) # 直接查看筛选后的真实值和预测值,确认是不是你要的那个基因 print("筛选后的真实得分:", Y_test[m]) print("筛选后的预测得分:", y_pred[m])
如果这里输出的样本数还是171,那大概率是Y_test的结构或者索引对齐的问题:
- 如果
Y_test是DataFrame(不是你描述的Series),那Y_test ==1会返回一个DataFrame,和y_pred(numpy数组)做与运算会出错,得改成Y_test['Score'] ==1。 - 如果X_test和Y_test的索引没对齐,直接用
Y_test ==1生成的布尔数组会和y_pred的顺序错位,导致筛选失效。
2. 修正后的完整代码
假设你的Y_test是Pandas Series(和你给出的数据结构一致),用下面的代码就能正确筛选:
import shap import xgboost as xgb # 假设模型已经训练好,X_train/Y_train是训练集,X_test/Y_test是测试集 xgbr = xgb.XGBRegressor() xgbr.fit(X_train, Y_train) # 生成SHAP值和预测值 explainer = shap.TreeExplainer(xgbr) shap_values = explainer.shap_values(X_test) y_pred = xgbr.predict(X_test) # 核心:正确生成筛选条件的布尔数组 # 用Y_test.values保证和y_pred的顺序完全一致,避免索引错位 threshold = 0.5 # 你可以改成0.8或者其他阈值 m = (y_pred <= threshold) & (Y_test.values == 1) # 先验证筛选结果 print(f"符合条件的样本数量:{sum(m)}") if sum(m) > 0: # 只针对筛选后的样本绘制SHAP决策图 shap.initjs() shap.decision_plot( explainer.expected_value, shap_values[m], X_test[m], return_objects=True ) else: print("没有找到符合条件的样本,请检查阈值设置或者数据!")
3. 几个关键细节要注意
- 索引对齐问题:如果X_test和Y_test的索引不一样,直接用
Y_test ==1会导致布尔数组的顺序和y_pred不匹配,这时候用Y_test.values直接取数值数组,就能保证顺序完全一致。 - 数据结构检查:确认
Y_test是Series,要是它是DataFrame,记得加上列名,比如Y_test['Score'].values ==1。 - 阈值灵活调整:把代码里的
threshold改成0.8或者你需要的其他值就行。
这样应该就能精准筛选出你要的那1个基因,画出正确的SHAP决策图啦!
内容的提问来源于stack exchange,提问作者DN1
相关产品推荐
相关产品推荐

