You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中Logistic回归识别需安全库存物料时的收敛警告问题咨询

逻辑回归模型警告问题排查与解决

问题背景

在R中构建用于识别新库存物料是否需要安全库存的逻辑回归模型,自变量为LeadTime(天数)、UnitCost(美元)、DailyUsage(数量/天),因变量SafetyStock为因子型(1=需要,0=不需要)。执行以下代码时出现两条警告:

SafetyStock_model <- glm(formula = SafetyStock ~ UnitCost + LeadTime + DailyUsage, family = binomial(link = "logit"), data = SafetyStock_Train)

警告信息:

  1. glm.fit: algorithm did not converge
  2. 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,全量数据中这类变量组合可能完全将两类样本分开,触发分离问题

解决办法

  1. 验证分离情况:

    • 对每个自变量绘制箱线图,对比SafetyStock=0和1的分布差异;或生成自变量组合与因变量的交叉表,确认是否存在完全区分的情况
    • 用car::vif()检查自变量是否存在多重共线性,共线性可能加剧分离问题
  2. 改用Firth逻辑回归:
    Firth方法针对完全/准完全分离的逻辑回归问题做了偏差修正,可直接使用logistf包实现:

    # 安装并加载包
    install.packages("logistf")
    library(logistf)
    # 训练模型
    SafetyStock_model <- logistf(SafetyStock ~ UnitCost + LeadTime + DailyUsage, data = SafetyStock_Train)
    summary(SafetyStock_model)
    
  3. 加入正则化约束:
    使用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)
    
  4. 处理极端样本:
    如果是少数极端样本导致分离,可结合业务逻辑判断是否移除这些样本,但需注意避免数据泄漏或偏差

内容的提问来源于stack exchange,提问作者brossb12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:24:52