R语言lm回归cut_fair、clarity_I1虚拟变量未输出问题
产生原因
- 你手动生成虚拟变量的操作是在
diamonds_7数据集上完成的,但后续建模调用的是train数据集,两个是独立的R对象,你生成的cut_*、clarity_*系列变量根本没有进入建模数据集,模型完全没用到你手动写的虚拟变量。 - 你写的
lm公式里传入的是原始的分类列train$cut和train$clarity,R中lm函数会自动将因子(factor)类型的分类变量转换为虚拟变量进入模型。为了避免虚拟变量陷阱(即同组所有虚拟变量加和恒为1,和截距项形成完全多重共线性,导致模型无法求解),对于k个水平的分类变量,R会默认丢弃排序第一的因子水平作为参照组,该组的效应会被合并到截距项中,不会单独输出系数。
按照diamonds数据集默认的因子排序:cut的水平顺序为Fair < Good < Very Good < Premium < Ideal,排在第一的Fair被设为参照组,所以没有cutFair的系数输出clarity的水平顺序为I1 < SI2 < SI1 < VS2 < VS1 < VVS2 < VVS1 < IF,排在第一的I1被设为参照组,所以没有clarityI1的系数输出
你输出的系数表中其他分类变量的估计值,含义都是该水平相对于参照组(Fair切工、I1净度)的价格差值,结果本身是可正常解释的。
- 额外说明:你写
lm公式时反复用train$列名的写法是不规范的,容易导致后续预测、变量分析时出现环境索引错误,直接在公式里写列名、靠data参数指定数据集即可。
解决方法
根据你的使用习惯二选一即可:
- 方案1:使用R自动哑变量编码(推荐,出错概率低)
不需要手动生成任何虚拟变量,直接用规范的lm语法建模即可,未输出的两个水平就是默认参照组:# 可选:如果要更换参照组,用relevel函数调整,比如把Ideal设为切工的基准 # train$cut <- relevel(train$cut, ref = "Ideal") lmTotal <- lm(price ~ carat + depth + table + cut + clarity, data = train) - 方案2:使用手动生成的虚拟变量建模
首先要把虚拟变量生成到你实际建模用的train数据集上,其次建模时不要传入原始的cut、clarity分类列,同时每个分类变量要故意留1个水平的哑变量不放入模型作为参照组,避免共线性:
这种写法得到的系数估计结果和R自动编码的结果完全一致,只是手动编码操作更繁琐,容易出现变量漏加、共线性的问题。# 在train数据集生成对应虚拟变量 train$cut_fair = ifelse(train$cut == "Fair" , 1 , 0) train$cut_good = ifelse(train$cut == "Good" , 1 , 0) train$cut_very_good = ifelse(train$cut == "Very Good" , 1 , 0) train$cut_premium = ifelse(train$cut == "Premium" , 1 , 0) train$cut_ideal = ifelse(train$cut == "Ideal" , 1 , 0) train$clarity_SI2 = ifelse(train$clarity == "SI2" , 1 , 0) train$clarity_SI1 = ifelse(train$clarity == "SI1" , 1 , 0) train$clarity_VS1 = ifelse(train$clarity == "VS1" , 1 , 0) train$clarity_VS2 = ifelse(train$clarity == "VS2" , 1 , 0) train$clarity_VVS2 = ifelse(train$clarity == "VVS2" , 1 , 0) train$clarity_VVS1 = ifelse(train$clarity == "VVS1" , 1 , 0) train$clarity_I1 = ifelse(train$clarity == "I1" , 1 , 0) train$clarity_IF = ifelse(train$clarity == "IF" , 1 , 0) # 建模时传入手动生成的哑变量,留cut_fair、clarity_I1作为参照不放入 lmTotal_manual <- lm(price ~ carat + depth + table + cut_good + cut_very_good + cut_premium + cut_ideal + clarity_SI2 + clarity_SI1 + clarity_VS1 + clarity_VS2 + clarity_VVS2 + clarity_VVS1 + clarity_IF, data = train)
内容的提问来源于stack exchange,提问作者Fleur Hoogendoorn
相关产品推荐
相关产品推荐

