如果我的标题不清楚,请原谅,但我想不出一个非常清楚的方法来总结我所追求的。
我正在使用泰坦尼克号数据集来学习逻辑回归。这个想法是建立一个预测生存的模型。数据包括乘客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",]))
这给
<<h2>平衡样本/h2>model.frame.default(Terms, newdata, na。动作= na。动作,xlev =对象$xlevels):因子age_group有新的水平[70,80]
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])
确认每个年龄类都存在于训练集和测试集中,尽管如果测试集中缺少类则不会造成任何问题只有…