您可以使用哪些指标来评估您的机器学习算法?
在本帖中,您将了解如何使用一些标准的评估指标在 R 中评估您的机器学习算法。
使用我的新书 《R 语言机器学习精通》 来启动您的项目,其中包含分步教程和所有示例的R 源代码文件。
让我们开始吧。

R 中的机器学习评估指标
照片由 Roland Tanglao 拍摄,部分权利保留。
R 语言中的模型评估指标
在 R 语言中,您可以使用许多不同的指标来评估您的机器学习算法。
当您使用 caret 来评估模型时,分类问题的默认指标是准确率 (accuracy),回归问题的默认指标是RMSE。但 caret 支持一系列其他流行的评估指标。
在下一节中,您将逐步了解 caret 提供的各项评估指标。每个示例都提供了一个完整的案例研究,您可以将其复制粘贴到您的项目中并改编以适应您的问题。
请注意,本帖假定您已经知道如何解释这些其他指标。如果它们对您来说是新的,请不要担心,我提供了一些进一步阅读的链接,您可以在其中了解更多信息。
需要更多关于R机器学习的帮助吗?
参加我为期14天的免费电子邮件课程,了解如何在您的项目中使用R(附带示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
评估机器学习算法的指标
在本节中,您将了解如何使用许多不同的常用评估指标来评估机器学习算法。
具体来说,本节将向您展示如何在 R 中的 caret 包中使用以下评估指标:
- 准确率和 Kappa
- RMSE 和 R^2
- ROC(AUC、灵敏度和特异度)
- LogLoss
准确率和 Kappa
这些是 caret 中用于评估二分类和多分类数据集上算法的默认指标。
准确率 (Accuracy) 是所有实例中正确分类的实例所占的百分比。它在二分类问题上比多分类问题更有用,因为在多分类问题上,准确率在不同类别的分布情况可能不太清楚(例如,您需要通过混淆矩阵来深入了解)。在此处了解更多关于准确率的信息。
Kappa 或 Cohen's Kappa 类似于分类准确率,不同之处在于它已根据数据集上的随机几率基线进行了归一化。在使用类别不平衡的问题时,它是一个更有用的度量(例如,类别 0 和 1 的比例为 70-30,通过预测所有实例都属于类别 0,您可以达到 70% 的准确率)。在此处了解更多关于 Kappa 的信息。
下面的示例使用了 Pima Indians 糖尿病数据集。该数据集的类别分布为阴性(无)和阳性(有)结果的比例为 65% 对 35%。
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 准备重采样方法 control <- trainControl(method="cv", number=5) set.seed(7) fit <- train(diabetes~., data=PimaIndiansDiabetes, method="glm", metric="Accuracy", trControl=control) # 显示结果 print(fit) |
运行此示例,我们可以看到每个机器学习算法的准确率和 Kappa 表。这包括平均值(左侧)和标准差(标记为 SD),这些值是从交叉验证折叠和试验的总体中获取的。
您可以看到模型的准确率约为 76%,比基线准确率 65% 高出 11 个百分点,这实际上并不算令人印象深刻。而 Kappa 显示约为 46%,这更有趣。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
广义线性模型 768 个样本 8 个预测变量 2 个类别:“neg”、“pos” 无预处理 重采样:交叉验证(5 折) 样本大小汇总:614、614、615、615、614 重采样结果 Accuracy Kappa Accuracy SD Kappa SD 0.7695442 0.4656824 0.02692468 0.0616666 |
RMSE 和 R^2
这些是 caret 中用于评估回归数据集上算法的默认指标。
RMSE 或均方根误差是预测值与观测值之间的平均偏差。它有助于大致了解算法的表现如何(好或不好),单位与输出变量相同。在此处了解更多关于 RMSE 的信息。
R^2(读作 R 平方,也称为决定系数)为预测值与观测值提供了一个“拟合优度”度量。这是一个介于 0 和 1 之间的值,分别表示无拟合和完美拟合。在此处了解更多关于 R^2 的信息。
此示例使用了 longley 经济数据集。输出变量是“就业人数”。不清楚这是否是实际计数(例如,以百万计)或百分比。
1 2 3 4 5 6 7 8 9 10 |
# 加载库 library(caret) # 加载数据 data(longley) # 准备重采样方法 control <- trainControl(method="cv", number=5) set.seed(7) fit <- train(Employed~., data=longley, method="lm", metric="RMSE", trControl=control) # 显示结果 print(fit) |
运行此示例,我们可以看到每个机器学习算法的 RMSE 和 R Squared 表。同样,您可以看到两个指标的平均值和标准差。
您可以看到 RMSE 为 0.38,单位是“就业人数”(无论该单位是什么)。而 R Squared 值显示数据拟合良好,值非常接近 1(0.988)。
1 2 3 4 5 6 7 8 9 10 11 12 |
线性回归 16 个样本 6 个预测变量 无预处理 重采样:交叉验证(5 折) 样本大小汇总:12、12、14、13、13 重采样结果 RMSE Rsquared RMSE SD Rsquared SD 0.3868618 0.9883114 0.1025042 0.01581824 |
ROC 曲线下面积
ROC 指标仅适用于二分类问题(例如,两个类别)。
要计算 ROC 信息,您必须将 trainControl 中的 summaryFunction 更改为 twoClassSummary。这将计算 ROC 曲线下面积 (AUROC),也称为曲线下面积 (AUC)、灵敏度和特异度。
ROC 实际上是 ROC 曲线下面积或 AUC。AUC 代表模型区分正负类别的能力。1.0 的面积代表一个做出所有预测都完美的模型。0.5 的面积代表一个与随机一样好的模型。在此处了解更多关于 ROC 的信息。
ROC 可以细分为灵敏度和特异度。二分类问题实际上是灵敏度和特异度之间的权衡。
灵敏度 (Sensitivity) 是真阳性率,也称为召回率。它是正类(第一个类别)中实际被正确预测的实例数量。
特异度 (Specificity) 也称为真阴性率。它是负类(第二个类别)中实际被正确预测的实例数量。在此处了解更多关于灵敏度和特异度的信息。
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 准备重采样方法 control <- trainControl(method="cv", number=5, classProbs=TRUE, summaryFunction=twoClassSummary) set.seed(7) fit <- train(diabetes~., data=PimaIndiansDiabetes, method="glm", metric="ROC", trControl=control) # 显示结果 print(fit) |
在这里,您可以看到 0.833 的“好”但非“优秀”的 AUC 分数。第一个类别被视为正类别,在本例中为“neg”(无糖尿病发作)。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
广义线性模型 768 个样本 8 个预测变量 2 个类别:“neg”、“pos” 无预处理 重采样:交叉验证(5 折) 样本大小汇总:614、614、615、615、614 重采样结果 ROC Sens Spec ROC SD Sens SD Spec SD 0.8336003 0.882 0.5600978 0.02111279 0.03563706 0.0560184 |
对数损失
对数损失或 LogLoss 用于评估二分类,但对于多分类算法更常见。具体来说,它评估算法估计的概率。在此处了解更多关于对数损失的信息。
在本例中,我们看到了为鸢尾花多分类问题计算的 logloss。
1 2 3 4 5 6 7 8 9 10 |
# 加载库 library(caret) # 加载数据集 data(iris) # 准备重采样方法 control <- trainControl(method="cv", number=5, classProbs=TRUE, summaryFunction=mnLogLoss) set.seed(7) fit <- train(Species~., data=iris, method="rpart", metric="logLoss", trControl=control) # 显示结果 print(fit) |
Logloss 被最小化,我们可以看到最佳 CART 模型具有 cp=0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
CART 150 个样本 4 个预测变量 3 个类别:“setosa”、“versicolor”、“virginica” 无预处理 重采样:交叉验证(5 折) 样本大小汇总:120、120、120、120、120 跨调优参数的重采样结果 cp logLoss logLoss SD 0.00 0.4105613 0.6491893 0.44 0.6840517 0.4963032 0.50 1.0986123 0.0000000 logLoss 用于选择最佳模型,采用最小化该值。 用于模型的最终值为 cp = 0。 |
总结
在本帖中,您发现了一些可以使用 R 中的 caret 来评估机器学习算法性能的不同指标。具体来说:
- 准确率和 Kappa
- RMSE 和 R^2
- ROC(AUC、灵敏度和特异度)
- LogLoss
您可以使用本帖中的配方来评估您当前或下一个机器学习项目中的机器学习算法。
下一步
按照本帖中的示例进行操作。
- 打开您的 R 交互式环境。
- 键入或复制粘贴上面的示例代码。
- 花时间理解正在发生的事情,使用 R 帮助来阅读函数。
您有任何问题吗?请留言,我会尽力解答。
对于不平衡的二分类问题,使用“Accuracy”作为训练指标,并使用 ROCR 包查找 AUC 分数是否合乎逻辑?还是我必须使用“ROC”作为计算 AUC 分数的指标?
感谢您的好文章。
RMSE 可以用于比较不同算法(多项式回归、SVR、决策树或随机森林)创建的模型之间的准确性吗?
谢谢你……
嗨 John,
不是准确性,而是误差。是的,它可用于比较不同算法在回归问题上的误差,而不是在分类问题上。
嗨 Jason,感谢您的文章。您知道 rpart 用来查找最佳 CP 的相对误差是多少吗?
我不确定,可以查看 ?rpart 文档。
狼群算法中狼如何选择特征?
抱歉,我不知道该算法。
感谢您的文章和您的网站。在 R 3.5 中运行对数损失示例,我得到了一个不同且次优的结果,声称 cp = 0.44 给出最小 logLoss 为 0.390。当 number 增加到 10 而不是 5 时,我得到了正确的结果。此外,我没有得到 SD 列。有什么窍门可以得到它们吗?
也许 API 自我编写帖子以来已经改变了?
假设我有一个 80% / 20% 的训练和测试数据分割。
是否会在测试数据上计算 RMSE 和 RSquared?还是在测试上计算 RMSE,在训练数据上计算 RSquared?
谢谢你
在测试数据上。
原因是您正在估计模型在对训练期间未见过的数据(新数据)进行预测时的技能。这正是您在实践中打算使用模型的方式。
嗨 Jason!非常感谢您的帖子!
在回归问题中,我想拟合一个关注低值而非高值的模型。
在讨论模型评估指标的一些论文中,例如“DAWSON et al (2007)。HydroTest: A web-based toolbox of evaluation metrics for the standardised assessment of hydrological forecasts”,他们解释说,“RMSE”更适合高值(因为比较值是平方的),而“Rsquared”用于寻找更好的值形状,并且值也是平方的。
那么,如果我的目的是更好地模拟低值,在应用 caret-train-metrics 时,您建议在“metrics”中设置什么?因为担心这个问题,RMSE 和 Rsquared 似乎不适合应用。
再次感谢!
也许可以尝试几种指标,看看哪种符合您的直觉或要求?
尊敬的 Brownlee 博士
非常感谢您的教程。
我遵循了“R 语言第一个机器学习项目分步指南”,然后看了这篇文章。
我有一些问题
- 这些指标(特别是 RMSE 和 R^2、ROC 和 log loss)是否遵循训练模型然后在验证数据集上进行测试的逻辑?或者这只适用于 accuracy 和 K?
- log loss 是做什么的?log loss 在哪个意义上估计模型的概率?
- 如何获取 ROC 的截止分数?
非常感谢。
大多数都可以用于拟合和评估模型。
您可以在此处了解更多关于 log loss 的信息
https://machinelearning.org.cn/how-to-score-probability-predictions-in-python/
您可以在此处了解更多关于 ROC 的信息
https://machinelearning.org.cn/roc-curves-and-precision-recall-curves-for-classification-in-python/
嗨 Jason,
我想在新的数据(生成预测后的测试数据)上比较 SVR、RF、ANN、MLR 的调整后 R 平方。我知道 caret 有一个 R 平方和 RMSE 的函数,但我找不到 R 中任何用于调整后 R 平方的函数……请帮忙。
抱歉,我不太确定,也许可以尝试交叉验证或 R 用户组?
嗨,Jason,
感谢您的精彩文章。
我有一个问题,在使用 traincontrol 时。当我使用以下代码片段运行 GBM 模型时。我得到最佳调优模型的准确率约为 86%。但是当我将模型运行在整个训练数据集上时,准确率约为 98%。为什么训练和交叉验证误差之间会有如此大的差距?
我将不胜感激。期待您的回复。
gbmGrid <- expand.grid(
n.trees = (1:30)*50,
shrinkage=c(0.05,0.1,0.2,0.3),n.minobsinnode = c(10,15, 12),interaction.depth=c(4,5,6,8,9))
trainControl <- trainControl(method = "repeatedcv",
number = 3,
repeats = 3,
classProbs = T,
savePredictions = "all",
allowParallel = T)
modelFit <- train(
dv ~ . , data = train,
method = "gbm",
trControl = trainControl,
metric = "AUC",
preProcess = c("scale", "center"),
tuneGrid = gbmGrid,
bag.fraction=0.5
)
也许您的数据集太小了?
是的,确实如此。但是模型选择过程不应该选择过拟合模型吗?这个模型是否过拟合了?
您可以比较模型在训练集和测试集上的性能来判断模型是否过拟合。
感谢您的回复 Jason。
在这种情况下,我应该检查最佳调优模型的测试准确率与交叉验证准确率,还是测试准确率与训练准确率,以判断模型是否过拟合?
这是一个方法。
如果模型是迭代学习的,并且大多数模型都是如此,那么您可以使用学习曲线进行单次运行。
https://machinelearning.org.cn/learning-curves-for-diagnosing-machine-learning-model-performance/
如果我没记错的话,在 GBM 的情况下,参数是从 expand.grid 中选择的,然后生成一个模型,并根据该模型计算准确率?
在 caret R 中,我能否在每个树深度处计算验证准确率?
也许您可以改变模型上的树深度参数?
嗨,Jason,
感谢您一如既往的出色帖子!您提到对数损失适用于多分类问题。我想问一下,如果多分类也存在不平衡,对数损失是否也适用?对于不平衡的多分类数据集,您建议使用什么指标?谢谢!
分类交叉熵是多分类或多项式损失的损失。
也许从这里开始
https://machinelearning.org.cn/cross-entropy-for-machine-learning/