使用样本中的数据分配不正确



我有2个问题。

  1. 当我尝试将数据分为测试和火车集时,使用sample.split如下所示,采样是不清楚的。我的意思是,数据d的长度为392,因此,4:1的分区应显示0.8*392 = 313.6即313或314行,但所示的长度为304。缺少?

    require(caTools)
    set.seed(101)
    samplev = sample.split(d[,], SplitRatio= 0.80)
    train = subset(d, samplev == TRUE)
    test = subset(d, samplev == FALSE)
    
  2. 我正在尝试使用logistic回归任务的拆分数据,如下所示 -

    #Training
    m <- glm(mpg01~ . -name, data= train, family = binomial(link = 'logit'))
    out2 <- predict.glm(m, test, type = "response")
    class2 <- vector()
    for (i in 1:length(out2))
    {
      if(out2[i] >= 0.5)
      {
        class2[i] <- 1
      }
      else
      {
        class2[i] <- 0
      }
    }
    r2 <- table(class2, test$mpg01)  #confusion Matrix
    

这个想法是不要在数据中使用"名称"列进行培训。当我尝试在测试数据上运行构建模型时,它显示以下 -

out2&lt; - predive.glm(m,test,type ="响应")

model.frame.default中的错误(术语,newdata,na.Action = na.Action,xlev = object $ xlevels):

因子名称具有新级别AMC大使SST,AMC Concord DL 6,AMC Pacer,AMC Pacer D/L,AMC Rebel SST,Audi 100 LS,Audi 5000,Buick Century 350,别克世纪350,别克世纪有限公司,Cadillac Seville,Capri II,Capri II,雪佛兰Bel Air,Chevrolet Cavalier,Chevrolet Cavalier Wagon,Chevrolet Monte Carlo,Chevrolet Vega 2300,Chrysler Lebaron Town @ Country(SW),Chrysler New Yorker Brougham,Datsun 510货车(SW),道奇·阿斯彭6,道奇柯尔特硬顶,道奇柯尔特M/m,道奇飞镖习俗,道奇·玛格南XE,道奇横冲直撞,菲亚特124 TC,福特野马,福特野马二世,福特野马RX3,Mazda 626,Mazda GLC 4,Mazda GLC定制,梅赛德斯 - 奔驰240D,梅赛德斯 - 奔驰280S,Mercury Capri 2000,Mercury Marquis,Oldsmobile Cutlass Ciera(柴油)轿车,普利茅斯大愤怒,普利茅斯地平线,普利茅斯地平线Miser,普利茅斯地平线TC3,普利茅斯卫星,普利莫

从我的理解中,由于我们不使用"名称"属性,因此不应该出现此错误吗?或者,如果我们在不打算时以某种方式使用它,我做错了什么?

问题1答案

sample.split函数期望第一个参数的向量,看起来您要么通过data.framematrix。这是一个显示不同行为的简单示例。

# Mock up some data
library(caTools)
df0 <- data.frame(
     y = as.factor(rbinom(392, 1, 0.75)),
     x1 = rnorm(392)
)
# sample.split with a data.frame as the first argument does not split 80/20 as expected
set.seed(101)
samplev = sample.split(df0, SplitRatio= 0.80)
train = subset(df0, samplev == TRUE)
test = subset(df0, samplev == FALSE)
nrow(train)
[1] 196
nrow(test)
[1] 196
# feed in your response variable as a vector to get the expected split
set.seed(101)
samplev = sample.split(df0$y, SplitRatio= 0.80)
train = subset(df0, samplev == TRUE)
test = subset(df0, samplev == FALSE)
nrow(train)
[1] 314
nrow(test)
[1] 78

问题2答案

虽然您正在做的事情看起来很合理,并且似乎应该按照您的期望来工作,但它似乎并不是glmmodel.frame最终功能在引擎盖下的公式。

首先,这里是将复制您正在做的事情和所看到的错误的代码。

set.seed(123)
df <- data.frame(
    y = as.factor(rbinom(100, 1, 0.5)),
    x1 = rnorm(100),
    x2 = rnorm(100),
    name = c(rep('a',40), rep('b',30), rep('c', 30))
)
train <- df[1:70,]
test <- df[71:100,]
m <- glm(y~ . -name, data= train, family = binomial(link = 'logit'))
out2 <- predict.glm(m, test, type = "response")

现在注意到,当我直接使用您的公式调用model.frame时,它仍包括name列。

head(model.frame(y~ . -name, data = train), 1)
  y        x1        x2 name
1 0 0.2533185 0.7877388    a

虽然不包括.列符号的公式将不包括该额外的列。

head(model.frame(y~ x1 + x2, data = train), 1)
  y        x1        x2
1 0 0.2533185 0.7877388

在一天结束时,您似乎需要通过直接在公式中指定列或使用.列符号来解决此问题,然后通过删除要排除的列来。

更具体地说,用我的简单示例,解决方法看起来像。

m <- glm(y~ x1 + x2, data= train, family = binomial(link = 'logit'))
out2 <- predict.glm(m, test, type = "response")

和解决方案选项2看起来像。

m <- glm(y~ ., data= train[,names(train) != 'name'], family = binomial(link = 'logit'))
out2 <- predict.glm(m, test, type = "response")

最新更新