P

您所在的位置:网站首页 matlab画函数曲线代码 P

P

2023-07-23 08:36| 来源: 网络整理| 查看: 265

简介

P-R曲线,是指以查准率(亦称准确率)为纵轴、查全率(亦称召回率)为横轴画出的曲线,反映了查准率随查全率的变化趋势,在机器学习中常用于二分类模型的评价及选择。

相关概念 混淆矩阵 实际为负实际为正预测为负TNFP预测为正FNTP 查准率(亦称准确率)

p r e c i s i o n = T P T P + F P precision = \frac{TP}{TP+FP} precision=TP+FPTP​

查全率(亦称召回率)

r e c a l l = T P T P + F N recall = \frac{TP}{TP+FN} recall=TP+FNTP​

绘制原理

在训练集上训练出二分类模型后我们将测试集中的数据输入模型,这时我们可以计算得到这些数据属于某个类别的概率,将这些预测概率从小到大排列,然后将分类阈值依次设为[0,1]区间中不同的概率值并计算这时的准确率和召回率,最后将这些准确率和召回率在二维坐标系中连起来就得到了ROC曲线

示例

为了说明计算细节,这里使用一个虚构的例子:假设数据集有两个特征,分别是length和width,取值都是整数,标签有两类,分别是0和1,并且类别1是正类(positive);假设我们在这个数据集上训练得到的树模型如下: 在这里插入图片描述

并且我们假设训练数据在叶节点的分布如下:

叶节点编号类别为0的样本个数类别为1的样本点个数该叶节点属于类别0的概率该叶节点属于类别1的概率该叶节点预测类别19001000.90.1026002000.750.2503509500.050.951

其中

某 叶 节 点 属 于 类 别 1 的 概 率 = 落 在 该 节 点 的 真 实 类 别 为 1 的 样 本 数 落 在 该 节 点 的 总 样 本 数 某叶节点属于类别1的概率=\frac{落在该节点的真实类别为1的样本数}{落在该节点的总样本数} 某叶节点属于类别1的概率=落在该节点的总样本数落在该节点的真实类别为1的样本数​

并且叶节点的预测类别为它的所属概率更大的那个类别

假设测试集为:

特征测试数据1测试数据2测试数据3测试数据4测试数据5测试数据6测试数据7测试数据8测试数据9测试数据10length21561711591012width4861913218329实际所属类别0111101000

按照我们决策树的划分,可以得到测试集属于正类(类别1)的概率分别为(例如测试数据1最终被分到了叶节点2,那么它属于类别1的概率就是叶节点2属于类别1的概率):

测试数据1测试数据2测试数据3测试数据4测试数据5测试数据6测试数据7测试数据8测试数据9测试数据100.250.10.250.950.950.250.950.10.10.1

将他们按概率大小排列得到:

测试数据 10测试数据9测试数据8测试数据2测试数据1测试数据3测试数据6测试数据4测试数据5测试数据7属于正类的概率0.10.10.10.10.250.250.250.950.950.95实际所属类别0001010111

现在我们将分类阈值分别设为0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,并将概率大于阈值的测试样本预测为类别1,可以得到不同分类阈值下的准确率和召回率:

分类阈值TPFNFP准确率召回率05050.510.14120.670.80.24120.670.80.332010.60.432010.60.532010.60.632010.60.732010.60.832010.60.932010.6

将(召回率,准确率)在坐标中画出来就得到了P-R曲线: 在这里插入图片描述 可见我们虚构的模型表现不太理想

代码实现 自己写代码

我们以sklearn.datasets中的乳腺癌数据集为例,这是一个二分类数据集,我们将在这个数据集上学习一个分类树模型并绘制该模型的P-R曲线:

from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.datasets import load_breast_cancer from sklearn.metrics import precision_score from sklearn.metrics import recall_score import matplotlib.pyplot as plt import numpy as np data = load_breast_cancer() X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=66) dtc = DecisionTreeClassifier(min_samples_leaf=10) dtc.fit(X_train, y_train) # predict_proba返回的是每个样本分别属于两个类别的概率,而我们只关心它属于正类的概率 probs = dtc.predict_proba(X_test)[:, 1] # 就像在上面那个虚构的例子中展示的那样, # 决策树在做预测时对每个样本会算出它属于两个类别的概率, # 最终预测结果就是预测概率大于0.5的那个类 y_predict = dtc.predict(X_test) # 人为地生成一系列不同的阈值 thresholds = np.arange(np.min(probs), np.max(probs), 0.1) precisions = [] recalls = [] for threshold in thresholds: y_predict = np.array(probs >= threshold, dtype='int') pre = precision_score(y_test, y_predict) recall = recall_score(y_test, y_predict) precisions.append(pre) recalls.append(recall) plt.plot(recalls, precisions) plt.xlabel('Recall') plt.ylabel('Precision') plt.show()

输出: 在这里插入图片描述

调用sklearnAPI

sklearn已经封装了绘制P-R曲线的函数,使用时只要导入sklearn.metrics.precision_recall_curve就可以了。该函数参数如下:

y_true:真实的类标签,默认在 {-1, 1} 或 {0, 1} 中取值pos_label:正类的标签,默认为1probas_pred:样本的预测概率sample_weight:样本权重

函数返回三个列表:

precision:不同概率阈值对应的预测准确率recall:不同的概率阈值对应的预测召回率thresholds:绘制P-R曲线时取的不同的概率阈值

我们还是以sklearn.datasets中的乳腺癌数据集为例,在这个数据集上建立一个逻辑回归模型,并绘制该模型的P-R曲线:

from sklearn.metrics import precision_recall_curve from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.datasets import load_breast_cancer import matplotlib.pyplot as plt data = load_breast_cancer() X = data.data y = data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=66) model = LogisticRegression(solver='liblinear') model.fit(X_train, y_train) scores = model.decision_function(X_test) precisions, recalls, thresholds = precision_recall_curve(y_test, scores) plt.plot(precisions, recalls) plt.xlabel('Recall') plt.ylabel('Precision') plt.show()

输出: 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3