R中Logistic回归识别需安全库存物料时的收敛警告问题咨询
逻辑回归模型警告问题排查与解决
问题背景
在R中构建用于识别新库存物料是否需要安全库存的逻辑回归模型,自变量为LeadTime(天数)、UnitCost(美元)、DailyUsage(数量/天),因变量SafetyStock为因子型(1=需要,0=不需要)。执行以下代码时出现两条警告:
SafetyStock_model <- glm(formula = SafetyStock ~ UnitCost + LeadTime + DailyUsage, family = binomial(link = "logit"), data = SafetyStock_Train)
警告信息:
- glm.fit: algorithm did not converge
- glm.fit: fitted probabilities numerically 0 or 1 occurred
用户怀疑是完全分离导致,但认为自身数据不存在该情况,现附上数据样本与模型摘要,寻求问题原因与解决办法。
数据样本
structure(list(PartNumber = c("72150", "66K4A3SN-SF", "AN320-4", "67L20423", "72245", "60N29740-CT", "LW-16107", "65990", "LW-349290-1-70", "31M22993"), UnitCost = c(93.45, 752.584, 0.4984, 142.044, 784.24486, 0.16198, 101.12536, 33.642, 610.2285, 784.24486), DailyUsage = c(0.0145833333333333, 1.10833333333333, 0.0229166666666667, 0.00416666666666667, 0.06875, 0.00833333333333333, 0.0104166666666667, 0.00208333333333333, 0.0166666666666667, 0.0520833333333333), LeadTime = c(35, 180, 40, 30, 130, 365, 90, 40, 40, 130), SafetyStock = structure(c(1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L), levels = c("0", "1"), class = "factor")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"))
模型摘要
Call: glm(formula = SafetyStock ~ UnitCost + LeadTime + DailyUsage, family = binomial(link = "logit"), data = SafetyStock_Train) Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) -2.677e+02 3.951e+02 -0.678 0.498 UnitCost 1.284e-03 1.011e-02 0.127 0.899 LeadTime 1.296e-01 3.420e-01 0.379 0.705 DailyUsage 5.122e+03 7.660e+03 0.669 0.504 (Dispersion parameter for binomial family taken to be 1) Null deviance: 1.1914e+03 on 1026 degrees of freedom Residual deviance: 7.6262e-03 on 1023 degrees of freedom AIC: 8.0076 Number of Fisher Scoring iterations: 25
问题原因
从模型摘要可明确判断是准完全分离导致的问题:
- 残差偏差几乎为0(7.6262e-03),说明模型几乎完美拟合训练数据,意味着存在自变量组合可完全区分SafetyStock的0和1两类
- Fisher迭代次数达25次仍未收敛,算法试图无限增大系数以拟合完全分离的情况,最终导致拟合概率趋近于0或1
- 样本中SafetyStock=1的条目(如PartNumber为66K4A3SN-SF、72245、31M22993)均具有较高UnitCost、较长LeadTime或较高DailyUsage,全量数据中这类变量组合可能完全将两类样本分开,触发分离问题
解决办法
验证分离情况:
- 对每个自变量绘制箱线图,对比SafetyStock=0和1的分布差异;或生成自变量组合与因变量的交叉表,确认是否存在完全区分的情况
- 用
car::vif()检查自变量是否存在多重共线性,共线性可能加剧分离问题
改用Firth逻辑回归:
Firth方法针对完全/准完全分离的逻辑回归问题做了偏差修正,可直接使用logistf包实现:# 安装并加载包 install.packages("logistf") library(logistf) # 训练模型 SafetyStock_model <- logistf(SafetyStock ~ UnitCost + LeadTime + DailyUsage, data = SafetyStock_Train) summary(SafetyStock_model)加入正则化约束:
使用glmnet包实现带L1/L2正则化的逻辑回归,通过限制系数大小避免无限增大的问题:# 安装并加载包 install.packages("glmnet") library(glmnet) # 构造矩阵格式的自变量和数值型因变量 x <- model.matrix(SafetyStock ~ UnitCost + LeadTime + DailyUsage - 1, data = SafetyStock_Train) y <- as.numeric(SafetyStock_Train$SafetyStock) - 1 # 训练正则化模型 model <- glmnet(x, y, family = "binomial") # 通过交叉验证选择最优lambda cv_model <- cv.glmnet(x, y, family = "binomial") best_model <- glmnet(x, y, family = "binomial", lambda = cv_model$lambda.min)处理极端样本:
如果是少数极端样本导致分离,可结合业务逻辑判断是否移除这些样本,但需注意避免数据泄漏或偏差
内容的提问来源于stack exchange,提问作者brossb12
相关产品推荐
相关产品推荐

