与火车相比,R RF不平衡舱对看不见的数据的预测期望值低

时间:2019-01-23 11:53:06

标签: r random-forest

我建立了一个随机森林模型,用于预测客户是否在进行欺诈方面的操作。这是一个非常不平衡的大样本,有3%的欺诈案例,我想预测少数群体(欺诈)。

我平衡数据(各占50%)并构建RF。到目前为止,我有一个很好的模型,其整体准确度约为80%,正确预测的欺诈率为+ 70%。但是,当我在看不见的数据(测试)上尝试该模型时,尽管总体准确性良好,但与训练数据相比,负预测值(欺诈)确实很低(仅13%对+70%)。

我曾尝试增加样本量,增加平衡类别,调整RF参数等,但是没有一个效果很好,结果相似。我是否以某种方式过度拟合?我该怎么做才能改善欺诈检测(负预测值) 在看不见的数据上?

这是代码和结果:

set.seed(1234)

#train and test sets
model <- sample(nrow(dataset), 0.7 * nrow(dataset))
train <- dataset[model, ]
test <- dataset[-model, ]
    #Balance the data
balanced <- ovun.sample(custom21_type ~ ., data = train, method = "over",p = 0.5, seed = 1)$data

table(balanced$custom21_type)

   0    1 
5813 5861

#build the RF
rf5 = randomForest(custom21_type~.,ntree = 100,data = balanced,importance = TRUE,mtry=3,keep.inbag=TRUE)
rf5

Call:
 randomForest(formula = custom21_type ~ ., data = balanced, ntree = 100,      importance = TRUE, mtry = 3, keep.inbag = TRUE) 
               Type of random forest: classification
                     Number of trees: 100
No. of variables tried at each split: 3

        OOB estimate of  error rate: 21.47%
Confusion matrix:
     0    1 class.error
0 4713 1100   0.1892310
1 1406 4455   0.2398908

#test on unseen data
predicted <- predict(rf5, newdata=test)
confusionMatrix(predicted,test$custom21_type)
Confusion Matrix and Statistics

          Reference
Prediction     0     1
         0 59722   559
         1 13188  1938

               Accuracy : 0.8177          
                 95% CI : (0.8149, 0.8204)
    No Information Rate : 0.9669          
    P-Value [Acc > NIR] : 1               

                  Kappa : 0.1729          
 Mcnemar's Test P-Value : <2e-16          

            Sensitivity : 0.8191          
            Specificity : 0.7761          
         Pos Pred Value : 0.9907          
         Neg Pred Value : 0.1281          
             Prevalence : 0.9669          
         Detection Rate : 0.7920          
   Detection Prevalence : 0.7994          
      Balanced Accuracy : 0.7976          

       'Positive' Class : 0     

1 个答案:

答案 0 :(得分:2)

首先,我注意到您没有使用任何交叉验证。包括这将有助于增加用于训练的数据的变化,并有助于减少过度拟合。另外,我们将使用用户C.50代替randomForest,因为它更健壮,并且对第1类错误有更多的惩罚。

您可能要考虑的一件事实际上是火车数据中没有50-50的余额分配,而是增加了80-20。这样一来,欠平衡类不会被过度采样。我确信这会导致过度拟合,并且您的模型无法将新颖的示例归类为负面。

创建重新平衡的数据(p=.2)后运行此

library(caret)
#set up you cross validation
Control <- trainControl(
summaryFunction = twoClassSummary, #displays model score not confusion matrix
classProbs = TRUE, #important for the summaryFunction
verboseIter = TRUE, #tones down output
savePredictions = TRUE, 
method = "repeatedcv", #repeated cross validation, 10 folds, 3 times
repeats = 3,
number = 10,
allowParallel = TRUE

现在,我在注释中读到所有变量都是分类变量。这对于NaiveBayes算法是最佳的。但是,如果您有任何数值数据,则需要按照标准程序进行预处理(缩放,规格化和NA输入)。我们还将实施网格搜索过程。

如果您的数据都是分类的

model_nb <- train(
x = balanced[,-(which(colnames(balanced))%in% "custom21_type")],
y= balanced$custom21_type,
metric = "ROC",
method = "nb", 
trControl = Control,
tuneGrid = data.frame(fL=c(0,0.5,1.0), usekernel = TRUE, 
adjust=c(0,0.5,1.0)))

如果您希望使用RF方法(如果数据为数字,请确保进行预处理)

model_C5 <- train(
x = balanced[,-(which(colnames(balanced))%in% "custom21_type")],
y= balanced$custom21_type,
metric = "ROC",
method = "C5.0", 
trControl = Control,
tuneGrid = tuneGrid=expand.grid(.model = "tree",.trials = c(1,5,10), .winnow = F)))

现在我们预测

C5_predict<-predict(model_C5, test, type = "raw")
NB_predict<-predict(model_nb, test, type = "raw")
confusionMatrix(C5_predict,test$custom21_type)
confusionMatrix(nb_predict,test$custom21_type)

编辑:

尝试调整下面的费用矩阵。这种错误是对第二类错误的惩罚是第一类错误的两倍。

cost_mat <- matrix(c(0, 2, 1, 0), nrow = 2)
rownames(cost_mat) <- colnames(cost_mat) <- c("bad", "good")
cost_mod <- C5.0( x = balanced[,-(which(colnames(balanced))%in% 
"custom21_type")],
y= balanced$custom21_type,
             costs = cost_mat)
summary(cost_mod)

编辑2:

predicted <- predict(rf5, newdata=test, type="prob")

将为您提供每个预测的实际概率。默认截止值为.5。即高于.5的所有内容将归为0,低于0.5的所有内容将归为1。因此,您可以调整此临界值以帮助解决不平衡的类。

ifelse(predicted[,1] < .4, 1, predicted[,1])