我有2个问题。
-
当我尝试将数据分为测试和火车集时,使用
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)
-
我正在尝试使用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.frame
或matrix
。这是一个显示不同行为的简单示例。
# 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答案
虽然您正在做的事情看起来很合理,并且似乎应该按照您的期望来工作,但它似乎并不是glm
和model.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")