逻辑回归中添加32个犯罪类型虚拟变量向量的技术咨询
嘿,我来帮你把这个逻辑回归分析的代码和思路理清楚,顺便提几个关键的优化点~
逻辑回归分析:多犯罪类型虚拟变量处理
1. 虚拟变量的创建优化
你目前用ifelse逐个生成犯罪类型虚拟变量的思路是对的,但要注意不要把这些变量拼成一维向量——我们需要每个观测对应32个虚拟变量的取值,所以应该把它们组合成数据框或矩阵:
手动创建单个虚拟变量
# 生成单类犯罪的二值标记 narcotics <- ifelse(train$PRIMARY.DESCRIPTION == "NARCOTICS", 1, 0) theft <- ifelse(train$PRIMARY.DESCRIPTION == "THEFT", 1, 0) burglary <- ifelse(train$PRIMARY.DESCRIPTION == "BURGLARY", 1, 0) # 以此类推,创建剩余29种犯罪类型的虚拟变量
组合成结构化数据
# 将所有虚拟变量组合成数据框,方便后续建模 crime_type_dummies <- data.frame( narcotics = narcotics, theft = theft, burglary = burglary, motor_vehicle_theft = motor.vehicle.theft, battery = battery, robbery = robbery, assault = assault, criminal_damage = criminal.damage, deceptive_practice = deceptive.practice, kidnapping = kidnapping # 补充剩余22种犯罪类型的变量 )
更高效的批量生成方法
手动写32个ifelse太麻烦了,推荐用model.matrix或者dplyr批量生成,省时间还不容易出错:
# 方法1:用model.matrix自动生成所有虚拟变量 crime_dummies <- model.matrix(~ PRIMARY.DESCRIPTION - 1, data = train) # 生成的列名类似 PRIMARY.DESCRIPTIONNARCOTICS、PRIMARY.DESCRIPTIONTHEFT # 方法2:用dplyr批量生成(更直观) library(dplyr) train_with_dummies <- train %>% mutate( across( .cols = PRIMARY.DESCRIPTION, .fns = ~ as.integer(.x == unique(PRIMARY.DESCRIPTION)), .names = "crime_{.value}" ) )
2. 逻辑回归模型的正确构建
这里要敲个重点:逻辑回归不能用lm()!lm()是做线性回归的,逻辑回归需要用glm()并指定family = binomial:
基础写法(手动列变量)
# 合并原始数据和虚拟变量数据 model_data <- cbind(train, crime_type_dummies) # 构建逻辑回归模型(假设street1是二分类因变量,比如是否发生在目标街道) logit.mod.train <- glm( formula = street1 ~ narcotics + theft + burglary + motor_vehicle_theft + battery + robbery + assault + criminal_damage + deceptive_practice + kidnapping + ..., data = model_data, family = binomial(link = "logit") )
简洁写法(引用所有虚拟变量)
如果虚拟变量都在同一个数据框里,可以直接用.代表所有自变量:
# 只保留因变量和犯罪类型虚拟变量 model_data_subset <- model_data[, c("street1", names(crime_type_dummies))] logit.mod.train <- glm( formula = street1 ~ ., data = model_data_subset, family = binomial )
3. 必须注意的多重共线性问题
因为每个观测只会属于一种犯罪类型,32个虚拟变量的和恒等于1,这会导致完全多重共线性,模型无法正常估计系数!解决方法是:
- 去掉其中一个虚拟变量作为基准类别(比如去掉
other_offense),剩下的31个变量用来和基准类别做对比; - 或者在模型中加
-1去掉截距,但这种方式的系数解释性很差,不推荐。
举个例子,假设我们把other_offense作为基准,建模时就不要把它放进公式里:
logit.mod.train <- glm( street1 ~ narcotics + theft + burglary + ..., # 去掉other_offense data = model_data, family = binomial )
内容的提问来源于stack exchange,提问作者user8276807
相关产品推荐
相关产品推荐

