机器学习——模型评估与P-R曲线

目录

前言

一、常见的性能度量

        1.错误率和精度

        2.混淆矩阵

        3.P-R曲线

        4.ROC曲线

二、实现P-R曲线

        1.生成数据集

        2.训练模型

        3.计算混淆矩阵

        4.绘制P-R曲线

三、实现ROC曲线、

        1. 生成数据集

        2.训练模型

        3.计算出FPR、TPR和AUC

        4.绘制ROC曲线


前言

        在机器学习中,通常有多种学习算法可选择。而选择哪一个算法、使用哪一种参数配置就是机器学习中的模型选择问题。模型选择本质上是选择出泛化误差小的模型泛化误差需要用到一系列的实验评估方法获得某种性能度量指标。

          性能度量是机器学习中非常重要的概念之一。这是因为性能度量本质是衡量模型泛化能力好坏的标准,反映了任务需求。

一、常见的性能度量

        1.错误率和精度

        在分类任务中,即预测离散值的问题,最常用的是错误率(Error Rate)精度(Accuracy)表示。

  • 错误率是分类错误的样本数占样本总数的比例,定义为

  • 精度是分类正确的样本数占样本总数的比例,定义为

        2.混淆矩阵

        错误率和精度虽然常用,但是不适用与所有的任务需求。这时就需要用查准率(precision)和查全率(revall)来解决问题。

        混淆矩阵(Confusion Matrix)是一种常用的评价分类模型性能的方法。 它基于模型预测结果和真实分类结果之间的交叉比对。

  • TP:True Positive, 把正类预测为正类
  • FP:False Positive,把负类预测为正类
  • TN:True Negative, 把负类预测为负类
  • FN:False Negative,把正类预测为负类

 查准率(Precision)又称为精确率:在所有被预测为正类的样本中真实结果也为正类的占比。

P=\frac{TP}{TP+FP}

 查全率(Recall) 又称为召回率:所有实际为真的样本被预测为真的的概率

R=\frac{TP}{TP+FN}

查准率和查全率往往是一对矛盾量的:当我们试图提高查准率时,可能会降低查全率; 反之亦然。 这是因为调整模型的预测策略,如提高分类阈值,可以增加预测为正例的准确性,但也可能过滤掉一些真正的正例,从而降低查全率; 相反,降低分类阈值可以捕捉更多正例,但也可能导致误报增加,从而降低查准率。

3.P-R曲线

正因为查准率和查全率往往是一对矛盾量,而我们想要得到查准率和查全率都较高的值,这时就可以使用的度量方法就是绘制P-R曲线。

在 P-R 曲线中,横轴表示查全率(Recall),纵轴表示查准率(Precision)。 每个点代表着使用不同阈值得到的查准率和查全率的组合。 通过在不同阈值上调整模型的预测策略,可以得到一系列不同的查准率和查全率值,进而绘制出 P-R 曲线。

另外P-R曲线可以比较学习器的性能

如果一个学习器的P-R曲线被另一个学习器的P-R曲线完全包住,则可断言后者的性能优于前者。但更常用的是平衡点或者是F1值。平衡点(BEP)是P=R时的取值,如果这个值较大,则说明学习器的性能较好。而F1 = 2 * P * R /( P + R ),同样,F1值越大,我们可以认为该学习器的性能较好。如图:

 4.ROC曲线

在ROC 曲线中,横轴表示假正例率(FPR),纵轴表示真正例率(TPR)。 每个点代表着使用不同阈值得到的 FPR 和 TPR 的组合。 根据模型的预测结果,通过在不同阈值上调整判断是否为正例的条件,可以得到一系列不同的 FPR 和 TPR 值,进而绘制出 ROC 曲线。

真正例率:被预测为正例占真实正例的比例(与查全率相同)

TPR=\frac{TP}{TP+FN}

假正例率:被预测为正例占真实反例比例

FPR=\frac{FP}{TN+FP}

ROC 曲线的特点是 FPR 和 TPR 都在 [0, 1] 的范围内,并且随着阈值的变化而变化。

ROC曲线下的面积(AUC,Area Under the Curve)可以作为模型性能的度量。

ROC曲线同样可以比较学习器的性能。

若一个学习器的 ROC 曲线被另 一个学习器的曲线完全"包住", 则可断言后者的性能优于前者;
若两个学习器的 ROC 曲线发生交叉,则难以-般性地断言两者孰优孰劣 . 此时比较 AUC 。

 需要注意的是ROC 曲线在处理类别不平衡问题时相对于 P-R 曲线有一定的局限性。 由于 ROC 曲线只关注真正例率和假正例率,并不直接考虑类别分布。而 P-R 曲线则更能反映出在正例样本中的预测准确性和覆盖能力。

二、实现P-R曲线

1.生成数据集
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt

# 生成样本数据集
X, y = make_classification(n_samples=1000, n_features=20, n_informative=10, n_redundant=5, random_state=42)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

使用了 make_classification 函数来生成一个二分类的合成数据集。参数 n_samples 表示生成的样本数量,n_features 表示特征的数量,n_informative 表示有信息的特征数量,n_redundant 表示冗余特征的数量,random_state 是一个随机种子,用于确保可重复性。

参数 test_size 表示测试集占总样本的比例,这里设置为 0.2 表示将 20% 的数据作为测试集,而剩下的 80% 作为训练集。random_state 是一个随机种子,用于确保可重复性。函数会返回训练集和测试集的特征矩阵及对应的标签。

部分数据集

2.训练模型
# 训练KNN模型
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = knn.predict(X_test)

使用K-最近邻(KNN)分类器,并在测试集上进行了预测。

3.计算混淆矩阵
# 计算混淆矩阵
def calculate_confusion_matrix(y_true, y_pred):
    tp = np.sum((y_true == 1) & (y_pred == 1))
    fp = np.sum((y_true == 0) & (y_pred == 1))
    fn = np.sum((y_true == 1) & (y_pred == 0))
    tn = np.sum((y_true == 0) & (y_pred == 0))
    return tp, fp, fn, tn

tp, fp, fn, tn = calculate_confusion_matrix(y_test, y_pred)

通过混淆矩阵手动计算精确率(Precision)和召回率(Recall)

def calculate_precision_and_recall(tp, fp, fn):
    precision = tp / (tp + fp)
    recall = tp / (tp + fn)
    return precision, recall

precision, recall = calculate_precision_and_recall(tp, fp, fn)
4.绘制P-R曲线
# 绘制P-R曲线
precision_curve, recall_curve, _ = precision_recall_curve(y_test, y_pred)
plt.plot(recall_curve, precision_curve, marker='.', label='KNN')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('P-R Curve')
plt.legend()
plt.show()

print("混淆矩阵:")
print("True Positive (TP):", tp)
print("False Positive (FP):", fp)
print("False Negative (FN):", fn)
print("True Negative (TN):", tn)
print("\n精确率(Precision):", precision)
print("召回率(Recall):", recall)

运行结果:可以看出本次实验的精确率和召回率较高。

三、实现ROC曲线、

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, auc

# 生成样本数据
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5,
                            n_redundant=0, n_classes=2, weights=[0.3, 0.7], random_state=42)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 训练模型
clf = LogisticRegression()
clf.fit(X_train, y_train)

# 得到预测概率
y_score = clf.predict_proba(X_test)[:, 1]

# 计算fpr和tpr
fpr, tpr, _ = roc_curve(y_test, y_score)

# 计算AUC
roc_auc = auc(fpr, tpr)

# 绘制ROC曲线
plt.figure(figsize=(8,6))
lw = 2
plt.plot(fpr, tpr, color='darkorange',
         lw=lw, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()
1. 生成数据集

和绘制P-R曲线一样同样使用make_classification生成数据集,并划分训练集和测试集。

2.训练模型

创建一个LogisticRegression分类器,使用训练数据X_trainy_train来拟合(训练)模型。

3.计算出FPR、TPR和AUC

roc_curve函数计算接收者操作特征(ROC)曲线的假FPR和TPR。另外使用auc函数计算ROC曲线下的面积,得到AUC值。

4.绘制ROC曲线

运行结果:AUC的值为0.8368290081763241,可以看出此次运行的结果较好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值