如何可视化分类器的类别预测概率及置信度分布
分类器预测概率可视化方案
你现有实现的核心问题是直接取predict_proba返回的最大概率值,将「预测为类别0的置信度」和「预测为类别1的置信度」混在同一维度展示,无法单独区分不同置信度下类别1预测结果的价值差异。
优化逻辑
- 单独提取
predict_proba输出中类别1对应的概率值,横轴直接映射模型判定为类别1的置信度,范围0-1,其中0.5是分类阈值,越接近1代表模型越确信样本属于类别1 - 拆分两类可视化图表:一类展示不同预测结果(TP/FP)在置信度轴上的分布,另一类分箱统计不同置信度区间的预测准确率,量化高/低置信度结果的参考价值
- 过滤预测为类别0的样本,避免无关数据干扰类别1置信度的分布展示
可直接运行的优化代码
from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score import seaborn as sns import pandas as pd import matplotlib.pyplot as plt # 生成模拟数据集 X, y = make_classification(n_samples=1000, n_features=4, n_informative=2, n_redundant=0, random_state=0, shuffle=False) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=30) # 训练模型 clf = RandomForestClassifier(max_depth=2, random_state=0) clf.fit(X_train, y_train) # 获取预测结果、类别1的预测概率 y_pred = clf.predict(X_test) # 索引1对应类别1的预测概率,取值范围0-1 y_prob1 = clf.predict_proba(X_test)[:, 1] # 输出基础分类指标 print("准确率:", accuracy_score(y_test, y_pred)) print("精确率:", precision_score(y_test, y_pred)) print("召回率:", recall_score(y_test, y_pred)) print("F1值:", f1_score(y_test, y_pred)) print("混淆矩阵:\n", confusion_matrix(y_test, y_pred)) # 构建结果统计表 df = pd.DataFrame({ "真实标签": y_test, "预测标签": y_pred, "类别1预测概率": y_prob1 }) # 标记混淆矩阵分类 def mark_cm_type(row): if row["预测标签"] == 1: return "真阳性(TP)" if row["真实标签"] == 1 else "假阳性(FP)" else: return "真阴性(TN)" if row["真实标签"] == 0 else "假阴性(FN)" df["结果类型"] = df.apply(mark_cm_type, axis=1) # 图1:类别1预测结果的置信度分布 plt.figure(figsize=(10, 6)) # 只筛选预测为类别1的样本,排除类别0预测的干扰 sns.kdeplot( data=df[df["预测标签"] == 1], x="类别1预测概率", hue="结果类型", fill=True, common_norm=False ) plt.xlabel("预测为类别1的概率(置信度)") plt.ylabel("样本密度") plt.title("类别1预测结果的置信度分布") plt.xlim(0.5, 1) plt.show() # 图2:分置信度区间统计预测准确率 # 按0.1步长拆分置信度区间 df["置信度区间"] = pd.cut( df["类别1预测概率"], bins=[0, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0], right=False ) bin_stat = df.groupby("置信度区间").apply( lambda g: pd.Series({ "样本量": len(g), "区间准确率": (g["真实标签"] == g["预测标签"]).mean() }) ).reset_index() plt.figure(figsize=(10, 6)) sns.barplot(data=bin_stat, x="置信度区间", y="区间准确率", color="#3b75af") plt.xlabel("类别1预测概率区间") plt.ylabel("区间内预测准确率") plt.title("不同置信度区间的预测效果") plt.ylim(0, 1.1) # 在柱上标注对应区间的样本量 for idx, row in bin_stat.iterrows(): plt.text(idx, row["区间准确率"] + 0.02, f"n={int(row['样本量'])}", ha="center") plt.show()
效果说明
- 第一张密度图横轴从0.5(分类阈值)到1,完全对应类别1的预测置信度,你可以直接观察到:80%以上高置信度的预测几乎都是正确的TP样本,51%左右的低置信度预测中FP错误样本占比很高,直接体现两类正确预测的价值差异
- 第二张柱状图量化了每个置信度段的预测准确率,可以直接作为业务上筛选高价值预测结果的依据,比如可以设置阈值只采纳预测概率≥0.8的结果,过滤掉低置信度的不确定预测
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

