我的基本问题是:置换特征重要性可以用来识别过拟合吗?
当您遇到具有平衡类的二元分类问题(即 70 x 是,70 x 否)时,当没有任何预测变量与分类任务相关时,您会期望 50% 的准确度对吗?
我们训练了一个准确率为 95% 的 MLP,这表明一些预测变量与二元分类任务相关。我们使用 IML R 包计算了排列重要性,并且仅对一个相关预测器获得了 0.08 的排列重要性得分(方法差异,因此排列误差 - 基线误差)。所有其他预测变量的重要性得分为 0(当预测变量被打乱时没有变化)
这是否意味着我们过度拟合?唯一重要的预测变量的排列导致准确度下降 8%,我们仍然保持 87% 的准确度(95% 的基线准确度 - 该特征的 8%)。
编辑 - 拆分以验证过拟合:
在一些有用的评论建议我需要拆分数据以确保我做的过度拟合之后。
我使用了 100 个观察值(数据的 72.5%)作为分组 5 倍 CV 的训练数据,对于 5 的超参数大小(单个隐藏层中的 5 个神经元),我的准确率为 98.04%。
基于最终caret模型对未见过的左侧 38 个观测值(数据的 27.5%)的预测导致 100% 的准确度。
然而,我的排列特征重要性的总和(见下文)仍然只有 6.2%。3 预测变量被认为是相关的(它们的排列导致误差增加)。然而,我不清楚如何解释这个结果:基线准确度 98.04% - 6.2% 置换相关特征的误差增加 = 当所有相关特征都被置换时,仍然是 91.84%。
这是我的部分代码,很抱歉,但我不能给出一个可重现的例子,因为我不拥有我正在使用的数据。
# preparation for the contrasting dataset
df_test <- subset(df, Class == "Control" | Class == classes[i])
df_test$Class <- factor(df_test$Class)
preproc <- select(df_test,-ID,-Class) %>% caret::preProcess(., method = c("center","scale","zv"), verbose = T)
df.contrast <- predict(preproc, df_test)
# Splitting: testing for overfit splitting of the contrast ds
partition = 0.725
train_ids = sample(unique(df.contrast$ID), size=partition*length(unique(df.contrast$ID)))
df.train = df.contrast %>% filter(ID %in% train_ids)
df.test = df.contrast %>% filter(!ID %in% train_ids)
# train the model and evaluate on test set
model <- tuneModel.contrast(df.train)
x.test <- select(df.test,-ID,-Class)
predictions.testset = caret::predict.train(model, newdata = x.test)
print(confusionMatrix(predictions.testset, df.test$Class))
permutation_vip.perclass(df.contrast,classes[i],levels(df.contrast$Class),model)
这里是用来训练模型的函数
allSummary <- function(data, lev = NULL, model = NULL){
a1 <- defaultSummary(data, lev, model)
b1 <- twoClassSummary(data, lev, model)
c1 <- prSummary(data, lev, model)
out <- c(a1, b1, c1)
out
# return(out)
}
########################## Hyperparametertuning NeuralNet (MLP) ############################
tuneModel.contrast <- function(contrast_df){
############## Caret Preparation ##############
set.seed(1337)
k.folds = 5
contrast_df.folds <- groupKFold(contrast_df$ID, k = k.folds)
contrast_df.control <- trainControl( # k Folds grouped by subject cross validation, repeated 3 times
method = "repeatedcv",
number = k.folds,
repeats = 3,
index = contrast_df.folds,
savePredictions = T,
summaryFunction = allSummary,
classProbs = T
)
contrast_df <- select(contrast_df, -"ID")
contrast_df.tunegrid <- expand.grid(.size=c(1:(ncol(contrast_df)-1)))
metric <- "Accuracy"
# metric <- "AUC"
tic("MLP Contrasting, Hyperparameter Startegy 1: Grid Search")
mlp <- train(Class~.,
data=contrast_df,
method="mlp",
metric=metric,
tuneGrid=contrast_df.tunegrid,
trControl=contrast_df.control
# , preProc=c("center", "scale","zv")
)
toc()
print(mlp)
# M <- mlp$results
# print(sort(apply(M,2,sd), decreasing = T))
return(mlp)
}
