Spark 多项式 Logistic 回归中的意外系数

Posted

技术标签:

【中文标题】Spark 多项式 Logistic 回归中的意外系数【英文标题】:Unexpected coefficients from Spark multinomial Logistic Regression 【发布时间】:2017-12-08 09:52:16 【问题描述】:

我在我的 Mac OS Sierra 上运行 Spark 2.1.1(这是否有帮助)。我尝试在网上找到的测试数据集上拟合多项逻辑回归,我在这里报告前几行(我不知道如何在此处附加文件):

1,0,24
1,0,26
1,0,26
1,1,27
1,1,27
3,1,27

第一列是标签('brand',值:1、2、3),第二和第三列是特征('sex'和'age')。

由于标签有 3 个类别,因此多项逻辑回归应执行 3 个二项模型,然后从最大化该类别概率的模型中选择预测。所以我希望模型返回一个 3x2 系数矩阵:3 因为类是 3,而 2 因为特征是 2。This 文档似乎与这个观点一致。

但是,意外惊喜……

>>> logit_model.coefficientMatrix
DenseMatrix(4, 2, [-1.2781, -2.8523, 0.0961, 0.5994, 0.6199, 0.9676, 0.5621, 1.2853], 1)
>>> logit_model.interceptVector
DenseVector([-4.5912, 13.0291, 1.2544, -9.6923])

coefficientMatrix 是 4x2,我有 4 个截距而不是 3 个截距。更奇怪的是:

>>> logit_model.numClasses
4

出于某种奇怪的原因,模型“感觉”了 4 个类,即使我只有 3 个(请参阅下面的代码以进行检查)。

有什么建议吗? 非常感谢。


这里是完整的代码:

from pyspark.sql import functions as f
from pyspark.sql import types as t
from pyspark.ml import classification as cl
from pyspark.ml import feature as feat

customSchema = t.StructType(
    [t.StructField('brand', t.IntegerType(), True),
    t.StructField('sex', t.IntegerType(), True),
    t.StructField('age', t.IntegerType(), True)]
)

test_df01 = (
    spark
    .read
    .format('csv')
    .options(delimiter=',', header=False)
    .load('/Users/vanni/Downloads/mlogit_test.csv', schema=customSchema)
)

va = (
    feat.VectorAssembler()
    .setInputCols(['sex', 'age'])
    .setOutputCol('features')
)
test_df03 = (
    va
    .transform(test_df01)
    .drop('sex')
    .drop('age')
    .withColumnRenamed('brand', 'label')
)

logit_abst = (
    cl.LogisticRegression()
    .setFamily('multinomial')
    .setStandardization(False)
    .setThresholds([.5, .5, .5]) # to be adjusted after I know the actual values
    .setThreshold(None)
    .setMaxIter(100) # default
    .setRegParam(0.0) # default
    .setElasticNetParam(0.0) # default
    .setTol(1e-6) # default
)

logit_model = logit_abst.fit(test_df03)

这是检查类只有 3 个:

>>> test_df03.select('label').distinct().orderBy('label').show()
+-----+
|label|
+-----+
|    1|
|    2|
|    3|
+-----+

【问题讨论】:

【参考方案1】:

这里没有什么奇怪的。 Spark 假设标签是连续的整数值,表示为DoubleType,并以 0 开头。

由于您获得的最大标签是 3,Spark 假定标签实际上是 0、1、2、3 - 即使数据集中从未出现过 0。

如果不希望出现这种行为,您应该将标签重新编码为从零开始,或在原始标签上应用 StringIndexer

【讨论】:

非常感谢,我把class 3换成了0,成功了!我永远不会猜到这样的解决方案。

以上是关于Spark 多项式 Logistic 回归中的意外系数的主要内容,如果未能解决你的问题,请参考以下文章

PySpark多项式回归中的参考组

如何用SPSS做多项Logistic回归

R语言广义线性模型函数GLMR中有几种logistic回归扩展和变异robust包中的glmRob函数鲁棒logistic回归ms包中的lrm函数拟合序数逻辑回归

机器学习线性回归(最小二乘法/梯度下降法)多项式回归logistic回归softmax回归

如何应用spss软件包进行logistic回归分析

MATLAB 多项 Logistic 回归输入