sklearn.confusion_matrix默认按标签排序而非训练顺序,导致TP/FP错位;需显式指定labels并用classification_report核对;ROC需predict_proba等连续分数,多分类需OvR策略。

sklearn.metrics.confusion_matrix 为什么输出和你想的不一样
默认情况下 confusion_matrix 把第一类(索引 0)当负例、第二类当正例,但如果你的标签是 ['cat', 'dog'] 或数值从 1 开始(比如 [1, 2]),它会按排序值分正负——不是按你训练时的逻辑顺序。结果就是 TP/FP 位置反了,后续准确率、召回率全错。
- 显式指定
labels=[0, 1]或labels=['neg', 'pos'],确保行列顺序可控 - 用
normalize='true'看每行比例(查全率),normalize='pred'看每列比例(查准率) - 别直接 print 矩阵就完事——配合
classification_report(y_true, y_pred)核对 F1 是否合理
ROC 曲线画出来是直线或抖动严重
根本原因通常是预测得分没用概率或置信度输出,而是用了 model.predict() 的硬分类结果。ROC 需要的是“模型认为正例有多确定”,也就是连续型分数,比如 model.predict_proba()[:, 1] 或 model.decision_function()。
- 二分类下,优先用
predict_proba;SVM、LinearSVC 这类没概率接口的,改用decision_function - 如果 label 是字符串(如
['no', 'yes']),predict_proba列顺序可能不对应,先用model.classes_确认索引 -
roc_curve对样本少于 50 的数据很敏感,插值点稀疏会导致曲线不平滑——不是 bug,是统计波动
plt.plot(fpr, tpr) 画出的 ROC 没过左上角,AUC 小于 0.5
AUC
- 检查
y_true中正例占比,再看y_score分布:如果大部分 score > 0.5 但正例占比很低,大概率是标签编码反了 - 快速验证:把
y_score取反(1 - y_score),重算 AUC —— 如果变成 > 0.5,就该翻转标签或调整阈值逻辑 - 别手动调换
fpr/tpr去“修正”曲线,那是掩盖问题
多分类场景下还硬套二分类 ROC 和混淆矩阵
sklearn 的 confusion_matrix 支持多类,但 roc_curve 和 auc 默认只接受二分类。强行喂三类标签会报错 ValueError: Target is multiclass but average='binary'。
立即学习“Python免费学习笔记(深入)”;
- 多分类混淆矩阵:直接传入多维
y_true和y_pred,用labels控制行列顺序即可 - 多分类 ROC:得用 one-vs-rest(OvR)策略,对每个类单独算一对 fpr/tpr,再用
label_binarize+OneVsRestClassifier配合 - 注意
predict_proba输出 shape:如果是 (n_samples, n_classes),别直接取 [:, 1],要用np.argmax或按 class index 提取对应列
混淆矩阵里对角线看着高,不代表模型好——类别极度不均衡时,光靠猜多数类就能刷高准确率。ROC 虽能缓解这问题,但前提是你的正例定义清晰、得分可比、标签没被 sklearn 自动重排过。



















