👨💻 作者简介:程序员半夏 , 一名全栈程序员,擅长使用各种编程语言和框架,如JavaScript、React、Node.js、Java、Python、Django、MySQL等.专注于大前端与后端的硬核干货分享,同时是一个随缘更新的UP主. 你可以在各个平台找到我!
🏆 本文收录于专栏: 零基础学机器学习
🔥 专栏介绍: 本专栏将帮助您了解机器学习、其工作原理以及如何使用它。本教程包含以下内容:监督和无监督学习、线性回归、随机森林算法、朴素贝叶斯分类器、K-means聚类算法等等等基础学习基础知识,以及各种实战案例。
文章目录
什么是混淆矩阵通过混淆矩阵计算其他指标准确率-Accuracy精确率-Precision召回-RecallF1-Score错误率 - Error Rate特异度 -Specificity假正率 - False Positive Rate假负率 - False Negative Rate真正率 - True Positive Rate预测正例率 - Positive Predictive Value预测负例率 - Negative Predictive Value假发现率 - False Discovery Rate 用Python预测心脏病数据集导入模型加载数据缩放数据划分数据集使用逻辑回归模型准确性混淆矩阵混淆矩阵的各种指标 拓展查全率和召回率查准率和精确率在机器学习中,分类用于将数据划分为不同的类别。但在清理、预处理数据并训练我们的模型之后,我们如何知道分类模型的性能是否良好呢?这就是混淆矩阵的作用。
什么是混淆矩阵
分类模型具有多个类别输出。大多数误差度量将计算模型的总误差,但我们无法找到模型中的单个错误实例。模型可能将某些类别误分类得比其他类别更多,但我们无法通过标准准确性度量来看到这一点。
此外,假设给定数据中存在显著的类别不平衡,即某个类别的数据实例比其他类别多,模型可能会对所有情况预测出占多数的类别,并具有较高的准确性得分;而实际上它并没有预测到少数类别。这就是混淆矩阵的用途。
混淆矩阵(confusion matrix)是在机器学习和统计学中广泛使用的一种表格,用于评估分类模型的性能。它以表格布局呈现分类问题的预测和结果的不同结果。它是将真实类别和预测类别进行对比的一种方式,通常用于二元分类问题,其中真实类别和预测类别都只有两种可能的取值:正类和负类。
混淆矩阵的四个元素分别是:
真正例(TP):实际为正例且被正确预测为正例的次数。即预测为正例,实际为正例。假正例(FP):模型错误地将负例预测为正例的次数。即预测为正例,实际为负例。真负例(TN):实际为负例且被正确预测为负例的次数。即预测为负例,实际为负例。假负例(FN):模型错误地将正例预测为负例的次数。即预测为负例,实际为正例。
混淆矩阵可以用以下形式表示:
通过混淆矩阵,可以计算出多种分类模型的性能指标,例如准确率、精确率、召回率、F1值等。其中,准确率是指模型正确分类的样本占总样本数的比例;精确率是指模型预测为正类的样本中,实际为正类的样本占比;召回率是指实际为正类的样本中,被模型预测为正类的样本占比;F1值是精确率和召回率的调和平均数,用于综合评估模型的性能。
总之,混淆矩阵是评估分类模型性能的重要工具,通过对混淆矩阵的分析,可以了解模型在不同情况下的表现,进而优化模型,提高分类准确率。
通过混淆矩阵计算其他指标
考虑一个基于英语或西班牙语的分类器所生成的混淆矩阵。
从上面的图表中,我们可以看到:
真正例(TP)= 86
真负例(TN)= 79
假正例(FP)= 12
假负例(FN)= 10
从矩阵上看,我们的模型表现并不十分清晰。为了找出模型的准确性,我们使用以下指标:
准确率-Accuracy
准确率(Accuracy):用于找到分类正确的值的比例。它告诉我们分类器的正确率。准确率是所有真实值之和除以总数。
A c c u r a c y = ( T P + T N ) / ( T P + F P + T N + F N ) Accuracy = (TP + TN) / (TP + FP + TN + FN) Accuracy=(TP+TN)/(TP+FP+TN+FN)
在这种情况下:
Accuracy = (86 + 79) / (86 + 79 + 12 + 10) = 0.8823 = 88.23%
精确率-Precision
精确率(Precision):用于计算模型正确分类正值的能力。它是真正值除以预测正值的总数。
P r e c i s i o n = T P / ( T P + F P ) Precision = TP / (TP + FP) Precision=TP/(TP+FP)
在这种情况下:
Precision = 86 / (86 + 12) = 0.8775 = 87.75%
召回-Recall
召回率(Recall):用于计算模型预测正值的能力。即“模型正确预测正值的频率是多少?”。它是真正值除以实际正值的总数。
R e c a l l = T P / ( T P + F N ) Recall = TP / (TP + FN) Recall=TP/(TP+FN)
在这种情况下:
Recall = 86 / (86 + 10) = 0.8983 = 89.83%
F1-Score
F1-Score:它是精确率和召回率的调和平均数。当需要同时考虑精确率和召回率时,它很有用。
F 1 值( F 1 − s c o r e ) = 2 ∗ P r e c i s i o n ∗ R e c a l l / ( P r e c i s i o n + R e c a l l ) F1值(F1-score)= 2 * Precision * Recall / (Precision + Recall) F1值(F1−score)=2∗Precision∗Recall/(Precision+Recall)
在这种情况下:
F1-Score = (2* 0.8775 * 0.8983) / (0.8775 + 0.8983) = 0.8877 = 88.77%
错误率 - Error Rate
错误率(Error Rate):分类器错误预测的样本数占总样本数的比例。
E r r o r R a t e = ( F P + F N ) / ( T P + F P + T N + F N ) Error Rate = (FP + FN) / (TP + FP + TN + FN) ErrorRate=(FP+FN)/(TP+FP+TN+FN)
在这种情况下:
Error Rate = (12 + 10) / (86 + 12 + 79 + 10) = 0.1176
特异度 -Specificity
特异度(Specificity):真正为负例的样本中,分类器正确预测为负例的样本数占真正为负例的样本数的比例。
S p e c i f i c i t y = T N / ( T N + F P ) Specificity = TN / (TN + FP) Specificity=TN/(TN+FP)
在这种情况下:
Specificity = 79 / (79 + 12) = 0.8681
假正率 - False Positive Rate
假正率(False Positive Rate):真正为负例的样本中,分类器错误预测为正例的样本数占真正为负例的样本数的比例。
F a l s e P o s i t i v e R a t e = F P / ( T N + F P ) False Positive Rate = FP / (TN + FP) FalsePositiveRate=FP/(TN+FP)
在这种情况下:
False Positive Rate= 12 / (79 + 12) = 0.1318
假负率 - False Negative Rate
假负率(False Negative Rate):真正为正例的样本中,分类器错误预测为负例的样本数占真正为正例的样本数的比例。
F a l s e N e g a t i v e R a t e = F N / ( T P + F N ) False Negative Rate = FN / (TP + FN) FalseNegativeRate=FN/(TP+FN)
在这种情况下:
False Negative Rate= 10 / (86 + 10) = 0.1041
真正率 - True Positive Rate
真正率(True Positive Rate):同召回率。
T r u e P o s i t i v e R a t e = T P / ( T P + F N ) True Positive Rate = TP / (TP + FN) TruePositiveRate=TP/(TP+FN)
在这种情况下:
True Positive Rate= 86 / (86 + 10) = 0.8958
预测正例率 - Positive Predictive Value
预测正例率(Positive Predictive Value):同精确率。
P o s i t i v e P r e d i c t i v e V a l u e = T P / ( T P + F P ) Positive Predictive Value= TP / (TP + FP) PositivePredictiveValue=TP/(TP+FP)
在这种情况下:
Positive Predictive Value= 86 / (86 + 12) = 0.8775
预测负例率 - Negative Predictive Value
预测负例率(Negative Predictive Value):真正为负例的样本中,分类器正确预测为负例的样本数占预测为负例的样本数的比例。
N e g a t i v e P r e d i c t i v e V a l u e = T N / ( T N + F N ) Negative Predictive Value= TN / (TN + FN) NegativePredictiveValue=TN/(TN+FN)
在这种情况下:
Negative Predictive Value= 79 / (79 + 10) = 0.8876
假发现率 - False Discovery Rate
假发现率(False Discovery Rate):同1-精确率。
F a l s e D i s c o v e r y R a t e = F P / ( F P + T P ) False Discovery Rate = FP / (FP + TP) FalseDiscoveryRate=FP/(FP+TP)
在这种情况下:
False Discovery Rate= 12 / (12 + 86) = 0.1224
用Python预测心脏病
我们将使用心脏病发作数据集构建一个逻辑回归模型,以预测患者是否有心脏病发作的风险。
数据集
下图展示了我们将在此演示中使用的数据集。
age:患者的年龄sex:患者的性别(1 = 男性,0 = 女性)cp:胸痛类型(值为0、1、2、3,分别表示不同类型的胸痛)trestbps:患者在休息状态下的收缩压(毫米汞柱)chol:患者的胆固醇水平(毫克/分升)fbs:空腹血糖(1 = 空腹血糖 > 120 mg/dl,0 = 空腹血糖 <= 120 mg/dl)restecg:静息心电图结果(值为0、1、2,分别表示不同类型的心电图结果)thalach:患者达到的最大心率exang:运动诱发心绞痛(1 = 是,0 = 否)oldpeak:运动相对于休息时引起的ST段下降(心电图测量)slope:运动高峰ST段的斜率(值为0、1、2,分别表示不同类型的斜率)ca:通过荧光透视检查发现的主要血管数量(值为0、1、2、3、4)thal:地中海贫血症(值为0、1、2、3,分别表示不同类型的地中海贫血症)target:心脏病发作的风险(1 = 是,0 = 否)
导入模型
让我们导入必要的库来创建我们的模型。
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_scorefrom sklearn.metrics import confusion_matrix from sklearn.metrics import classification_report
以下是对所提到的 Python 包和模块的解释:
Pandas 是一个用于数据处理和分析的 Python 库。它提供了数据结构和功能,以便轻松处理结构化数据。pd
是 Pandas 的常用别名。
train_test_split
函数来自 Scikit-learn(一个用于机器学习的 Python 库)的model_selection
模块。它用于将数据集划分为训练集和测试集,以便在训练模型时进行交叉验证。
StandardScaler
类来自 Scikit-learn 的preprocessing
模块。它用于对数据进行标准化处理,即将数据转换为均值为 0,标准差为 1 的分布。
LogisticRegression
类来自 Scikit-learn 的linear_model
模块。它实现了逻辑回归算法,用于解决二分类问题。
accuracy_score
函数来自 Scikit-learn 的metrics
模块。它用于计算分类模型的准确率,即正确预测的样本数占总样本数的比例。
confusion_matrix
函数也来自 Scikit-learn 的metrics
模块。它用于计算分类模型的混淆矩阵,以评估模型的性能。混淆矩阵显示了真实类别与预测类别之间的关系。
classification_report
函数同样来自 Scikit-learn 的metrics
模块。它生成一个包含主要分类指标(如精确度、召回率、F1 分数等)的报告,以评估模型的性能。
这些包和模块通常用于构建、训练和评估机器学习模型,特别是在分类任务中。
加载数据
# 导入 Pandas 库import pandas as pd# 使用 Pandas 库的 read_csv 函数读取位于指定路径的 CSV 文件# 并将其内容存储在名为 data 的 DataFrame 对象中data = pd.read_csv("C:\\Users\\Administrator\\Downloads\\heart.csv")# 从 data DataFrame 中提取名为 "target" 的列# 并将其存储在名为 y 的 Series 对象中# "target" 列通常表示数据集中的目标变量,即我们希望预测的变量y = data["target"]# 使用 DataFrame 的 drop 方法删除 "target" 列# 通过设置 axis=1 指定删除列而非行# 并将结果存储在名为 x 的新 DataFrame 对象中# 这样,x 包含了数据集中的所有特征变量,不包括目标变量x = data.drop('target', axis=1)# 使用 DataFrame 的 head 方法显示 x 的前五行# 这是一种快速查看数据集前几行内容的方法,以便了解数据的结构和特征x.head()# 使用 Series 的 head 方法显示 y 的前五行# 这是一种快速查看目标变量前几行内容的方法y.head()
缩放数据
我们可以看到,我们的数据包含大量的值,有些是1位,有些是3位。为了简化计算,我们可以使用Standard Scaler
缩放数据并将其减少到一小部分值。
# 创建 StandardScaler 对象scaler = StandardScaler()# 使用 StandardScaler 对象的 fit_transform 方法对 x 进行特征缩放# fit_transform 方法会计算 x 中每个特征的均值和标准差,并使用这些值对特征进行标准化# 标准化后,每个特征的均值为 0,标准差为 1# 将缩放后的数据转换为 DataFrame 对象x = pd.DataFrame(scaler.fit_transform(x))# 打印缩放后的 xprint(x)
划分数据集
现在,让我们将数据集分为两部分:一部分用于训练模型,另一部分用于测试模型。
# 使用 train_test_split 函数将特征变量 x 和目标变量 y 划分为训练集和测试集# test_size 参数设置为 0.2,表示测试集占整个数据集的 20%# random_state 参数设置为 42,用于确保每次运行代码时,数据集的划分方式相同X_train, X_test, Y_train, Y_test = train_test_split(x, y, test_size=0.2, random_state=42)
random_state
是一个可选参数,用于设置随机数生成器的种子。它的值可以是一个整数、一个RandomState
实例或者None
。当设置为整数时,它将作为随机数生成器的种子,确保每次运行代码时,随机过程的结果相同。这有助于复现结果和调试。
例如,在将数据集划分为训练集和测试集时,如果设置random_state
为一个固定的整数(如 42),那么每次运行代码时,数据集的划分方式都相同。这使得结果具有可复现性,便于比较不同模型或参数设置的性能。选择 42 作为random_state
的值是一个约定俗成的做法,因为 42 被认为是“生命、宇宙以及万物的终极答案”(来自英国科幻小说《银河系漫游指南》)。实际上,你可以选择任何整数作为random_state
的值,只要在整个项目中保持一致即可。
如果将random_state
设置为None
(默认值),则每次运行代码时,随机数生成器将使用当前系统时间作为种子,导致随机过程的结果在每次运行时都不同。这有助于增加结果的随机性,但可能导致结果难以复现。
使用逻辑回归模型
为此,我们使用从sklearn导入的train_test_split。使用逻辑回归模型,我们将对训练数据执行分类,并预测测试数据以检查准确性。
# 创建逻辑回归模型实例model = LogisticRegression()# 使用训练数据集 (X_train, Y_train) 拟合模型model.fit(X_train, Y_train)# 使用测试数据集 (X_test) 进行预测pred = model.predict(X_test)# 输出预测结果pred
输出的预测结果是一个整数数组,表示逻辑回归模型对测试数据集的预测结果。数组中的每个元素对应一个测试样本的预测类别(0 或 1)。例如,结果数组的第一个元素为 0,表示第一个测试样本被预测为类别 0;第二个元素为 1,表示第二个测试样本被预测为类别 1。
准确性
要找到混淆矩阵的准确性和所有其他指标,我们可以从同一个库中导入accuracy_score和classification_report。
score = accuracy_score(Y_test,prod)score
上面代码用于计算逻辑回归模型在测试数据集上的准确率:使用accuracy_score
函数计算模型预测结果(prod
)与实际标签(Y_test
)之间的准确率。准确率是预测正确的样本数占总样本数的比例。
混淆矩阵
confusion_matrix(Y_test,prod)
上面的代码用于计算逻辑回归模型在测试数据集上的混淆矩阵:使用confusion_matrix
函数计算模型预测结果(prod
)与实际标签(Y_test
)之间的混淆矩阵。混淆矩阵是一个二维数组,用于描述模型预测结果与实际标签之间的关系。
代码输出的结果解释:
混淆矩阵的结果是一个 2x2 的整数数组,表示模型在测试数据集上的预测情况。矩阵中的元素如下:
第一行第一列(25):真实类别为 0,预测类别也为 0 的样本数(真阴性,True Negative,TN)。第一行第二列(4):真实类别为 0,预测类别为 1 的样本数(假阳性,False Positive,FP)。第二行第一列(5):真实类别为 1,预测类别为 0 的样本数(假阴性,False Negative,FN)。第二行第二列(27):真实类别为 1,预测类别也为 1 的样本数(真阳性,True Positive,TP)。
混淆矩阵的各种指标
上面的代码用于计算逻辑回归模型在测试数据集上的分类报告:使用classification_report
函数计算模型预测结果(prod
)与实际标签(Y_test
)之间的分类报告。分类报告包括精确率(precision)、召回率(recall)、F1 分数(f1-score)和支持度(support)等性能指标。
分类报告展示了模型在各个类别上的性能指标。每一行对应一个类别,每一列对应一个性能指标。
精确率(precision):预测为某类别且实际上也是该类别的样本数占预测为该类别的样本数的比例。值越高,表示模型在预测为该类别时的准确性越高。召回率(recall):预测为某类别且实际上也是该类别的样本数占实际上为该类别的样本数的比例。值越高,表示模型在找出该类别的样本时的能力越强。F1 分数(f1-score):精确率和召回率的调和平均值。值越高,表示模型在精确率和召回率之间的平衡性越好。支持度(support):实际上为该类别的样本数。
上面结果的具体数值如下:
类别 0:
精确率(precision):0.83召回率(recall):0.86F1 分数(f1-score):0.85支持度(support):29
类别 1:
精确率(precision):0.87召回率(recall):0.84F1 分数(f1-score):0.86支持度(support):32
整体指标:
准确率(accuracy):0.85宏平均(macro avg): 精确率(precision):0.85召回率(recall):0.85F1 分数(f1-score):0.85支持度(support):61 加权平均(weighted avg): 精确率(precision):0.85召回率(recall):0.85F1 分数(f1-score):0.85支持度(support):61
拓展
查全率和召回率
查全率和召回率实际上是同一个概念,它们都表示预测为某类别且实际上也是该类别的样本数占实际上为该类别的样本数的比例。在不同的领域和文献中,这个概念可能被称为查全率(sensitivity)、召回率(recall)或者真阳性率(true positive rate, TPR)。
定义:预测为某类别且实际上也是该类别的样本数占实际上为该类别的样本数的比例。解释:查全率衡量了模型在找出某个类别的样本时的能力。值越高,表示模型在找出该类别的样本时的能力越强。
总之,查全率和召回率是同一个指标,只是在不同领域和文献中可能有不同的称呼。
查准率和精确率
查准率和精确率实际上是同一个概念,它们都表示预测为某类别且实际上也是该类别的样本数占预测为该类别的样本数的比例。在不同的领域和文献中,这个概念可能被称为查准率(precision)或者精确率(accuracy)。
定义:预测为某类别且实际上也是该类别的样本数占预测为该类别的样本数的比例。解释:查准率衡量了模型在预测为某个类别时的准确性。值越高,表示模型在预测为该类别时的准确性越高。
总之,查准率和精确率是同一个指标,只是在不同领域和文献中可能有不同的称呼。