当您构建预测模型时,您需要一种方法来评估模型在未见过的数据上的能力。
这通常通过使用未用于训练模型的数据(例如测试集)来估算准确性,或者使用交叉验证来完成。R 中的 caret 包提供了许多估算机器学习算法准确性的方法。
在这篇文章中,您将发现 5 种在未见过的数据上估算模型性能的方法。您还可以获得使用 caret 包的 R 代码,可以立即复制并粘贴到您自己的项目中。
立即开始您的项目,阅读我的新书《R 机器学习精通》,其中包括分步教程和所有示例的R 源代码文件。
让我们开始吧。

R 中的 Caret 包,来自 caret 主页
估算模型准确性
我们之前在测试框架中的测试选项配置中考虑过模型准确性。您可以在文章中了解更多信息:如何在评估机器学习算法时选择正确的测试选项。
在这篇文章中,您将发现 5 种可用于估算模型准确性的不同方法。
它们如下,每种方法都将依次介绍
- 数据分割
- Bootstrap
- k 折交叉验证
- 重复 k-fold 交叉验证
- 留一法交叉验证
总的来说,我推荐重复 k-fold 交叉验证,但每种方法都有其特点和优点,尤其是在考虑数据量或空间和时间复杂度时。请考虑哪种方法最适合您的问题。
需要更多关于R机器学习的帮助吗?
参加我为期14天的免费电子邮件课程,了解如何在您的项目中使用R(附带示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
数据分割
数据拆分涉及将数据划分为用于准备模型的显式训练数据集和用于评估模型在未见过的数据上性能的未见过测试数据集。
当您拥有非常大的数据集时,这种方法很有用,这样测试数据集就可以提供有意义的性能估算,或者当您使用慢速方法并需要快速性能估算时。
下面的示例拆分了 iris 数据集,其中 80% 用于训练朴素贝叶斯模型,20% 用于评估模型的性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 加载库 library(caret) library(klaR) # 加载iris数据集 data(iris) # 定义数据集的 80%/20% 训练/测试拆分 split=0.80 trainIndex <- createDataPartition(iris$Species, p=split, list=FALSE) data_train <- iris[ trainIndex,] data_test <- iris[-trainIndex,] # 训练一个朴素贝叶斯模型 model <- NaiveBayes(Species~., data=data_train) # 进行预测 x_test <- data_test[,1:4] y_test <- data_test[,5] predictions <- predict(model, x_test) # 总结结果 confusionMatrix(predictions$class, y_test) |
Bootstrap
Bootstrap resampling involves taking random samples from the dataset (with re-selection) against which to evaluate the model. In aggregate, the results provide an indication of the variance of the models performance. Typically, large number of resampling iterations are performed (thousands or tends of thousands).
下面的示例使用具有 10 次重采样的 bootstrap 来准备朴素贝叶斯模型。
1 2 3 4 5 6 7 8 9 10 |
# 加载库 library(caret) # 加载iris数据集 data(iris) # 定义训练控制 train_control <- trainControl(method="boot", number=100) # 训练模型 model <- train(Species~., data=iris, trControl=train_control, method="nb") # 总结结果 print(model) |
k 折交叉验证
k-fold 交叉验证方法涉及将数据集分成 k 个子集。在训练模型时,每个子集都被排除。此过程一直进行到确定数据集中每个实例的准确性,并提供总体准确性估算。
它是估算准确性的一种稳健方法,k 的大小和调优会影响估算中的偏差量,常用的值为 3、5、7 和 10。
下面的示例使用 10 折交叉验证在 iris 数据集上估算朴素贝叶斯。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 加载库 library(caret) # 加载iris数据集 data(iris) # 定义训练控制 train_control <- trainControl(method="cv", number=10) # 固定算法参数 grid <- expand.grid(.fL=c(0), .usekernel=c(FALSE)) # 训练模型 model <- train(Species~., data=iris, trControl=train_control, method="nb", tuneGrid=grid) # 总结结果 print(model) |
重复 k-fold 交叉验证
将数据拆分成 k 折的过程可以重复多次,这称为重复 k-fold 交叉验证。最终模型准确性取自重复次数的平均值。
下面的示例使用 10 折交叉验证和 3 次重复来估算 iris 数据集上的朴素贝叶斯。
1 2 3 4 5 6 7 8 9 10 |
# 加载库 library(caret) # 加载iris数据集 data(iris) # 定义训练控制 train_control <- trainControl(method="repeatedcv", number=10, repeats=3) # 训练模型 model <- train(Species~., data=iris, trControl=train_control, method="nb") # 总结结果 print(model) |
留一法交叉验证
在 留一法交叉验证 (LOOCV) 中,会排除一个数据实例,并在训练集中的所有其他数据实例上构建模型。这会针对所有数据实例重复进行。
下面的示例演示了 LOOCV 在 iris 数据集上估算朴素贝叶斯。
1 2 3 4 5 6 7 8 9 10 |
# 加载库 library(caret) # 加载iris数据集 data(iris) # 定义训练控制 train_control <- trainControl(method="LOOCV") # 训练模型 model <- train(Species~., data=iris, trControl=train_control, method="nb") # 总结结果 print(model) |
总结
在这篇文章中,您发现了 5 种可用于估算模型在未见过数据上准确性的不同方法。
这些方法是:数据拆分、Bootstrap、k-fold 交叉验证、重复 k-fold 交叉验证和留一法交叉验证。
您可以在 caret 包主页 和 caret 包 CRAN 页面上了解更多关于 R 中的 caret 包。如果您想精通 caret 包,我推荐该包作者撰写的书籍《应用预测建模》,特别是关于模型过拟合的第 4 章。
先生,您好,
您能否提供贝叶斯分类器和 bootstrap 重采样(resampling)的完整代码?
我将把它作为我工程项目工作的模型……
confusionMatrix(predictions$class,y_test)
$ 运算符对原子向量无效
我在实现 R 代码以进行混淆矩阵时收到了一条错误消息……
您解决这个问题了吗?????
您是一位很棒的老师!其他人让复杂的事情变得更复杂,而您让上述内容看起来很简单。然而,您的电子邮件只是将我引向了其他书籍。为什么您不开始拥有自己的视频课程或书籍呢?
我正在努力,Romeo,请看看我网站上的培训部分。
尊敬的先生,如何在 caret 中为 fold 交叉验证计算混淆矩阵?
您可以在此处查看 caret 关于创建混淆矩阵的文档
https://topepo.github.io/caret/measuring-performance.html
嗨,Jason!
还有嵌套交叉验证用于估算真正的泛化误差。
是的。
嗨 Jason,非常感谢您分享您的知识,您能否提供关于嵌套交叉验证的信息?
您是在寻找这个吗? https://machinelearning.org.cn/nested-cross-validation-for-machine-learning-with-python/
非常有用的信息,非常简化
谢谢 pushpa。
嗨 Jason,在 k-fold 交叉验证的情况下,模型的准确性应该用“model”变量中的那个还是混淆矩阵中显示的那个?我假设是前者,但想确认一下。谢谢。
模型用于创建预测。
我们只能评估预测的准确性,准确性反映了模型的能力。
感谢您的回复,Jason。当我运行您的重复 k-fold 交叉验证代码,并查看“model”变量的内容时,我得到以下结果,准确性显示为 0.9533333。相比之下,当我查看 confusionMatris() 函数的结果时,准确性为 0.96(见下文)。在我的实际数据中,这种差异更大,分别为模型和混淆矩阵的 0.931 对 0.998。那么我的问题是,应该使用哪个结果作为模型的性能?
> model
朴素贝叶斯
150 个样本
4 个预测变量
3 个类别:“setosa”、“versicolor”、“virginica”
无预处理
重采样:交叉验证(10 折,重复 3 次)
样本大小摘要:135、135、135、135、135、135,…
跨调优参数的重采样结果
usekernel 准确率 Kappa 准确率 SD Kappa SD
FALSE 0.9533333 0.93 0.05295845 0.07943768
TRUE 0.9533333 0.93 0.05577734 0.08366600
调优参数 'fL' 固定为 0
准确度用于使用最大值选择最优模型。
用于模型的最终值为 fL = 0 和 usekernel = FALSE。
> confusionMatrix(predictions, iris$Species)
混淆矩阵和统计数据
参考
预测集 setosa versicolor virginica
setosa 50 0 0
versicolor 0 47 3
virginica 0 3 47
总体统计
准确率 : 0.96
(截断)
非常有帮助的材料!!!!!!
你好,
非常有用的,谢谢,我想知道您的代码有什么许可。
澄清一下会很好,因为您提供了复制/粘贴功能。
也许可以像 CC-BY 一样,通过引用您的网站来重用?
谢谢
Tobias
嗨,jason
看起来非常有帮助。我想为二次模型进行 bootstrap。当我将 training 模型中的 species~. 替换为我的模型,该模型有点像 lm(y~poly(x,2)+poly(z,2)).. 时,我发现回归方法不合适的错误。你能帮忙吗?
model <- train(Species~., data=iris, trControl=train_control, method="nb")
致敬
Dev
亲爱的Jason
我有一个包含 3 个类别(C1、C2 和 C3)和 7 个特征(变量)的数据集。
我已经使用所有变量对我的数据进行了多种方法的分类。
现在我想为每种方法绘制并说明例如一个 2D 图。
但我只能使用 2 个变量进行 2D 图。现在我不知道如何选择两个变量才能在图中最好地区分各个类别。我可以测试变量对的分类准确性(例如:V1-V2、V1-V3,...),但这非常耗时。你能帮我吗?有没有选择两个最佳变量进行分类模型的方法?
非常感谢。
此致,
Amir
很棒的博客。但我不太确定 kfold 模型是如何构建的。它运行 10 个折叠,然后使用 10 个折叠中的最佳模型,还是它在所有数据上拟合模型,您通过 kfolds 知道它的性能如何?
终于!一篇关于如何在 R 中进行交叉验证的清晰文章!
(它甚至使用了 Caret 包)。恭喜 Jason Brownlee!
超越混淆矩阵
这是一个维基百科文章,展示了计算相关度量值的公式
来自混淆矩阵
https://en.wikipedia.org/wiki/Sensitivity_and_specificity
真阳性 (TP)
等同于命中
真阴性 (TN)
等同于正确拒绝
假阳性 (FP)
等同于误报,第一类错误
假阴性 (FN)
等同于漏报,第二类错误
灵敏度或真阳性率 (TPR)
等同于命中率,召回率
TPR = TP / P = TP / (TP+FN)
特异度 (SPC) 或真阴性率
SPC = TN / N = TN / (TN+FP)
精确率或阳性预测值 (PPV)
PPV = TP / (TP + FP)
阴性预测值 (NPV)
NPV = TN / (TN + FN)
漏报率或假阳性率 (FPR)
FPR = FP / N = FP / (FP + TN) = 1-SPC
假阴性率 (FNR)
FNR = FN / (TP + FN) = 1-TPR
假发现率 (FDR)
FDR = FP / (TP + FP) = 1 – PPV
准确率 (ACC)
ACC = (TP + TN) / (TP + FP + FN + TN)
https://en.wikipedia.org/wiki/Sensitivity_and_specificity
一篇清晰且非常有用的文章
谢谢。
杰森 –
我正在进行一个使用 caret 包的项目,我首先将数据划分为 5 个 CV 折,然后在 5 个训练折中的每个折上训练竞争模型,并使用 10 折 CV 对剩余的测试折进行评分以评估性能。
如何获得 5 个测试折分区中的最佳拟合模型预测值?
例如,使用以下数据集
# 加载数据并因子化 admit 变量。
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv"😉
mydata$admit <- as.factor(mydata$admit)
# 创建 yes/no 级别,以确保 classprobs 获得正确的名称。
levels(mydata$admit) = c("yes", "no")
# 将数据划分为 5 个折。
set.seed(123)
folds <- createFolds(mydata$admit, k=5)
# 使用 index 参数通过 10 折 CV 在每个 5 个训练折上训练弹性网络逻辑回归。
set.seed(123)
train_control <- trainControl( method="cv",
number=10,
index=folds,
classProbs = TRUE,
savePredictions = TRUE)
glmnetGrid <- expand.grid(alpha=c(0, .5, 1), lambda=c(.1, 1, 10))
model<- train(admit ~ .,
data=mydata,
trControl=train_control,
method="glmnet",
family="binomial",
tuneGrid=glmnetGrid,
metric="Accuracy",
preProcess=c("center","scale"))
caret 是否可以通过 10 折 CV 获得的最佳拟合模型(具有最优 alpha 和 lambda 值)在每个 5 个测试折分区上提取预测值?
Caret Train 不输出准确率 SD
我尝试运行以下代码,但唯一可以获得的度量是准确率和 Kappa。我需要查看准确率 SD 和 Kappa SD。有可能吗?
我使用的代码是
library(“caret”, lib.loc=”~/R/win-library/3.3″)
set.seed(42)
mtry <- sqrt(ncol(Train_2.4.16[,-which(names(Train_2.4.16) == "Label")]))
control <- trainControl(method="repeatedcv", number=10, repeats=5)
tunegrid <- expand.grid(.mtry=mtry)
rfFit <- train(Label ~., data = Train_2.4.16,
method = "rf",
preProc = c("center", "scale"),
tuneLength = 10,
metric = "Accuracy",
trControl=control,
allowParallel=TRUE)
print(rfFit)
输出是关于不同 mtry 值以及准确率和 kappa 度量的多行,但它没有显示准确率的标准差 (Accuracy SD) 和 kappa 的标准差 (Kappa SD),这两者也很重要。是否有任何指标需要设置才能在输出中显示这两个重要度量?
你好 Heba,也许 caret API 已经改变了。我很抱歉。
这是正常的吗?
model <- train(Species~., data=iris, trControl=train_control, method="nb", tuneGrid=grid)
Error in command 'train.default(x, y, weights = w, …)'
调优参数网格应包含 fL、usekernel、adjust 列
也许是包已更新。错误表明您需要将“fL, usekernel, adjust”包含在要优化的参数网格中。
estou com o mesmo problema
I have the same problem
在评估模型准确性之后,您是否可以返回修改模型?例如,您发现模型在比较训练集和测试集结果时存在过拟合。我问这个问题是因为在机器学习课程中,老师说我们永远不应该使用测试数据来帮助模型构建。测试数据只是用于现实检验模型的力量。
你好 Peter,
我同意你老师的观点,如果测试集或验证集被保留,并且您正在使用训练集进行交叉验证或类似操作。
你好 Jason。感谢你精彩的帖子。
但我有一个问题。
为了计算模型的准确性,我在决策树中使用 confusionMatrix。
在执行此过程之前,我使用 createDataPartition() 函数分割了数据。
现在我想计算 gbm 模型的准确性。
我认为 gbm 模型使用全部数据,因为它是一种提升模型。
所以……我无法计算 gbm 模型的准确性……
你能解释一下如何计算 gbm() 函数的准确性吗?
我是否必须使用 createDataPartition() 来分割数据集?
祝你有美好的一天!
是的,您可以使用重采样方法来评估任何算法的性能。
你的意思是使用数据分割方法?
在 gbm() 建模中,使用训练数据集进行建模有问题吗?
我认为我必须在 gbm() 建模中使用完整的数据集。
我的信息是错误的吗?
我们经常在评估模型时分割数据,即使是使用 gbm。
某些实现确实为“自动”调优提供了内置的交叉验证,也许这会让您感到困惑。
稍后,一旦我们为生产环境选择了一个模型,我们就可以在所有数据上拟合模型
https://machinelearning.org.cn/train-final-machine-learning-model/
你好 Jason。谢谢你提供的好信息!
我有一个问题。
你在 k 折交叉验证中使用了 tunegrid
但是,你为什么没有在重复 k 折交叉验证方法中使用它呢?
有什么区别??
使用重复进行 CV 来评估随机算法是个好主意。
在这个例子中为了简单起见,我没有这样做。
请参阅这篇关于随机机器学习算法的帖子
https://machinelearning.org.cn/randomness-in-machine-learning/
谢谢你的回复。
但我指的是 tunegrid 参数,而不是重复 CV。
我的意思是,你在 k 折交叉验证中使用了 tunegrid 参数,但你没有在重复 k 折交叉验证方法中使用 tunegrid 参数。
有什么区别?
tunegrid 用于评估一组超参数。
这对于使用 CV(无论是否重复)都不是必需的。
我有点困惑。
“评估模型准确性”是否包含在这些教程中,而没有明确的
代码?
https://machinelearning.org.cn/compare-models-and-select-the-best-using-the-caret-r-package/
https://machinelearning.org.cn/evaluate-machine-learning-algorithms-with-r/
此示例的准确性值与其他示例的准确性值有何不同?
这个错误是什么意思?
> model <- NaiveBayes(n2~., data=data_train)
Error in NaiveBayes.default(X, Y, …)
grouping/classes object must be a factor
此示例是否需要 colClasses 参数?
此示例是否仅用于分类问题?
是的,这个示例是用于分类的。
这意味着您的输出变量不是因子(类别)。
您可以使用 as.factor()(凭记忆)将其转换为因子。
Y 可以是它自己的类别吗?
我不明白。
Y 是输出变量,它可以是类别(因子)或实数值,具体取决于您的问题是分类还是回归。
重复交叉验证是否应该给我们提供样本外(训练)误差的有效估计?我似乎在比较 caret 的 repeatedcv 指标和手动留出样本时得到非常不同的错误率。我是否遗漏了关于 repeatedcv 的什么?谢谢!我喜欢你的内容!
重复交叉验证应该是一个偏差较小的估计。
留出样本得分可能会过于乐观。
你好
当我运行你的代码时,我收到了以下错误
Error in train(Species ~ ., data = iris, trControl = train_control, method = “nb”)
unused arguments (data = iris, trControl = train_control, method = “nb”)
你能解释一下如何解决这个问题吗?
请确认您已复制代码中的所有必要代码。
你好,
我将使用留一法交叉验证 (leave one out cross validation) 来处理 Cubist。但我不知道如何使用它。你在这里发布的代码在我的代码中不起作用。
请问你能在这方面帮助我吗?
祝好,
如何将这些技术应用于时间序列预测?
从这里开始,了解时间序列
https://machinelearning.org.cn/start-here/#timeseries
嗨,
感谢您提供出色的教程。
是否有其他包我们可以使用而不是 caret?因为对于版本 3.2.4,caret 不可用。
谢谢你
你说的不可用是什么意思?
https://github.com/topepo/caret
https://cran.r-project.cn/web/packages/caret/
你好 Jason,方法 “cv” 是否也适用于分层 k 折方法?
亲爱的 Jason,
首先,非常感谢您努力解释一个困难的主题。
我目前正在处理线性混合模型,并希望对我的模型进行
LOOCV。
fm2 <- lme(X1 ~ X2 + X3, random= ~1|X4, method="REML", data = bb)
fm4<-update(fm2, correlation = corSpher(c(25, 0.5), nugget=TRUE,form = ~ X5 + X6|X4))
如何将我的模型插入你的脚本?
先谢谢了
emanuele
在 k 折交叉验证方法中,我收到此错误消息
> model
我不知道这是什么意思,所以很感谢你能提供解决方案。
祝好
Duncan
看来您可能没有将所有相关代码复制到您的示例 Duncan 中?
Error: The tuning parameter grid should have columns fL, usekernel, adjust
如何将 fL, usekernel, adjust 参数包含在网格中?
非常感谢,
Mansur
这个博客写得真好
谢谢克里斯!
我有点不好意思问这个问题……
我有一个小样本集(大约 120 个,其中有 20 个“阳性”案例)。我正在使用逻辑回归和交叉验证(cv = 10)。我还需要一个留出集来进行测试以真正确定准确性吗?
CV 应该是模型技能的足够估计。
这有帮助吗?
是的 – 谢谢。我之前对 cv / 留出样本测试感到困惑。谢谢。
没问题 Keith,希望现在清楚了。
嗨 Jason
我运行我的 train 函数,如下所示
caret_model <- train(method "glm", trainControl (method = "cv", number = 5, …), data = train, …)
我正在收集我的 ROC 结果,使用 caret_model$results 和系数,使用 caret_model$finalModel 或 summary(caret_model)。
然后,我运行一个简单的 glm,如下所示
glm_model <- glm(data = train, formula=…, family=binomial).
当我检查我的 glm_model 的系数时,它们与我的 caret_model 的系数完全相同。
那么,我的问题是,caret 实际上在什么数据上通过交叉验证运行 glm 模型,因为它产生的系数与在训练数据上运行的简单 glm 模型完全相同?我以为它实际上运行了 5 个 glm 模型,生成了 5 个 ROC,然后显示了这 5 个 ROC 的平均值,并根据最佳 ROC 选择最佳 glm 模型。但我认为它没有这样做,因为系数与在训练数据上运行的简单 glm 模型完全相同。
非常感谢。
也许 caret 训练了一个最终模型,并且还使用了 CV。
事实上,情况就是这样
https://www.rdocumentation.org/packages/caret/versions/6.0-78/topics/train
当我运行我的代码时
> train_control model <- train(emotion~., data=tweet_p1, trControl=train_control, method="nb")
我得到
需要此模型的一个包,但未安装。(klaR)。您是否想现在尝试安装它?
1: yes
2: no
Selection: yes
Warning: dependency ‘later’ is not available
然后它安装了一堆其他依赖项。这是安装消息的结尾
已下载的二进制包位于
/var/folders/k0/bl302_r97b171sw66wd_h8nw0000gn/T//RtmpmT5Kvt/downloaded_packages
Error: package klaR is required
包 klaR 如何要求安装它本身?总之,我直接安装了 library(klaR),这些消息的结尾是
Error: package or namespace load failed for ‘klaR’ in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]])
there is no package called ‘later’
然后我执行 install.packages("later"),我收到的错误是
Warning in install.packages
package ‘later’ is not available (for R version 3.5.0)
然后我执行 library(later)
有什么建议吗?
抱歉,第一行代码应该是
> train_control model <- train(emotion~., data=tweet_p1, trControl=train_control, method="nb")
我很抱歉听到您遇到的困难。
也许试试将您的错误消息发布到 stackoverflow?
我的意思是:(它一直在吃我的文本)
train_control <- trainControl(method="LOOCV")
model <- train(emotion~., data=tweet_p1, trControl=train_control, method="nb")
先生,我正在从事股票市场预测项目,哪种模型最好?
这是我在这里回答的一个常见问题
https://machinelearning.org.cn/faq/single-faq/can-you-help-me-with-machine-learning-for-finance-or-the-stock-market
假设我想比较一个标准的逻辑回归对象(即 modlog<-glm(class~., data=dat, family= binomial(link= ‘logit’))),而不是一个 caret() 训练的逻辑回归对象,与一个 caret 决策树对象。
虽然随机分区数据,使用 caret createDataPartition(),可以最初应用于原始数据集,但看起来 trainControl() 创建的 trControl 变量仅与 caret train() 树或 glm 派生对象兼容,这意味着 trainControl 中实现的 k 折交叉验证无法应用于标准的逻辑回归对象。这是正确的吗?
祝好,
Charlie
附言:好文章
我不确定我是否明白了。您可以使用 caret 来评估模型或在所有数据上拟合独立的 glm 模型,您也可以使用 caret(例如,分割)来准备数据并手动拟合 glm 模型。
对不同方法的精彩解释。您是否知道 Caret 包是否可以使用负二项分布处理多水平模型?谢谢~
也许可以查阅 glm 文档?
你好,
谢谢你这篇帖子。
我想对回归进行 CV,特别是 NonpModelCheck 包中的 localpoly.reg。此函数不在 train 函数的“method”选项中!我该如何将此函数用于 train?
我不熟悉那个函数,抱歉。也许试试发布到 stackoverflow?
我使用留一法交叉验证 (Leave One Out Cross Validation) 对一个具有 102 个因变量 (y dependent=true) 和 x (解释) 变量/记录的数据集进行了测试。y 预测值和 y 真值之间的相关系数为 0.43;RMSEP=19.84;y 真值对 y 预测值的回归系数 = 0.854;y 真值的标准差 SD=21.94,RPD = SD/RMSEP=1.10。
Williams, PC (1987) 提出了一个表格,其中对各种 RPD 值有以下解释(见下方完整参考文献)
0 到 2.3 非常差
2.4 到 3.0 差
3.1 到 4.9 一般
5.0 到 6.4 好
6.5 到 8.0 很好
8.1+ 优秀
基于此,我的预测模型 RPD=1.1 非常差。
我希望能就 RPD 在预测模型评估中的使用发表评论。
一个额外的问题
我们应该使用真值对预测值的回归,还是反之?这其中一种理论上是否比另一种更正确?
mvh
Bjarne
Williams, PC (1987) Variables affecting near-infrared reflectance spectroscopic analysis. Pages 143-167 in: Near Infrared Technology in the Agriculture and Food Industries. 1st Ed. P.Williams and K.Norris, Eds. Am. Cereal Assoc. Cereal Chem., St. Paul, MN.
该手册的第二版于 2004 年出版。在第 8 章“近红外技术实施”(第 145 至 169 页)中,作者是 P. C. Williams。
我在这里有一些关于改进模型性能的一般性建议
https://machinelearning.org.cn/machine-learning-performance-improvement-cheat-sheet/
我不明白你的第二个问题,抱歉,你能详细说明吗?
我的第一个问题是如何解释给定数据和所选模型的结果。
正如你所指出的,如果你使用 r-squared 和其他度量标准以及标准化输出,你就可以使用表格来解释结果。
如果您使用标准误差度量,例如MSE,可以相对地比较性能,例如与基线朴素方法相比——以确定模型是否熟练。我在这里有更多关于这方面的信息。
https://machinelearning.org.cn/faq/single-faq/how-to-know-if-a-model-has-good-performance
我的第二个问题与以下事实有关:似乎没有一种公认的方法来评估预测模型;例如,预测值对真实值的回归,或真实值对预测值的回归。后者会给出更高的回归系数,因为预测值的方差小于真实值的方差。使用这两种方法中的一种是否有理论依据?
例如,请参阅 Pineiro 等人,2016。如何评估模型:观察值与预测值,还是预测值与观察值?生态模型 2 1 6,316–322。
有标准的度量,例如MAE、MSE和RMSE,用于评估回归模型的熟练度。
假设我用重复交叉验证拟合了一个套索模型。测试误差估计可以通过您的解释找到。但是,估计的活动集根据重复次数的不同而不同。我如何报告套索的系数估计?
也许报告多次运行中每个系数的平均值/标准差?
但是,如果我报告平均值,那么根据数据,最终模型中的任何系数估计可能都不会为零。这意味着没有变量选择。
你好,Jason,
我的问题是:交叉验证之后下一步是什么?
让我解释一下
>我有一个数据集,并随机抽取测试集和训练集(比例为30:70)。
>现在我用逻辑回归(LRM1)创建了一个模型,并计算了准确率,似乎还可以。
>使用模型LRM1在测试集上进行预测。
>在训练数据集上绘制ROC曲线,并获得新的截止点。基于新的截止点,对测试预测模型进行分类并计算准确率。
现在,我想进行交叉验证。
我的理解是,使用交叉验证,我需要验证已构建的模型,即LRM1。
但根据您的文章,我有点迷茫。
>我的问题是:我是否需要使用交叉验证在训练数据集上创建一个新模型,计算准确率,绘制ROC曲线,并在测试数据集上进行预测?
>与之前创建的模型(LRM1)无关。
请告诉我我是否说得通。:(
通常,我们使用交叉验证来估计模型在未见过的数据上的熟练程度。
之后,我们可以将熟练程度与其他模型进行比较,选择一个模型,然后拟合最终模型以开始在新数据上进行预测。
https://machinelearning.org.cn/train-final-machine-learning-model/
这有帮助吗?
不,实际情况并非如此。我更困惑了。
在下面的代码中,我们传递的是数据集而不是已构建的模型。
# 加载库
library(caret)
# 加载iris数据集
data(iris)
# 定义训练控制
train_control <- trainControl(method="repeatedcv", number=10, repeats=3)
# 训练模型
model <- train(Species~., data=iris, trControl=train_control, method="nb")
# 总结结果
print(model)
## 假设我用我的数据构建了RFM1。现在如何进行交叉验证?
我正在热切等待您的回复。
你好,
我想使用LOOCV和随机森林,我不知道如何在构建LOO模型后获得预测。
提前感谢
Sidy
拟合一个在所有数据上的最终模型并调用predict。
也许这会有帮助。
https://machinelearning.org.cn/train-final-machine-learning-model/
嗨,Jason,
您的帖子总结得很好!但我有一个困惑:交叉验证和留一(或p)个样本交叉验证之间有什么确切的区别?我可以理解为留一交叉验证是一种交叉验证吗?提前谢谢!
嗨,Jason,
作为对我上面问题的补充和阐述:如果我理解正确(请纠正我是否错误):留一交叉验证是K折交叉验证的逻辑极端,K等于N,即数据点的数量。换句话说,如果我们有100个观测值,留一交叉验证是每次都使用99个样本进行训练,然后留下一个样本使用已构建的模型进行预测,并进行100次,我说的对吗?如果是这样,我想每次迭代的预测误差将仅基于这“一个”样本,所以每次迭代的准确率要么是0(错误)要么是1(正确)。然后使用这100次的平均值作为模型性能的估计,对吗?非常感谢!
是的。
谢谢。
LOOCV是K折交叉验证,其中K等于训练集中的示例数量。
明白了,谢谢Jason!
不客气。
这里有一个一直困扰我的问题。caret包中的交叉验证似乎最小化了折叠特定的RMSE的平均值,即平方根分别在每个折叠中取,然后取平均值。您知道这是什么原理吗?Hastie和Tibshirani在他们著名的书中(第二版,第242页)将所有观测值的平方预测误差相加并最小化。后者更容易理解。
感谢您提供的精彩页面。它们对我帮助很大。
平方根像一个缩放操作,您可以直接操作总和(MSE),我不会期望在选择最终模型/模型比较方面有所不同。
是的,在大多数应用中不应该有太大区别,除非最佳值的选择在任何情况下都不确定。然而,对于留一交叉验证,两个可能的损失函数(折叠内的RMSE vs 观测值的平方误差)将对应于绝对预测误差之和与平方预测误差之和,这听起来差别很大。
我开发了以下工作流程。
1-拆分数据 80/20
2-用80%训练随机森林
3-在20%上进行预测
4-保存混淆矩阵的准确率
5-重复n次(蒙特卡洛)
6-平均n次的性能指标
这样做合理吗?
在您的帖子中,如果我理解正确,我们对训练数据进行cv,然后只预测一次?我这样做对吗?
非常感谢Jason。
你说的对。只有在步骤5中,你需要确保随机森林是全新的训练,没有先前数据分割的知识。然后性能指标是针对随机森林作为你的数据的算法,而不是针对你训练的特定随机森林。
嗨,Jason,
您能否也向我们展示如何进行嵌套交叉验证?
谢谢
这有帮助:https://machinelearning.org.cn/nested-cross-validation-for-machine-learning-with-python/
嗨,Jason,
感谢您的代码,我正在使用“留一交叉验证”部分的代码,在接下来的步骤中,我该如何绘制ROC并获得AUC?您能帮我解决这个问题吗?
您需要使用其他R包来完成。这应该有帮助:https://rviews.rstudio.com/2019/03/01/some-r-packages-for-roc-curves/
你好 Adrian,
感谢您的回复,我使用了“pROC”包来绘制ROC并获取AUC,但我只得到了一个拐点。我认为我的代码可能出了问题,您能帮我纠正一下吗?
这是我的R代码。
df1 <- read.table("./.txt",header = TRUE,quote="")
df1[,1] <- as.factor(df1[,1])
set.seed(100)
train_control<-trainControl(method = "LOOCV")
ntree_fit<-randomForest(type2~.,data=df1,mtry=2,ntree=200)
plot(ntree_fit)
fit_randomForest1<-randomForest(type2~. ,data=df1,method="rf",mtry=2,ntree = 50,
trControl=train_control,important = TRUE, proximity = TRUE)
ran_roc <- roc(df1$type2,as.numeric(fit_randomForest1[["predicted"]]))
plot(ran_roc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
grid.col=c("green", "red"), max.auc.polygon=TRUE,auc.polygon.col="skyblue",
print.thres=TRUE,legacy.axes=TRUE, partial.auc.focus="se")
你好,
我使用了R包“pROC”来绘制ROC曲线,但我认为我的代码有问题,我只得到一个拐点,您能帮我纠正一下吗?
fit_randomForest1<-randomForest(Type2~. ,data=df1,method="rf",mtry=2,ntree = 50,
trControl=train_control,important = TRUE, proximity = TRUE)
ran_roc <- roc(df1$type2,as.numeric(fit_randomForest1[["predicted"]]))
plot(ran_roc, print.auc=TRUE, auc.polygon=TRUE, grid=c(0.1, 0.2),
grid.col=c("green", "red"), max.auc.polygon=TRUE,auc.polygon.col="skyblue",
print.thres=TRUE,legacy.axes=TRUE, partial.auc.focus="se")
从代码中看不出什么问题。为什么您认为一个拐点是不正确的?
我不确定。我看到的多数ROC曲线都有多个拐点,并且我读过一篇博客说:如果ROC只有一个拐点,那是因为在绘制曲线时,您使用了类别的预测值,而不是使用概率。
当我运行“fit_randomForest1[[“predicted”]]”时
我得到这个:fit_randomForest1[[“predicted”]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1 1 1 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1
Levels: 1 2
我认为我应该使用概率来绘制ROC曲线。但我不知道如何获得概率。
ROC图绘制的是真正率与假正率。对于您的二元分类示例,我认为曲线看起来非常典型。关于计算TPR和FPR的公式(ROC绘图库应该会为您完成),请参阅https://en.wikipedia.org/wiki/Receiver_operating_characteristic。
谢谢。
我想冒昧地问一个问题。
我想评估我的逻辑回归模型的区分准确性。
我如何评估我的模型是否能准确地将病例与非病例分类?在文献中,有人建议使用ROC和ROC下的面积(auc)。然而,由于我在模型中使用了pweght,Stata命令在计算ROC时不支持pweight。我该如何处理这些问题?
提前感谢您的帮助。
此致,
你好 Gebretsadik……以下资源可能感兴趣。
https://machinelearning.org.cn/roc-curves-and-precision-recall-curves-for-imbalanced-classification/
很棒的文章。但我有一个问题。为什么我们不能为LOOCV计算混淆矩阵。
例如,在上面的LOOCV示例中,如果我们使用
cm <- confusionMatrix(model, "none")
它会抛出错误:Error in confusionMatrix.train(model, "none")
无法计算留一法、袋外重采样或无重采样的混淆矩阵。
你好 Malik……感谢您的反馈!以下讨论可能提供一些思路。
https://github.com/topepo/caret/issues/947