在 `bwplot()` 中对 `caret` 模型进行排序
sort `caret` models in `bwplot()`
我正在绘制用 caret
训练的年度模型重采样的准确度分数的箱线图。
这些模型以它们所指的年份命名:2000、2001、2002、...、2010。
我希望模型以基于年份(即模型名称)的升序出现在箱线图中。
基于以下代码的重采样总结
fit.year.res <- resamples(fit.year)
summary(fit.year.res)
看起来像这样:
但是,箱形图中的不同年度模型未排序:
scales <- list(x=list(relation="free"), y=list(relation="free"))
bwplot(fit.year.res, scales=scales)
我试过将 resamples fit.year.res$models
的模型元素转换为 factor from character,但并没有什么区别。
我不知道使用 caret 包中的 bwplot
方法的简单解决方案。也许有一个,但我缺乏格子技能。我建议使用 ggplot2 手动绘制箱线图。这样你就能更好地控制最终情节。
由于您没有 post 带有数据的示例,我将使用 ?caret:::bwplot.resamples
中的示例之一
library(caret)
library(party)
library(RWeka)
load(url("http://topepo.github.io/caret/exampleModels.RData"))
resamps <- resamples(list(CART = rpartFit,
CondInfTree = ctreeFit,
MARS = earthFit))
bwplot(resamps,
metric = "RMSE")
产生:
要使用 ggplot 手动绘制绘图,您需要进行一些数据操作:
library(tidyverse)
resamps$values %>% #extract the values
select(1, ends_with("RMSE")) %>% #select the first column and all columns with a name ending with "RMSE"
gather(model, RMSE, -1) %>% #convert to long table
mutate(model = sub("~RMSE", "", model)) %>% #leave just the model names
ggplot()+ #call ggplot
geom_boxplot(aes(x = RMSE, y = model)) -> p1 #and plot the box plot
p1
要在 y 轴上设置特定顺序:
p1 +
scale_y_discrete(limits = c("MARS", "CART", "CondInfTree"))
如果你更喜欢格子
library(lattice)
resamps$values %>%
select(1, ends_with("RMSE")) %>%
gather(model, RMSE, -1) %>%
mutate(model = sub("~RMSE", "", model)) %>%
{bwplot(model ~ RMSE, data = .)}
更改顺序更改模型级别(此方法也适用于 ggplot2):
resamps$values %>%
select(1, ends_with("RMSE")) %>%
gather(model, RMSE, -1) %>%
mutate(model = sub("~RMSE", "", model),
model = factor(model, levels = c("MARS", "CART", "CondInfTree"))) %>%
{bwplot(model ~ RMSE, data = .)}
函数 bwplot.resamples
用于生成此图,如果您查看 underlying code,变量将根据其在感兴趣指标下的平均表现进行因式分解。
下面是进行因式分解的相关代码:
bwplot.resamples <- function (x, data = NULL, models = x$models, metric = x$metric, ...)
{
....
avPerf <- ddply(subset(plotData, Metric == metric[1]),
.(Model),
function(x) c(Median = median(x$value, na.rm = TRUE)))
avPerf <- avPerf[order(avPerf$Median),]
......
}
我想你需要做的是手动制作情节:
data(BloodBrain)
gbmFit <- train(bbbDescr[,-3], logBBB,"gbm",tuneLength=6,
trControl = trainControl(method = "cv"),verbose=FALSE)
glmnetFit <- train(bbbDescr[,-3], logBBB,"glmnet",tuneLength=6,
trControl = trainControl(method = "cv"))
rfFit <- train(bbbDescr[,-3], logBBB,"rf",tuneLength=6,
trControl = trainControl(method = "cv"))
knnFit <- train(bbbDescr[,-3], logBBB,"knn",tuneLength=6,
trControl = trainControl(method = "cv"))
resamps <- resamples(list(gbm = gbmFit,glmnet=glmnetFit,knn=knnFit,rf=rfFit))
如果你画图,你可以看到它们是根据中位数(实心点)排序的:
bwplot(resamps,metric="MAE")
您可以访问 $values 下的值并创建一个函数来绘制它,如下所示:
plotMet = function(obj,metric,var_order){
mat = obj$values
mat = mat[,grep(metric,colnames(mat))]
colnames(mat) = gsub("[~][^ ]*","",colnames(mat))
boxplot(mat[,var_order],horizontal=TRUE,las=2,xlab=metric)
}
plotMet(resamps,"MAE",c("rf","knn","gbm","glmnet"))
用数字命名你的模型也不是一个好主意..试试像 model_2000, model_2001 等等
我正在绘制用 caret
训练的年度模型重采样的准确度分数的箱线图。
这些模型以它们所指的年份命名:2000、2001、2002、...、2010。
我希望模型以基于年份(即模型名称)的升序出现在箱线图中。
基于以下代码的重采样总结
fit.year.res <- resamples(fit.year)
summary(fit.year.res)
看起来像这样:
但是,箱形图中的不同年度模型未排序:
scales <- list(x=list(relation="free"), y=list(relation="free"))
bwplot(fit.year.res, scales=scales)
我试过将 resamples fit.year.res$models
的模型元素转换为 factor from character,但并没有什么区别。
我不知道使用 caret 包中的 bwplot
方法的简单解决方案。也许有一个,但我缺乏格子技能。我建议使用 ggplot2 手动绘制箱线图。这样你就能更好地控制最终情节。
由于您没有 post 带有数据的示例,我将使用 ?caret:::bwplot.resamples
library(caret)
library(party)
library(RWeka)
load(url("http://topepo.github.io/caret/exampleModels.RData"))
resamps <- resamples(list(CART = rpartFit,
CondInfTree = ctreeFit,
MARS = earthFit))
bwplot(resamps,
metric = "RMSE")
产生:
要使用 ggplot 手动绘制绘图,您需要进行一些数据操作:
library(tidyverse)
resamps$values %>% #extract the values
select(1, ends_with("RMSE")) %>% #select the first column and all columns with a name ending with "RMSE"
gather(model, RMSE, -1) %>% #convert to long table
mutate(model = sub("~RMSE", "", model)) %>% #leave just the model names
ggplot()+ #call ggplot
geom_boxplot(aes(x = RMSE, y = model)) -> p1 #and plot the box plot
p1
要在 y 轴上设置特定顺序:
p1 +
scale_y_discrete(limits = c("MARS", "CART", "CondInfTree"))
如果你更喜欢格子
library(lattice)
resamps$values %>%
select(1, ends_with("RMSE")) %>%
gather(model, RMSE, -1) %>%
mutate(model = sub("~RMSE", "", model)) %>%
{bwplot(model ~ RMSE, data = .)}
更改顺序更改模型级别(此方法也适用于 ggplot2):
resamps$values %>%
select(1, ends_with("RMSE")) %>%
gather(model, RMSE, -1) %>%
mutate(model = sub("~RMSE", "", model),
model = factor(model, levels = c("MARS", "CART", "CondInfTree"))) %>%
{bwplot(model ~ RMSE, data = .)}
函数 bwplot.resamples
用于生成此图,如果您查看 underlying code,变量将根据其在感兴趣指标下的平均表现进行因式分解。
下面是进行因式分解的相关代码:
bwplot.resamples <- function (x, data = NULL, models = x$models, metric = x$metric, ...)
{
....
avPerf <- ddply(subset(plotData, Metric == metric[1]),
.(Model),
function(x) c(Median = median(x$value, na.rm = TRUE)))
avPerf <- avPerf[order(avPerf$Median),]
......
}
我想你需要做的是手动制作情节:
data(BloodBrain)
gbmFit <- train(bbbDescr[,-3], logBBB,"gbm",tuneLength=6,
trControl = trainControl(method = "cv"),verbose=FALSE)
glmnetFit <- train(bbbDescr[,-3], logBBB,"glmnet",tuneLength=6,
trControl = trainControl(method = "cv"))
rfFit <- train(bbbDescr[,-3], logBBB,"rf",tuneLength=6,
trControl = trainControl(method = "cv"))
knnFit <- train(bbbDescr[,-3], logBBB,"knn",tuneLength=6,
trControl = trainControl(method = "cv"))
resamps <- resamples(list(gbm = gbmFit,glmnet=glmnetFit,knn=knnFit,rf=rfFit))
如果你画图,你可以看到它们是根据中位数(实心点)排序的:
bwplot(resamps,metric="MAE")
您可以访问 $values 下的值并创建一个函数来绘制它,如下所示:
plotMet = function(obj,metric,var_order){
mat = obj$values
mat = mat[,grep(metric,colnames(mat))]
colnames(mat) = gsub("[~][^ ]*","",colnames(mat))
boxplot(mat[,var_order],horizontal=TRUE,las=2,xlab=metric)
}
plotMet(resamps,"MAE",c("rf","knn","gbm","glmnet"))
用数字命名你的模型也不是一个好主意..试试像 model_2000, model_2001 等等