sklearn教程14 - 二分类模型评估-混淆矩阵,精确率,召回率,F1-score,ROC曲线与AUC指标
sklearn一站式学习->: sklearn一站式学习,机器学习数据集获取与划分,无量纲化,特征提取,特征降维(低方差,皮尔逊,PCA),KNN,模型选择调优,决策树,朴素贝叶斯,岭回归,kMeans等等
python一站式学习->: python一站式学习,python基础,数据类型,numpy,pandas,机器学习,NLP自然语言处理,deepseek大预言模型,Tensorflow,CV视觉
混淆矩阵
如下表格,当真实结果为正例,预测结果也为正叫真正例TP,预测结果为反则叫伪正例FP,同理当真实结果为假例,预测结果为正例叫伪正例FP,预测结果为假例则叫真反例TN,构成混淆矩阵。
预测/真实 | 预测正例 | 预测假例 |
---|---|---|
真实正例 | 真正例TP | 伪反例FN |
真实假例 | 伪正例FP | 真反例TN |
精准率 (Precision)
预测结果为正例样本中真实为正例的比例。(正例预测准确度,伪正例FP部分预测错误)
召回率(Recall)
真实为正例的样本中预测结果为正例的比例。(正例预测全不全,漏掉了伪反例FN)
F1-score
反应模型的稳健性
F
1
−
s
c
o
r
e
=
2
×
(
精确率
×
召回率
)
/
(
精确率
+
召回率
)
F1-score = 2 × (精确率 × 召回率) / (精确率 + 召回率)
F1−score=2×(精确率×召回率)/(精确率+召回率)
精确率(Precision)与召回率(Recall)存在天然矛盾时(例如提高召回率往往需要降低精确率,反之亦然),F1-score 通过调和平均数强制要求两者的均衡。
示例:
若模型 A:Precision=0.9, Recall=0.5 → F1 = 0.64
若模型 B:Precision=0.7, Recall=0.7 → F1 = 0.70
结论: 虽然模型 A 精确率更高,但 F1-score 显示模型 B 的综合性能更好。
代码示例
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
def linear5_demo():
# 乳腺癌数据
breastCancer = load_breast_cancer()
print(breastCancer)
#训练集特征值,测试集特征值,训练集目标值,测试集目标值
x_train, x_test, y_train, y_test = train_test_split(breastCancer.data, breastCancer.target, random_state=10)
# 数据进行标准化,较少影响
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 预估器
# penalty 正则化方式 L1 L2
# C 正则化力度默认1.0 范围 0.001(强正则化)到 100(弱正则化)
# max_iter 最大迭代次数 默认100
# solver 选择优化算法 liblinear 适合小数据集,支持 L1/L2;仅用于二分类。
# lbfgs(默认值):适合中等数据集,支持 L2 或 penalty='none'。
# 'sag' 或 'saga':随机梯度下降变种,适合大数据集;saga 还支持 L1、弹性网。
# 'newton-cg':牛顿法,需计算 Hessian 矩阵,适合小数据集。
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
print("模型的回归系数参数-----",estimator.coef_)
print("模型的偏置截距-----",estimator.intercept_)
#模型评估
res = estimator.score(x_test,y_test)
print("模型准确率为:",res)
y_perdict = estimator.predict(x_test)
report = classification_report(y_test,y_perdict,labels=[0,1],target_names=breastCancer["target_names"])
print(report)
if __name__ == '__main__':
linear5_demo()
结果返回: Precision精准率,Recall召回率,F1-score,support样本数
当样本不均衡,会有什么问题?
假如有100人,其中99个人得了乳腺癌,一个没有的病,假如有一个模型,不管怎样全都预测为正例得了癌症,计算得出:
准确率=99%
召回率=100%
精准率=99%
F1-score=99.5%
模型评估数据很好,但是模型实际是乱输出全部都得了癌症,明显没有评估出来这个模型的不可靠性。因此引入ROC曲线和AUC指标来解决这个问题。
TPR
所有实际类别为正例的样本中,预测类别为正例的比例(召回率)
TPR = TP/(TP+FN)
FPR
所有真实类别为假例的样本中,预测类别为正例的比例
ROC曲线
图中蓝色部分表示Roc曲线,x横轴是FPR,y纵轴是TPR,当两者相等时(图中红色虚线),表示无论真实样本室是正还是假,分类器预测为1的概率是相等的,此时AUC为0.5,当曲线往蓝色方向靠近,达到左上角,其实就是样本全为正例,预测全部正确都是正例,此时预测最准,此时AUC为1
AUC指标
如上图,AUC是图中ROC曲线和xy坐标轴的面积,含义如下:
AUC最小为0.5,最大为1,取值越高则说明模型越好,AUC=1时候则是理想的完美分类器。
此时使用AUC判断上面100个癌症例子,AUC=0.5,模型评估出了这个模型最差。
代码示例
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
def linear6_demo():
# 乳腺癌数据
breastCancer = load_breast_cancer()
print(breastCancer)
#训练集特征值,测试集特征值,训练集目标值,测试集目标值
x_train, x_test, y_train, y_test = train_test_split(breastCancer.data, breastCancer.target, random_state=10)
# 数据进行标准化,较少影响
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 预估器
# penalty 正则化方式 L1 L2
# C 正则化力度默认1.0 范围 0.001(强正则化)到 100(弱正则化)
# max_iter 最大迭代次数 默认100
# solver 选择优化算法 liblinear 适合小数据集,支持 L1/L2;仅用于二分类。
# lbfgs(默认值):适合中等数据集,支持 L2 或 penalty='none'。
# 'sag' 或 'saga':随机梯度下降变种,适合大数据集;saga 还支持 L1、弹性网。
# 'newton-cg':牛顿法,需计算 Hessian 矩阵,适合小数据集。
estimator = LogisticRegression()
estimator.fit(x_train, y_train)
print("模型的回归系数参数-----",estimator.coef_)
print("模型的偏置截距-----",estimator.intercept_)
#模型评估
res = estimator.score(x_test,y_test)
print("模型准确率为:",res)
y_predict = estimator.predict(x_test)
# y_true: 测试样本的真实目标值,必须是数字0,1,必须为0反例,1正例
# y_score: 预测得分,可以是正类的预估概率,也可以是分类器的返回值
auc = roc_auc_score(y_true=y_test,y_score=y_predict)
print("模型的auc为:",auc)
if __name__ == '__main__':
linear6_demo()
AUC为0.95879,很接近1,说明模型效果不错