为何model.matrix函数不为所有类别及女性创建虚拟变量?
关于model.matrix虚拟变量生成的问题
为啥不生成所有类别的虚拟变量?
model.matrix的核心逻辑是避免多重共线性:当处理因子变量时,它会选一个水平当「参考基准」,只给剩下的水平生成虚拟变量。要是给所有类别都建虚拟变量,这些变量加起来恒等于1,和模型截距项会完全线性相关,导致模型无法求解。
比如你用的Pclass有3个水平,默认带截距的公式只会出2个虚拟变量(参考水平的效应算在截距里);你加了~ -1去掉截距,这时候就没了共线性顾虑,所以Pclass的3个水平都生成了对应的虚拟变量(Pclass1、Pclass2、Pclass3)。
为啥没生成女性的虚拟变量?
从你贴的输出截图看,只有Sexmale,这是因为女性是Sex因子的参考水平:
- 你把
Sex转成因子时,默认按字母顺序排水平,"female"在"male"前面,所以自动把female设成了参考基准。 - 这里可能你对
-1的作用有点误解:理论上加-1去掉截距后,二元因子应该生成两个虚拟变量,但你这里只看到Sexmale,大概率是这两个情况:- 你看的输出只是前几列,
Sexfemale在后面没显示出来——运行colnames(X)就能看到所有列名。 - 检查下
Sex的因子水平:跑levels(titanicTib$Sex),要是结果是["male", "female"],那参考水平是male,应该会有Sexfemale;如果是["female", "male"],那加-1后本该出两个变量,可能是你截图没截全。
- 你看的输出只是前几列,
要是你铁了心要生成所有类别的虚拟变量,有两种简单办法:
- 手动指定对比方式,强制生成所有水平:
X <- model.matrix(~ -1 + Pclass + Sex + Age + Fare + FamSize, data = titanicTib, contrasts.arg = list(Sex = contr.treatment(nlevels(titanicTib$Sex), base = 0))) - 直接在数据里手动生成虚拟变量:
titanicTib <- titanicTib %>% mutate(Sex_female = as.integer(Sex == "female"), Sex_male = as.integer(Sex == "male"))
内容的提问来源于stack exchange,提问作者Rizzle
相关产品推荐
相关产品推荐

