Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R KNN用于不平衡数据集,并添加SMOTE以提高性能,但结果最差_R_Knn_Roc_Smote - Fatal编程技术网

R KNN用于不平衡数据集,并添加SMOTE以提高性能,但结果最差

R KNN用于不平衡数据集,并添加SMOTE以提高性能,但结果最差,r,knn,roc,smote,R,Knn,Roc,Smote,我有一个称为yeast4的不平衡数据集。记录分为两类目标“积极”和“消极”。 正类只占总比例的3%。 我使用了kNN算法进行分类,我没有指定k,但我对训练数据使用了5倍交叉验证。我发现:auc_knn_none=0.7062473。 我很有兴趣添加一个过采样算法来提高模型的质量。 所以我使用了SMOTE算法,也没有指定k ok kNN,我对训练数据使用了5倍交叉验证。 但这一次,我发现:auc_knn_smote=0.56676。 通常auc_knn_smote必须高于auc_knn_none

我有一个称为yeast4的不平衡数据集。记录分为两类目标“积极”和“消极”。 正类只占总比例的3%。 我使用了kNN算法进行分类,我没有指定k,但我对训练数据使用了5倍交叉验证。我发现:auc_knn_none=0.7062473。 我很有兴趣添加一个过采样算法来提高模型的质量。 所以我使用了SMOTE算法,也没有指定k ok kNN,我对训练数据使用了5倍交叉验证。 但这一次,我发现:auc_knn_smote=0.56676。 通常auc_knn_smote必须高于auc_knn_none 所以有一件事我和荣不知道是哪里的问题。 这是我的密码:

library(imbalance)
data(yeast4)
Data <- yeast4
Data$Mcg <- as.numeric(as.character(Data$Mcg))
Data$Gvh <- as.numeric(as.character(Data$Gvh))
Data$Alm <- as.numeric(as.character(Data$Alm))
Data$Mit <- as.numeric(as.character(Data$Mit))  
Data$Erl <- as.numeric(as.character(Data$Erl))
Data$Pox <- as.numeric(as.character(Data$Pox))
Data$Vac <- as.numeric(as.character(Data$Vac))
Data$Nuc <- as.numeric(as.character(Data$Nuc))
U <- data.frame(Data[,-9])
U <- scale(U,center = TRUE ,scale=TRUE)
U <- data.frame(U)
q <- as.factor(unlist(Data$Class))
Q <- vector()
for(i in 1: nrow(Data))
{
  if(substr(q[i],1,1)=="n")
  {
    Q <- c(Q,0)
  }
  else{
    Q <- c(Q,1)
  }
}
Q <- as.factor(Q)

库(不平衡)
数据(年份4)

数据我认为你的方法没有错。需要澄清的是结果解释

如您所述,在初始不平衡数据集上,您得到的AUC分数为0.7062473。然后应用SMOTE数据平衡算法,AUC得分为0.56676。在这两种情况下,均采用5倍交叉验证

解释

  • 最初的AUC分数较高,因为它偏爱比例较高的班级
  • 为了平衡数据集,采用了过采样技术。让我们简要了解过采样的工作原理。它引入了人工数据点。这会引入偏差,因为新数据点是从旧数据点生成的,所以它们不会给数据集带来太多差异。在大多数情况下,它们仅与原始版本略有不同
  • 从您的Q中看,列车测试拆分方面不清楚。假设数据在列车测试拆分之前取样过多,则会引入偏差。这里需要注意的是,您应该在平衡训练集之前执行拆分。您希望测试集尽可能不带偏见,以便对模型的性能进行客观评估。如果在分割数据集之前执行了平衡,那么模型可能在训练期间通过生成的数据点看到了测试集的信息
可能的解决方案

  • 重点是消除过采样带来的偏差。一种方法是对数据进行重采样
  • 请记住,您的重点必须是实现低偏差低方差模型。这将有助于改进绩效评估指标

谢谢您的回复。我刚才看到你的答案,我想我的Q不清楚。Q是向量,包含我称之为Data的数据集(yeast4)的目标,目标是Data$Class,Data$Class是yeast4的第9列。你数着没有目标的年份。我用U分割了我的训练测试,我在需要时添加目标(对于我称为train的训练集),所以测试是数据。frame(U[s,])没有目标列。
library(ROCR) 
library(pROC)
library(caret)
library(ROSE)
library(DMwR)
library(nnet)
AUC_KNN_SMOTE <- function(U,Q,k,M){
  folds <- createFolds(Q, k)
  AUC <- vector()
  W <- vector()
  for( i in 1:k){
    s <- data.frame(folds[i])[,1]
    TRAIN <- data.frame(U[-s,])
    TEST <- data.frame(U[s,])
    TRAIN$Class <- Q[-s]
    TRAIN.smote <- SMOTE(Class~.,data = TRAIN
                         ,perc.over = 100,perc.under = 200)
    trControl <- trainControl(method  = "cv",
                              number  = 5,
                              classProbs = TRUE,
                              summaryFunction = twoClassSummary)
    fit <- train(make.names(Class) ~ .,
                 method     = "knn",
                 tuneGrid   = expand.grid(k = 1:M),
                 trControl  = trControl,
                 metric     = "ROC",
                 data       = TRAIN.smote)
    W <- c(W,fit[["results"]][,2])
    W <- matrix(W,nrow=M,ncol = i)
    J <- which.is.max(W[,i])
    mod <- class::knn(cl = TRAIN.smote$Class,
                      test = TEST,
                      train = TRAIN.smote[,-9],
                      k = J,
                      prob = TRUE)
    X <-  roc(Q[s],attributes(mod)$prob,quiet = TRUE)
    AUC <- c(AUC, as.numeric(X$auc))
  }
  return(mean(AUC))
}
b <- 0
for(i in 1:1000)
{
  m <- AUC_KNN_SMOTE(U,Q,k=5,M=100)+b
  b <- m 
}
auc_knn_smote <- m/1000
auc_knn_smote=0.56676