【问题标题】:How to set reference levels in a Spark ML Logistic Regression using OneHotEncoder如何使用 OneHotEncoder 在 Spark ML Logistic 回归中设置参考水平
【发布时间】:2018-10-21 22:52:45
【问题描述】:

我正在 PySpark 中使用 Spark 2.1 准备我的数据以构建逻辑回归。我的数据中有几个字符串变量,我想将最常见的类别设置为参考级别。我首先使用 StringIndexer 将字符串列编码为标签索引,我知道这些是按标签频率排序的,最常接收到的索引为 0。

stringIndexer = StringIndexer(inputCol='income_grp', outputCol="income_grp_indexed")
model = stringIndexer.fit(df)
indexed = model.transform(df)

+-------------+------------------+
|   income_grp|income_grp_indexed|
+-------------+------------------+
|200000_299999|               0.0|
|300000_499999|               1.0|
|100000_199999|               2.0|
|500000_749999|               3.0|
|  less_100000|               4.0|
|750000_999999|               5.0|
|   ge_1000000|               6.0|
+-------------+------------------+

然后我使用 OneHotEncoder 将标签索引列映射到二进制向量列。但是,我只在 OneHotEncoder 中看到一个选项来删除最后一个级别,这是最不频繁的类别。

encoder = OneHotEncoder(dropLast=True, inputCol="income_grp_indexed", outputCol="income_grp_encoded")
encoded = encoder.transform(indexed)

+-------------+------------------+------------------+
|   income_grp|income_grp_indexed|income_grp_encoded|
+-------------+------------------+------------------+
|200000_299999|               0.0|     (6,[0],[1.0])|
|300000_499999|               1.0|     (6,[1],[1.0])|
|100000_199999|               2.0|     (6,[2],[1.0])|
|500000_749999|               3.0|     (6,[3],[1.0])|
|  less_100000|               4.0|     (6,[4],[1.0])|
|750000_999999|               5.0|     (6,[5],[1.0])|
|   ge_1000000|               6.0|         (6,[],[])|
+-------------+------------------+------------------+

如何删除每个字符串变量中出现频率最高的类别?

【问题讨论】:

  • 我不确定你在问什么。 OneHotEncoder 可以“删除”一个级别,因为您只需要n-1 级别即可完全描述具有n 级别的分类变量。从建模的角度来看,选择“删除”哪个级别是相当随意的。
  • @pault - 我知道从建模的角度来看这可能无关紧要,但出于其他原因,我需要控制它。所以我的问题是如何自定义要删除的级别。

标签: apache-spark pyspark one-hot-encoding


【解决方案1】:

我知道这是一个老问题,我的回答可能不适用于 Spark 2.1 版,但对于 Spark 3.1.2(我正在使用的版本),StringIndexer 有一个参数 @ 987654321@,可以设置为“frequencyAsc”。如果这样做,最后一个索引将是频率最高的索引,并将在 OneHotEncoder 处被丢弃。

所以你可以这样做:

    stringIndexer = StringIndexer(inputCol='income_grp', 
    outputCol="income_grp_indexed", stringOrderType='frequencyAsc')

    # The rest is the same
    encoder = OneHotEncoder(dropLast=True, inputCol="income_grp_indexed", outputCol="income_grp_encoded")
    encoded = encoder.transform(indexed)
    ...

这在我们处理pyspark.ml.regression.GeneralizedLinearRegression 时特别重要,这是一个可以输出每个系数的统计 p.values 的模型,并且这些 p.values 可以根据基本级别的频率而变化。

【讨论】: