R语言mlogit模型加入独热编码变量后触发计算奇异报错问题
mlogit系列报错原因与解决思路
基础多项Logit模型"system is computationally singular"报错
- 核心诱因是全量纳入独热编码列导致的完全共线性:对k个分类的离散变量做独热编码会生成k个0/1列,同一行的k个列取值之和恒为1,在多分类Logit模型中如果不删除1列作为参照组,会直接导致设计矩阵秩亏,矩阵求逆时触发计算奇异报错。
- 测试时移除所有Job相关列模型即可正常运行,加入该类列就报错,完全符合该问题特征:第一次建模时将Job变量对应的所有独热列(JobA-JobE)全部放入了个体特征变量位,没有预留参照组,必然触发共线性。
- 该问题的处理逻辑已经验证有效:对所有手动独热编码的分类变量,必须删除1个分类对应的列作为参照基准,不能全量纳入模型。额外需要注意检查第一次代码中纳入的Area变量,如果也是手动独热生成的,同样需要留1列作为参照,否则后续仍可能触发共线性报错。
对应第一次出错的基础模型代码如下:
#Multinomial Logistic Regression Model1 <- mlogit(choice ~ 0 | Sex + Age.1+ Household.Income +Area+JobA+JobB+JobC+JobD+JobE , data = DFIDX) summary(Model1)
移除参照组后混合Logit模型新报错
当前的混合Logit代码存在3个常见问题,按优先级逐一排查即可:
#Mixed logit Model with random parameters Model2 <- mlogit(choice ~ 0 | Sex + Age.1+ Household.Income +JobA+JobB , data = DFIDX, rpar=c("Sex:2" = 'n', "Sex:3" = 'n', "Age.1:2" = 'n', "Age.1:3" = 'n', "Household.Income:2" = 'n', "Household.Income:3" = 'n' , "JobA:2" = 'n', "JobA:3" = 'n', "JobB:2" = 'n', "JobB:3" = 'n'), R = 100 , panel = TRUE) summary(Model2)
- 随机参数名称不匹配:mlogit对
|分隔符后的个体层面变量,自动生成的系数命名规则为变量名:备选方案水平值,手动指定的rpar参数名(比如Sex:2、JobA:3)可能和模型实际生成的系数名不一致,比如备选方案的因子水平如果不是以2、3编号,或者变量名存在拼写误差,都会直接触发参数识别错误。
排查方法:先跑通无随机参数的基础模型,执行以下代码打印所有真实系数名,和rpar中填写的名称逐一比对,完全匹配后再运行混合模型:# 提取基础模型的系数名 print(names(coef(Model1))) - 数值不稳定导致估计失败:当前设置的模拟抽样次数R=100过小,同时一次性指定了10个服从正态分布的随机参数,模拟最大似然估计过程中很容易因模拟误差过大出现海森矩阵不可逆、计算奇异的问题。
排查方法:先将R值调高至500以上,面板数据场景建议设置为1000;不要一次性把所有个体变量都设为随机参数,先从核心解释变量(比如Job相关变量)开始添加,逐步增加其他变量的随机参数设定,定位触发报错的具体参数。 - 变量识别不足:Sex、Age、Job、收入都属于不随备选方案变化的个体特征变量,如果某一分类的样本在某个备选方案上的观测数过少(比如某类职业的受访者从未选择过某一备选方案),对应的系数无法被识别,也会触发报错。
排查方法:交叉统计分类变量和选择结果的频数表,确保每个分类单元格的观测数不低于5;可暂时关闭panel = TRUE设定,先跑通截面混合Logit模型,再逐步添加面板随机效应设定,排除面板结构带来的识别问题。
额外注意:手动生成的独热列需要确认是数值型0/1格式,如果存储为因子或字符型,mlogit会自动对其再次做独热编码,重新引入共线性问题。
内容的提问来源于stack exchange,提问作者Wahab Aftab
相关产品推荐
相关产品推荐

