【发布时间】:2019-11-03 13:02:38
【问题描述】:
在使用 predict.knn3 时,我遇到了一个有趣的数据争吵用例。我不知道我可以使用参数 type="class" 调用 predict 来获得预测的水平,这正是我所需要的。因此,我制定了一个有点复杂的解决方案,从每个predict() 的结果行中选择概率最大的级别。问题是由于names 函数不能以矩阵的“矢量化”形式工作,而只能与向量一起工作。
为了说明在发现 type="class" 参数之前和之后的用例:
rm(list = ls())
library(caret)
library(tidyverse)
library(dslabs)
data("tissue_gene_expression")
x <- tissue_gene_expression$x
y <- tissue_gene_expression$y
set.seed(1)
test_index <- createDataPartition(y, times = 1, p = 0.5, list = FALSE)
test_x <- x[test_index,]
test_y <- y[test_index]
train_x <- x[-test_index,]
train_y <- y[-test_index]
# fit the model, predict without type="class" and use sapply to build the y_hat levels
fit <- knn3(train_x, train_y, k = 1)
pred <- predict(fit, test_x)
y_hat <- sapply(1:nrow(pred), function(i) as.factor(names(pred[i,which.max(pred[i,])])))
# compare it to the solution using predict with type="class"
identical(y_hat, as.factor(predict(fit, test_x, type="class")))
[1] TRUE
为了说明问题,我可以执行以下操作,请参阅对命名数字元素的向量进行操作的 names 函数会产生所需的结果,而使用矩阵将失败并输出 NULL:
names(pred[1, which.max(pred[1,])])
[1] "cerebellum"
names(pred[1:2, which.max(pred[1:2,])])
NULL
假设在predict.knn3 函数中不知道这个方便的type="class";有没有更简单的方法使用 tidyverse 和 dplyr 来替换这个 sapply?或者任何其他更简单的方法来实现这个用例?
y_hat <- sapply(1:nrow(pred), function(i) as.factor(names(pred[i, which.max(pred[i,])])))
我正在追求类似以下的东西,但它不起作用:
as_tibble(predict(fit, test_x)) %>% mutate(y_hat=names(which.max(.[row_number(),])))
【问题讨论】: