抽查机器学习算法是 寻找最适合你的数据集的算法的方法。
但是你应该抽查哪些算法呢?
在这篇文章中,你将发现 8 种你应该在数据上抽查的机器学习算法。
你还将获得每种算法的示例,你可以复制并粘贴到你当前或下一个 R 机器学习项目中。
通过我的新书 R 语言机器学习精通启动你的项目,包括分步教程和所有示例的 R 源代码文件。
让我们开始吧。

在 R 语言中抽查机器学习算法
图片来源:Nuclear Regulatory Commission,部分权利保留。
最适合你的数据集的算法
你无法事先知道哪种算法最适合你的数据集。
你必须通过反复试验来发现一些在你的问题上表现良好的算法,然后你可以集中精力进一步调整它们。我将这个过程称为抽查。
问题不是
我应该在我的数据集上使用哪种算法?
而是
我应该在我的数据集上抽查哪些算法?
应该抽查哪些算法
你可以猜测哪些算法可能在你的数据集上表现良好,这可能是一个很好的起点。
我建议尝试混合使用算法,看看哪种算法擅长从你的数据中找出结构。
- 尝试混合使用算法表示(例如,实例和树)。
- 尝试混合使用学习算法(例如,学习相同类型表示的不同算法)。
- 尝试混合使用建模类型(例如,线性和非线性函数或参数和非参数)。
让我们具体一点。在下一节中,我们将介绍你可以在下一个 R 机器学习项目中抽查的算法。
需要更多关于R机器学习的帮助吗?
参加我为期14天的免费电子邮件课程,了解如何在您的项目中使用R(附带示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
在 R 语言中抽查的算法
R 语言中有数百种机器学习算法可用。
我建议探索其中的许多算法,特别是如果准确预测你的数据集很重要并且你有时间的话。
通常你没有时间,所以你需要知道一些你绝对必须在你的问题上测试的算法。
在本节中,你将发现你应在 R 语言中抽查的线性和非线性算法。这不包括集成算法,例如 Boosting 和 Bagging,这些算法可以在你获得基线之后再使用。
每种算法将从两个角度进行介绍
- 用于训练和进行算法预测的包和函数。
- 算法的 caret 封装。
你需要知道特定算法使用哪个包和函数。这在以下情况下是必需的
- 你正在研究算法参数以及如何最大限度地利用算法。
- 你已经发现了要使用的最佳算法,需要准备一个最终模型。
你需要知道如何使用 caret 使用每种算法,以便你可以使用 caret 的预处理、算法评估和调优功能,有效地评估算法在未见数据上的准确性。
两个标准数据集用于演示这些算法
- 用于回归的波士顿房价数据集(来自 mlbench 库的 BostonHousing)。
- 用于分类的印第安纳皮马人糖尿病数据集(来自 mlbench 库的 PimaIndiansDiabetes)。
算法分为两组
- 线性算法是更简单的方法,具有很强的偏差但训练速度快。
- 非线性算法是更复杂的方法,具有很大的方差但通常更准确。
本节中提供的每个示例都是完整的,并且会产生结果,因此你可以将其复制并粘贴到你当前或下一个机器学习项目中。
让我们开始吧。
线性算法
这些方法对所建模函数的形式进行了很大的假设。因此,它们具有高偏差但通常训练速度快。
最终模型通常也易于(或更容易)解释,这使得它们成为理想的最终模型。如果结果足够准确,你可能不需要转向非线性方法,如果线性算法。
1. 线性回归
lm() 函数位于 stats 库中,并使用普通最小二乘法创建线性回归模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 加载库 library(mlbench) # 加载数据 data(BostonHousing) # 拟合模型 fit <- lm(medv~., BostonHousing) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, BostonHousing) # 总结准确度 mse <- mean((BostonHousing$medv - predictions)^2) print(mse) |
lm 的实现可以在 caret 中使用,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(BostonHousing) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.lm <- train(medv~., data=BostonHousing, method="lm", metric="RMSE", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.lm) |
2. 逻辑回归
glm 函数在 stats 库中,并创建广义线性模型。它可以配置为执行适用于二元分类问题的逻辑回归。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- glm(diabetes~., data=PimaIndiansDiabetes, family=binomial(link='logit')) # 总结拟合 print(fit) # 进行预测 probabilities <- predict(fit, PimaIndiansDiabetes[,1:8], type='response') predictions <- ifelse(probabilities > 0.5,'pos','neg') # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
glm 算法可以在 caret 中使用,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.glm <- train(diabetes~., data=PimaIndiansDiabetes, method="glm", metric="Accuracy", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.glm) |
3. 线性判别分析
lda 函数在 MASS 库中,并创建分类问题的线性模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 加载库 library(MASS) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- lda(diabetes~., data=PimaIndiansDiabetes) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, PimaIndiansDiabetes[,1:8])$class # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
lda 算法可以在 caret 中使用,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.lda <- train(diabetes~., data=PimaIndiansDiabetes, method="lda", metric="Accuracy", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.lda) |
4. 正则化回归
glmnet 函数在 glmnet 库中,可用于分类或回归。
分类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# 加载库 library(glmnet) library(mlbench) # 加载数据 data(PimaIndiansDiabetes) x <- as.matrix(PimaIndiansDiabetes[,1:8]) y <- as.matrix(PimaIndiansDiabetes[,9]) # 拟合模型 fit <- glmnet(x, y, family="binomial", alpha=0.5, lambda=0.001) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, x, type="class") # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
回归示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 加载库 library(glmnet) library(mlbench) # 加载数据 data(BostonHousing) BostonHousing$chas <- as.numeric(as.character(BostonHousing$chas)) x <- as.matrix(BostonHousing[,1:13]) y <- as.matrix(BostonHousing[,14]) # 拟合模型 fit <- glmnet(x, y, family="gaussian", alpha=0.5, lambda=0.001) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, x, type="link") # 总结准确度 mse <- mean((y - predictions)^2) print(mse) |
它还可以通过将 alpha 参数分别设置为 1、0 或 [0,1] 来配置为执行三种重要的正则化类型:lasso、ridge 和 elastic net。
glmnet 的实现可以在 caret 中用于分类,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 |
# 加载库 library(caret) library(mlbench) library(glmnet) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.glmnet <- train(diabetes~., data=PimaIndiansDiabetes, method="glmnet", metric="Accuracy", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.glmnet) |
glmnet 的实现可以在 caret 中用于回归,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 |
# 加载库 library(caret) library(mlbench) library(glmnet) # 加载数据集 data(BostonHousing) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.glmnet <- train(medv~., data=BostonHousing, method="glmnet", metric="RMSE", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.glmnet) |
非线性算法
这些是机器学习算法,它们对所建模的函数做的假设更少。因此,它们具有更高的方差,但通常会带来更高的准确性。它们增加的灵活性也可能使它们训练更慢或增加它们的内存需求。
1. k-近邻
knn3 函数在 caret 库中,它不创建模型,而是直接从训练集中进行预测。它可用于分类或回归。
分类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# knn 直接分类 # 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- knn3(diabetes~., data=PimaIndiansDiabetes, k=3) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, PimaIndiansDiabetes[,1:8], type="class") # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
回归示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# 加载库 library(caret) library(mlbench) # 加载数据 data(BostonHousing) BostonHousing$chas <- as.numeric(as.character(BostonHousing$chas)) x <- as.matrix(BostonHousing[,1:13]) y <- as.matrix(BostonHousing[,14]) # 拟合模型 fit <- knnreg(x, y, k=3) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, x) # 总结准确度 mse <- mean((BostonHousing$medv - predictions)^2) print(mse) |
knn 的实现可以在 caret 的 train() 函数中用于分类,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.knn <- train(diabetes~., data=PimaIndiansDiabetes, method="knn", metric="Accuracy", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.knn) |
knn 的实现可以在 caret 的 train() 函数中用于回归,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) data(BostonHousing) # 加载数据集 data(BostonHousing) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.knn <- train(medv~., data=BostonHousing, method="knn", metric="RMSE", preProc=c("center", "scale"), trControl=control) # 总结拟合 print(fit.knn) |
2. 朴素贝叶斯
naiveBayes 函数在 e1071 库中,它独立地建模每个属性与结果变量的概率。它可用于分类问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 加载库 library(e1071) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- naiveBayes(diabetes~., data=PimaIndiansDiabetes) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, PimaIndiansDiabetes[,1:8]) # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
一个非常相似的朴素贝叶斯实现(来自 klaR 库的 NaiveBayes)可以与 caret 一起使用,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.nb <- train(diabetes~., data=PimaIndiansDiabetes, method="nb", metric="Accuracy", trControl=control) # 总结拟合 print(fit.nb) |
3. 支持向量机
ksvm 函数在 kernlab 包中,可用于分类或回归。它是 LIBSVM 库的包装器,并提供了一套内核类型和配置选项。
这些示例使用径向基函数内核。
分类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
加载 库 library(kernlab) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- ksvm(diabetes~., data=PimaIndiansDiabetes, kernel="rbfdot") # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, PimaIndiansDiabetes[,1:8], type="response") # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
回归示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 加载库 library(kernlab) library(mlbench) # 加载数据 data(BostonHousing) # 拟合模型 fit <- ksvm(medv~., BostonHousing, kernel="rbfdot") # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, BostonHousing) # 总结准确度 mse <- mean((BostonHousing$medv - predictions)^2) print(mse) |
带有径向基核的 SVM 实现可以与 caret 一起用于分类,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.svmRadial <- train(diabetes~., data=PimaIndiansDiabetes, method="svmRadial", metric="Accuracy", trControl=control) # 总结拟合 print(fit.svmRadial) |
带有径向基核的 SVM 实现可以与 caret 一起用于回归,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(BostonHousing) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.svmRadial <- train(medv~., data=BostonHousing, method="svmRadial", metric="RMSE", trControl=control) # 总结拟合 print(fit.svmRadial) |
4. 分类和回归树
rpart 库中的 rpart 函数提供了 CART 在分类和回归方面的实现。
分类示例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 加载库 library(rpart) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 拟合模型 fit <- rpart(diabetes~., data=PimaIndiansDiabetes) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, PimaIndiansDiabetes[,1:8], type="class") # 总结准确度 table(predictions, PimaIndiansDiabetes$diabetes) |
回归示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 加载库 library(rpart) library(mlbench) # 加载数据 data(BostonHousing) # 拟合模型 fit <- rpart(medv~., data=BostonHousing, control=rpart.control(minsplit=5)) # 总结拟合 print(fit) # 进行预测 predictions <- predict(fit, BostonHousing[,1:13]) # 总结准确度 mse <- mean((BostonHousing$medv - predictions)^2) print(mse) |
rpart 的实现可以与 caret 一起用于分类,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 训练 set.seed(7) control <- trainControl(method="cv", number=5) fit.rpart <- train(diabetes~., data=PimaIndiansDiabetes, method="rpart", metric="Accuracy", trControl=control) # 总结拟合 print(fit.rpart) |
rpart 的实现可以与 caret 一起用于回归,如下所示
1 2 3 4 5 6 7 8 9 10 11 |
# 加载库 library(caret) library(mlbench) # 加载数据集 data(BostonHousing) # 训练 set.seed(7) control <- trainControl(method="cv", number=2) fit.rpart <- train(medv~., data=BostonHousing, method="rpart", metric="RMSE", trControl=control) # 总结拟合 print(fit.rpart) |
其他算法
R 中提供了许多其他算法,并且在 caret 中可用。
我建议您探索它们,并在您的下一个机器学习项目中,将更多算法添加到您的必试算法短名单中。
您可以在此页面上找到 caret 包中机器学习函数和包到其名称的映射
如果您在 caret 中使用某个算法,并且想知道它属于哪个包,以便您可以阅读其参数并从中获得更多信息,那么此页面很有用。
如果您直接在 R 中使用机器学习算法,并且想知道如何在 caret 中使用它,那么此页面也很有用。
总结
在这篇文章中,您发现了 8 种不同的算法,您可以使用它们来对数据集进行快速检查。具体来说
- 线性回归
- 逻辑回归
- 线性判别分析
- 正则化回归
- k-近邻
- 朴素贝叶斯
- 支持向量机
- 分类与回归树
您学习了每个算法要使用的包和函数。您还学习了如何将每个算法与提供算法评估和调整功能的 caret 包一起使用。
您可以使用这些算法作为模板,在您当前或下一个 R 机器学习项目中进行快速检查。
你的下一步
您是否尝试过这些食谱?
- 启动您的 R 交互式环境。
- 键入或复制粘贴上述食谱并进行尝试。
- 使用 R 中的内置帮助来了解有关所用函数的更多信息。
您有问题吗?在评论中提问,我将尽力回答。
嗨,Jason,
这是一个很好的概述。2 个小建议
1. 您可能希望添加一个部分/额外的帖子,说明如何轻松比较各种模型,以确定哪个是最好的。
2. 为了方便您的读者,您不妨附上一个包含所有调用的单个文件(而不是需要从每个小窗口中复制)。
非常感谢。— dbs
好建议,谢谢 David。
嗨,Jason,
感谢这篇概述文章。它确实对像 caret 这样多功能的包有所帮助。
我一直在寻找使用 caret 执行多类逻辑回归的方法。glm 仅适用于两类。有什么办法可以使用 caret 执行此操作吗?
谢谢 — Mustafa
暂时没有,抱歉。
亲爱的杰森,您好,
对于一个数据集,我使用线性模型比非线性模型获得了更好的结果。我想检查我是否可以使用核方法来改进结果,所以尝试了核逻辑和 ksvm,但是 AUC 变得更糟了!
如果您能给我任何解释,我将不胜感激?
此致,
有时线性方法是数据集的最佳方法,因为数据的底层结构是线性的。
测试多种方法,并使用效果最好的方法。
谢谢你。
所以,我只需要选择 RMSE 最低的算法。
是的。