R中支持向量机和朴素贝叶斯分类器的可变重要性
Posted
技术标签:
【中文标题】R中支持向量机和朴素贝叶斯分类器的可变重要性【英文标题】:Variable importance for support vector machine and naive Bayes classifiers in R 【发布时间】:2016-08-19 02:57:33 【问题描述】:我正在用 R 语言在癌症数据集上构建预测分类器。 我正在使用随机森林、支持向量机和朴素贝叶斯分类器。我无法计算 SVM 和 NB 模型的变量重要性
我最终收到以下错误。
UseMethod("varImp") 中的错误: 没有适用于“c('svm.formula', 'svm')”类对象的“varImp”方法
如果有人可以帮助我,我将不胜感激。
【问题讨论】:
欢迎来到 ***。请阅读 (1) how do I ask a good question, (2) How to create a MCVE 以及 (3) how to provide a minimal reproducible example in R。然后相应地编辑和改进您的问题。即,提供重现错误的代码,例如通过使用内置的示例数据集。 【参考方案1】:我创建了一个循环,该循环一次迭代地删除一个预测变量,并在数据框中捕获从混淆矩阵派生的各种性能度量。这不应该是一个万能的解决方案,我没有时间,但应用修改应该不难。
确保预测变量位于数据框中的最后。
我主要需要模型中的特异性值,通过一次删除一个预测变量,我可以评估每个预测变量的重要性,即通过删除一个预测变量,模型的最小特异性(小于预测变量编号 i) 表示预测变量最重要。您需要知道您将重视哪些指标。
您还可以在内部添加另一个 for 循环以在内核之间进行更改,即线性、多项式、径向,但您可能必须考虑其他参数,例如伽玛。用你的目标变量改变“label_fake”,用你的数据框改变 df_final。
SVM 版本:
set.seed(1)
varimp_df <- NULL # df with results
ptm1 <- proc.time() # Start the clock!
for(i in 1:(ncol(df_final)-1)) # the last var is the dep var, hence the -1
smp_size <- floor(0.70 * nrow(df_final)) # 70/30 split
train_ind <- sample(seq_len(nrow(df_final)), size = smp_size)
training <- df_final[train_ind, -c(i)] # receives all the df less 1 var
testing <- df_final[-train_ind, -c(i)]
tune.out.linear <- tune(svm, label_fake ~ .,
data = training,
kernel = "linear",
ranges = list(cost =10^seq(1, 3, by = 0.5))) # you can choose any range you see fit
svm.linear <- svm(label_fake ~ .,
kernel = "linear",
data = training,
cost = tune.out.linear[["best.parameters"]][["cost"]])
train.pred.linear <- predict(svm.linear, testing)
testing_y <- as.factor(testing$label_fake)
conf.matrix.svm.linear <- caret::confusionMatrix(train.pred.linear, testing_y)
varimp_df <- rbind(varimp_df,data.frame(
var_no=i,
variable=colnames(df_final[,i]),
cost_param=tune.out.linear[["best.parameters"]][["cost"]],
accuracy=conf.matrix.svm.linear[["overall"]][["Accuracy"]],
kappa=conf.matrix.svm.linear[["overall"]][["Kappa"]],
sensitivity=conf.matrix.svm.linear[["byClass"]][["Sensitivity"]],
specificity=conf.matrix.svm.linear[["byClass"]][["Specificity"]]))
runtime1 <- as.data.frame(t(data.matrix(proc.time() - ptm1)))$elapsed # time for running this loop
runtime1 # divide by 60 and you get minutes, /3600 you get hours
朴素贝叶斯版本:
varimp_nb_df <- NULL
ptm1 <- proc.time() # Start the clock!
for(i in 1:(ncol(df_final)-1))
smp_size <- floor(0.70 * nrow(df_final))
train_ind <- sample(seq_len(nrow(df_final)), size = smp_size)
training <- df_final[train_ind, -c(i)]
testing <- df_final[-train_ind, -c(i)]
x = training[, names(training) != "label_fake"]
y = training$label_fake
model_nb_var = train(x,y,'nb', trControl=ctrl)
predict_nb_var <- predict(model_nb_var, newdata = testing )
confusion_matrix_nb_1 <- caret::confusionMatrix(predict_nb_var, testing$label_fake)
varimp_nb_df <- rbind(varimp_nb_df, data.frame(
var_no=i,
variable=colnames(df_final[,i]),
accuracy=confusion_matrix_nb_1[["overall"]][["Accuracy"]],
kappa=confusion_matrix_nb_1[["overall"]][["Kappa"]],
sensitivity=confusion_matrix_nb_1[["byClass"]][["Sensitivity"]],
specificity=confusion_matrix_nb_1[["byClass"]][["Specificity"]]))
runtime1 <- as.data.frame(t(data.matrix(proc.time() - ptm1)))$elapsed # time for running this loop
runtime1 # divide by 60 and you get minutes, /3600 you get hours
玩得开心!
【讨论】:
【参考方案2】:如果你使用R,变量重要性可以用rminer包中的Importance方法计算。这是我的示例代码:
library(rminer)
M <- fit(y~., data=train, model="svm", kpar=list(sigma=0.10), C=2)
svm.imp <- Importance(M, data=train)
详细请参考以下链接https://cran.r-project.org/web/packages/rminer/rminer.pdf
【讨论】:
【参考方案3】:给定
library(e1071)
model <- svm(Species ~ ., data = iris)
class(model)
# [1] "svm.formula" "svm"
library(caret)
varImp(model)
# Error in UseMethod("varImp") :
# no applicable method for 'varImp' applied to an object of class "c('svm.formula', 'svm')"
methods(varImp)
# [1] varImp.bagEarth varImp.bagFDA varImp.C5.0* varImp.classbagg*
# [5] varImp.cubist* varImp.dsa* varImp.earth* varImp.fda*
# [9] varImp.gafs* varImp.gam* varImp.gbm* varImp.glm*
# [13] varImp.glmnet* varImp.JRip* varImp.lm* varImp.multinom*
# [17] varImp.mvr* varImp.nnet* varImp.pamrtrained* varImp.PART*
# [21] varImp.plsda varImp.randomForest* varImp.RandomForest* varImp.regbagg*
# [25] varImp.rfe* varImp.rpart* varImp.RRF* varImp.safs*
# [29] varImp.sbf* varImp.train*
methods(varImp)
中没有函数varImp.svm
,因此报错。您可能也想看看this post on Cross Validated。
【讨论】:
以上是关于R中支持向量机和朴素贝叶斯分类器的可变重要性的主要内容,如果未能解决你的问题,请参考以下文章