为何sklearn多分类逻辑回归手动计算概率与predict_proba结果不符?
问题原因及解决方法
你的核心问题是混淆了二分类与多分类逻辑回归的概率计算方式,sklearn中multiclass="multinomial"对应的是多项式逻辑回归,用的是softmax函数计算概率,而非二分类的sigmoid函数。
具体错误点
- 你用了二分类逻辑回归的概率公式
p = e^logit/(1+e^logit),这个公式只适用于二分类场景。在多分类(3类)下,每个类别的概率不是独立计算的,必须通过softmax函数归一化,才能保证所有类别概率和为1。 - 另外需要注意:如果你的
Education是多分类变量(比如小学/中学/大学),sklearn默认会把它当成有序变量用LabelEncoder转成整数,但多项式逻辑回归更适合用OneHotEncoder处理这类无序分类变量。如果编码方式不一致,手动计算时也会出现偏差。
正确的手动计算步骤
假设你的模型拟合后:
- 截距项
mnlr.intercept_是长度为3的数组,对应Agree、Disagree、Unsure三类的截距 - 系数矩阵
mnlr.coef_是(3, n_features)的数组,每一行对应一类的自变量系数
对任意样本,先计算每个类别的线性预测值z_k:
# 假设样本的自变量特征为x(已和模型拟合时的编码一致) z_agree = mnlr.intercept_[0] + x @ mnlr.coef_[0].T z_disagree = mnlr.intercept_[1] + x @ mnlr.coef_[1].T z_unsure = mnlr.intercept_[2] + x @ mnlr.coef_[2].T
然后用softmax函数计算概率:
import numpy as np exp_z = np.exp([z_agree, z_disagree, z_unsure]) sum_exp = exp_z.sum() p_agree = exp_z[0] / sum_exp p_disagree = exp_z[1] / sum_exp p_unsure = exp_z[2] / sum_exp
这样计算出来的概率和为1,且结果会和mnlr.predict_proba(x.reshape(1,-1))完全一致。
额外检查项
- 自变量编码一致性:确保手动计算时用的自变量编码(比如
Education的取值、Gender的0/1对应)和模型拟合时完全相同。如果Education是无序多分类变量,建议用OneHotEncoder处理后再拟合模型,避免模型将其当成有序变量。 - 模型solver参数:多项式逻辑回归需要使用支持多分类的solver,比如
lbfgs、newton-cg、sag或saga,默认的solver='lbfgs'是支持的,但如果用了liblinear会直接报错,可确认你的模型参数。
内容的提问来源于stack exchange,提问作者stat_is_quo
相关产品推荐
相关产品推荐

