r语言 - 使用logistic模型进行预测时,与变量相关的误差



如果我的标题不清楚,请原谅,但我想不出一个非常清楚的方法来总结我所追求的。

我正在使用泰坦尼克号数据集来学习逻辑回归。这个想法是建立一个预测生存的模型。数据包括乘客Age。使用该属性,我将Age分解为

Age_labels <- c('0-10', '11-17', '18-29', '30-39', '40-49', '50-59', '60-69', '70-79')
train_data$AgeGroup <- cut(train_data$Age, c(0, 11, 18, 30, 40, 50, 60, 70, 80), include.highest=TRUE, labels= Age_labels)

模型完成后,我准备用它来预测测试数据上的存活率——但是当我尝试

时,我得到了一个错误
test_data_predictions <- predict(my_model, newdata = test_data, type = "response")

错误如下:

model.frame.default(Terms, newdata, na。Action = na.action;xlev =对象$xlevels):因子AgeGroup有新的级别60-69,70 - 79

为什么?似乎意味着问题是因为测试数据包括60-69岁和70-79岁年龄组的乘客(而火车数据不包括这些年龄范围的乘客)。或者这个错误实际上意味着别的什么?

显然,我想用这个模型来预测任何乘客的生存率,而不管年龄。

这是一个潜在的线索:str()告诉我test_data中的AgeGroup是w/8个级别的因子,而在train_data中它是w/6个级别的因子。此外,在train_data和test_data中都没有NA

我如何纠正错误,以便我可以继续进行实际的预测?由于

注:没有包括数据,因为这个问题似乎不需要可重复性来回答

根据@sjp的建议,我回去把AgeGroup当作连续变量(作为数字)。这样做会产生负面影响:AIC上升,残差的分形图现在看起来相当差(分形图外有太多),Hosmer-Lemeshow现在说"总结:模型不太拟合"。因此,将AgeGroup传递为数字确实使我可以使用模型对测试数据进行预测,但我担心价格太高。

br因为测试集中存在训练集中的年龄组(由于小类别的随机抽样),R不能对这些测试用例做出预测。您可以使用caret::createDataPartition(age_group)来创建一个训练/测试分割,它在年龄组变量上是平衡的(因此不会丢失任何类别)。帮助页面(?createDataPartition)警告您"for…非常小的类大小(<= 3)类可能不会同时出现在训练和测试数据中,但它似乎在这里工作得很好(最小的组有n=6)。

复制问题

tt <- transform(carData::TitanicSurvival,
age_group = cut(age,
breaks = c(0, 11, 18, 30, 40, 50, 60, 70, 80))
)
set.seed(101)
## allocate a small fraction (10%) to the training set to make 
##   it easier to get missing classes in the training set
split1 <- sample(c("train", "test"),
size = nrow(tt),
replace = TRUE,
prob = c(0.1, 0.9))
m1 <- glm(survived ~ age_group, family = binomial,
data = tt[split1 == "train", ])
try(predict(m1, newdata = tt[split1 == "test",]))

这给

model.frame.default(Terms, newdata, na。动作= na。动作,xlev =对象$xlevels):因子age_group有新的水平[70,80]

<<h2>平衡样本/h2>
library(caret)
set.seed(101)
w <- createDataPartition(tt$age_group, p = 0.1)$Resample1
table(tt$age_group[w])
table(tt$age_group[-w])
m2 <- glm(survived ~ age_group, family = binomial, data = tt[w,])
predict(m2, newdata = tt[-w,])

这个工作正常。使用table(tt$age_group[w])table(tt$age_group[-w])确认每个年龄类都存在于训练集和测试集中,尽管如果测试集中缺少类则不会造成任何问题只有…

最新更新