Scikit-learn与R的glm逻辑回归系数差异过大如何排查?
R glm与Scikit-learn逻辑回归结果差异排查
问题场景
对比R语言stats包glm函数与Python Scikit-learn库的逻辑回归实现效果,已确认传入两边求解器的特征矩阵维度、列名一致,但输出系数差异极大,且R版本模型的ROC AUC指标远优于Python版本,已知二者默认求解器存在差异,但当前结果差距远超合理预期。
使用的数据集为公开测试数据集。
Python侧实现代码
import pandas as pd from sklearn.linear_model import LogisticRegression df = pd.read_csv("dataset.csv") df = df.join(pd.get_dummies(df['var2'], prefix = 'var2', drop_first= True)) df.drop(columns = ['var2'], inplace = True) X = df.loc[:,df.columns != 'y'] y = df.y model = LogisticRegression(fit_intercept=True, penalty = 'none' ) model.fit(X, y) prob = model.predict_proba(X) model.coef_
Python侧输出变量系数:
var1, var3, var4, var2_B, var2_C -1.833653e-07, 2.823982e-12, 2.568188e-12, -4.116901e-13, 5.514602e-14
R侧实现代码
df=read_csv(file = "dataset.csv") glm_fit <- glm(y ~.,data = df, family=binomial(link = 'logit')) summary(glm_fit)
R侧输出变量系数:
(Intercept) -6.459e-01 var1 -1.042e-07 var2B -7.731e-01 var2C 1.880e+00 var3 -1.124e-04 var4 2.994e-03
排查步骤
- 优先排查模型收敛问题:你当前Python代码中
LogisticRegression(penalty='none')默认使用lbfgs求解器,默认最大迭代次数仅为100,输出系数绝大多数接近0是典型的迭代不足未收敛特征。先将max_iter参数调大到10000,fit模型时注意观察是否抛出ConvergenceWarning,如果警告消失后系数和R结果对齐,即可确认是迭代次数不足导致的问题。 - 校验特征尺度适配性:
lbfgs这类基于梯度的求解器对特征尺度非常敏感,R的glm使用迭代重加权最小二乘(IRLS)求解,对特征尺度的敏感度低很多。如果var1、var3、var4的量纲差异超过2个数量级,会大幅拖慢梯度类求解器的收敛速度。无正则项场景下特征标准化不会改变模型最终系数的理论值,只会提升收敛效率,可以先用StandardScaler对连续特征做标准化后再训练,验证结果是否对齐。 - 校验分类变量编码一致性:确认
pd.get_dummies(drop_first=True)丢弃的参考水平,和R的glm自动选择的因子参考水平完全一致,避免出现var2的B、C类编码错位的问题,可以通过交叉统计独热列与原分类列的取值对应关系验证。 - 校验标签编码一致性:确认两边y变量的正类定义完全一致,比对两边数据集的正类占比(y列均值),避免出现R和Python对y的0/1映射规则不同、正负类翻转的问题。
- 校验输入数据精度:不要仅通过维度、列名判断特征矩阵一致,要逐列比对两边特征的均值、标准差、最值、缺失值数量,排除csv读取时某列被误识别为字符串/因子、数值精度丢失的问题。
- 更换求解器做对照:将Python侧逻辑回归的求解器显式指定为
solver='newton-cg',该求解器为牛顿法,和R的glm使用的IRLS同属二阶优化方法,无正则项场景下二者收敛到的理论最优解应该完全一致,可以排除求解器本身的实现差异干扰。
内容的提问来源于stack exchange,提问作者user1700890
相关产品推荐
相关产品推荐

