如何在 R 中执行 k 折 CV?
How to perform k-fold CV in R?
我有一个 Python 代码,可以很好地对数据集执行 k 折 CV。我的 Python 代码如下所示:
import pandas
import numpy as np
from sklearn.model_selection import KFold
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVR
from sklearn.utils import shuffle
# Load the dataset.
dataset = pandas.read_csv('values.csv')
# Preprocessing the dataset.
X = dataset.iloc[:, 0:8]
Y = dataset.iloc[:, 8] # The class value is the last column and is called Outcome.
# Scale all values to 0,1.
scaler = MinMaxScaler(feature_range=(0, 1))
X = scaler.fit_transform(X)
# 3-fold CV computation.
scores = []
svr_rbf = SVR(kernel='rbf', gamma='auto')
cv = KFold(n_splits=3, random_state=42, shuffle=False)
for train_index, test_index in cv.split(X):
X_train, X_test = X[train_index], X[test_index]
Y_train, Y_test = Y[train_index], Y[test_index]
svr_rbf.fit(X_train, Y_train)
scores.append(svr_rbf.score(X_test, Y_test))
现在,我想在 R 中重写同样的东西,我试过这样做:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("values.csv", col_names=TRUE)
results <- train(Outcome~.,
data=dataset,
method="smvLinear",
trControl=trainControl(
method="cv",
number=3,
savePredictions=TRUE,
verboseIter=TRUE
))
print(results)
print(results$pred)
我的数据与此类似:https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.data
除了这个有 12 个属性,第 13 列是 class,在我的例子中有 8 个属性,第 9 个是 class。但是,就价值而言,它是相似的。
现在,我可以看到正在打印的结果,但是有几件事我不清楚。
1) 在我的 Python 代码中,我对值进行了这种缩放,我如何在 R 中做到这一点?
2) 我已经将 SVR 与 rbf
内核一起使用,如何在 R 中将 SVR 与该内核一起使用而不是 SMV?
3) 此外,在 Python 版本中,我使用 random_state=42
(只是一个随机数)来生成折叠的拆分,因此它使用不同的折叠。但它在不同的执行过程中是一致的。在 R 中如何做到这一点?
4) 最后,在 Python 中,我在每次折叠的 for 循环中进行训练。我在 R 中也需要这样的东西,因为在每次折叠之后,我想执行一些其他统计和计算。如何在 R 中做到这一点?
5) 我应该坚持使用 caret
还是使用 mlr
包? mlr
也做 k 折 CV 吗?如果是怎么办?
编辑:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
print(dataset)
X = dataset[, 1:8]
print(X)
Y = dataset$X9
set.seed(88)
nfolds <- 3
cvIndex <- createFolds(Y, nfolds, returnTrain = T)
fit.control <- trainControl(method="cv",
index=cvIndex,
number=nfolds,
classProbs=TRUE,
savePredictions=TRUE,
verboseIter=TRUE,
summaryFunction=twoClassSummary,
allowParallel=FALSE)
rfCaret <- caret::train(X, Y, method = "svmLinear", trControl = fit.control)
print(rfCaret)
1) caret::train
函数有一个 preProcess 参数,允许您选择预处理。有关详细信息,请参阅 ?caret::train
。
2) caret
有 svmRadial
个可用。您可以在 caret/train-models-by-tag.
查看示例和所有可用算法
3) 修正随机种子 set.seed(123)
以保持一致性。您可以访问训练对象中的训练折叠(此处 results$trainingData
)。
4) 不要循环,直接通过你的火车对象访问你的折叠并在需要时计算你的统计数据(参见 results$resample
)
5) mlr
也有cross-validation,就看你喜欢什么口味了
查看 caret
包中的 createFolds
固定折叠。
这里有一些代码,您可以修改这些代码以适合您的特定建模案例;此示例将构建一个随机森林模型,但您可以将模型切换为 SVM。如果你按照包指南有一个 link (为了方便复制在这里:http://topepo.github.io/caret/train-models-by-tag.html#support-vector-machines) - 第 7.0.47 节列出了所有可用的 SVM 模型及其 parameters.Note 你可能需要安装一些其他软件包,例如 kernlab
,以使用特定模型。
有一个名为 rngtools
的包应该允许您创建跨多个内核的可重现模型(并行处理),但如果您想确定,那么单核可能是我的最佳方式经验。
folds <- 3
set.seed(42)
cvIndex <- createFolds(your_data, folds, returnTrain = T)
fit.control <- trainControl(method = "cv",
index = cvIndex,
number = folds,
classProbs = TRUE,
summaryFunction = twoClassSummary,
allowParallel = FALSE)
search.grid <- expand.grid(.mtry = c(seq.int(1:sqrt(length(your_data)))+1))
rfCaret <- train(your_data_x, your_data_y, method = "rf",
metric = 'ROC', ntree = 500,
trControl = fit.control, tuneGrid = search.grid,
)
根据我的经验,插入符号非常适合涵盖几乎所有基础。如果您还想预处理数据(例如中心、比例)——那么您需要函数 preProcess
——同样,如果您键入 ?train,插入符号包中的详细信息——但例如您需要
preProcess(yourData, method = c("center", "scale"))
Caret 很聪明,因为它了解它是否采用了预处理输入,并将相同的缩放比例应用于您的测试数据集。
编辑 - 附加:未使用的参数问题
回答关于未使用参数的后续问题 - 这可能是因为您使用的是随机森林参数 mtry。
这是一个简单 SVM 的版本:
folds <- 3
set.seed(42)
cvIndex <- createFolds(dataset$Outcome, folds, returnTrain = T)
fit.control <- trainControl(method = "cv",
index = cvIndex,
number = folds,
classProbs = TRUE,
summaryFunction = twoClassSummary,
allowParallel = FALSE)
SVMCaret <- train(Outcome ~ ., data = dataset, method = "svmLinear",
metric = 'ROC',
trControl = fit.control)
您不需要调整网格;插入符将生成一个随机的。当然,如果你想测试特定的成本值,那么你自己创建一个,就像我为 randomForests 的 .mtry 参数所做的一样。
我有一个 Python 代码,可以很好地对数据集执行 k 折 CV。我的 Python 代码如下所示:
import pandas
import numpy as np
from sklearn.model_selection import KFold
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import SVR
from sklearn.utils import shuffle
# Load the dataset.
dataset = pandas.read_csv('values.csv')
# Preprocessing the dataset.
X = dataset.iloc[:, 0:8]
Y = dataset.iloc[:, 8] # The class value is the last column and is called Outcome.
# Scale all values to 0,1.
scaler = MinMaxScaler(feature_range=(0, 1))
X = scaler.fit_transform(X)
# 3-fold CV computation.
scores = []
svr_rbf = SVR(kernel='rbf', gamma='auto')
cv = KFold(n_splits=3, random_state=42, shuffle=False)
for train_index, test_index in cv.split(X):
X_train, X_test = X[train_index], X[test_index]
Y_train, Y_test = Y[train_index], Y[test_index]
svr_rbf.fit(X_train, Y_train)
scores.append(svr_rbf.score(X_test, Y_test))
现在,我想在 R 中重写同样的东西,我试过这样做:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("values.csv", col_names=TRUE)
results <- train(Outcome~.,
data=dataset,
method="smvLinear",
trControl=trainControl(
method="cv",
number=3,
savePredictions=TRUE,
verboseIter=TRUE
))
print(results)
print(results$pred)
我的数据与此类似:https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.data 除了这个有 12 个属性,第 13 列是 class,在我的例子中有 8 个属性,第 9 个是 class。但是,就价值而言,它是相似的。
现在,我可以看到正在打印的结果,但是有几件事我不清楚。
1) 在我的 Python 代码中,我对值进行了这种缩放,我如何在 R 中做到这一点?
2) 我已经将 SVR 与 rbf
内核一起使用,如何在 R 中将 SVR 与该内核一起使用而不是 SMV?
3) 此外,在 Python 版本中,我使用 random_state=42
(只是一个随机数)来生成折叠的拆分,因此它使用不同的折叠。但它在不同的执行过程中是一致的。在 R 中如何做到这一点?
4) 最后,在 Python 中,我在每次折叠的 for 循环中进行训练。我在 R 中也需要这样的东西,因为在每次折叠之后,我想执行一些其他统计和计算。如何在 R 中做到这一点?
5) 我应该坚持使用 caret
还是使用 mlr
包? mlr
也做 k 折 CV 吗?如果是怎么办?
编辑:
library(base)
library(caret)
library(tidyverse)
dataset <- read_csv("https://gist.githubusercontent.com/dmpe/bfe07a29c7fc1e3a70d0522956d8e4a9/raw/7ea71f7432302bb78e58348fede926142ade6992/pima-indians-diabetes.csv", col_names=FALSE)
print(dataset)
X = dataset[, 1:8]
print(X)
Y = dataset$X9
set.seed(88)
nfolds <- 3
cvIndex <- createFolds(Y, nfolds, returnTrain = T)
fit.control <- trainControl(method="cv",
index=cvIndex,
number=nfolds,
classProbs=TRUE,
savePredictions=TRUE,
verboseIter=TRUE,
summaryFunction=twoClassSummary,
allowParallel=FALSE)
rfCaret <- caret::train(X, Y, method = "svmLinear", trControl = fit.control)
print(rfCaret)
1) caret::train
函数有一个 preProcess 参数,允许您选择预处理。有关详细信息,请参阅 ?caret::train
。
2) caret
有 svmRadial
个可用。您可以在 caret/train-models-by-tag.
3) 修正随机种子 set.seed(123)
以保持一致性。您可以访问训练对象中的训练折叠(此处 results$trainingData
)。
4) 不要循环,直接通过你的火车对象访问你的折叠并在需要时计算你的统计数据(参见 results$resample
)
5) mlr
也有cross-validation,就看你喜欢什么口味了
查看 caret
包中的 createFolds
固定折叠。
这里有一些代码,您可以修改这些代码以适合您的特定建模案例;此示例将构建一个随机森林模型,但您可以将模型切换为 SVM。如果你按照包指南有一个 link (为了方便复制在这里:http://topepo.github.io/caret/train-models-by-tag.html#support-vector-machines) - 第 7.0.47 节列出了所有可用的 SVM 模型及其 parameters.Note 你可能需要安装一些其他软件包,例如 kernlab
,以使用特定模型。
有一个名为 rngtools
的包应该允许您创建跨多个内核的可重现模型(并行处理),但如果您想确定,那么单核可能是我的最佳方式经验。
folds <- 3
set.seed(42)
cvIndex <- createFolds(your_data, folds, returnTrain = T)
fit.control <- trainControl(method = "cv",
index = cvIndex,
number = folds,
classProbs = TRUE,
summaryFunction = twoClassSummary,
allowParallel = FALSE)
search.grid <- expand.grid(.mtry = c(seq.int(1:sqrt(length(your_data)))+1))
rfCaret <- train(your_data_x, your_data_y, method = "rf",
metric = 'ROC', ntree = 500,
trControl = fit.control, tuneGrid = search.grid,
)
根据我的经验,插入符号非常适合涵盖几乎所有基础。如果您还想预处理数据(例如中心、比例)——那么您需要函数 preProcess
——同样,如果您键入 ?train,插入符号包中的详细信息——但例如您需要
preProcess(yourData, method = c("center", "scale"))
Caret 很聪明,因为它了解它是否采用了预处理输入,并将相同的缩放比例应用于您的测试数据集。
编辑 - 附加:未使用的参数问题 回答关于未使用参数的后续问题 - 这可能是因为您使用的是随机森林参数 mtry。
这是一个简单 SVM 的版本:
folds <- 3
set.seed(42)
cvIndex <- createFolds(dataset$Outcome, folds, returnTrain = T)
fit.control <- trainControl(method = "cv",
index = cvIndex,
number = folds,
classProbs = TRUE,
summaryFunction = twoClassSummary,
allowParallel = FALSE)
SVMCaret <- train(Outcome ~ ., data = dataset, method = "svmLinear",
metric = 'ROC',
trControl = fit.control)
您不需要调整网格;插入符将生成一个随机的。当然,如果你想测试特定的成本值,那么你自己创建一个,就像我为 randomForests 的 .mtry 参数所做的一样。