为什么Spark的OneHotEncoder默认情况下会丢弃最后一个类别?

我想了解Spark的OneHotEncoder默认丢弃最后一个类别的原因。

例如:

>>> fd = spark.createDataFrame( [(1.0, "a"), (1.5, "a"), (10.0, "b"), (3.2, "c")], ["x","c"])>>> ss = StringIndexer(inputCol="c",outputCol="c_idx")>>> ff = ss.fit(fd).transform(fd)>>> ff.show()+----+---+-----+|   x|  c|c_idx|+----+---+-----+| 1.0|  a|  0.0|| 1.5|  a|  0.0||10.0|  b|  1.0|| 3.2|  c|  2.0|+----+---+-----+

默认情况下,OneHotEncoder会丢弃最后一个类别:

>>> oe = OneHotEncoder(inputCol="c_idx",outputCol="c_idx_vec")>>> fe = oe.transform(ff)>>> fe.show()+----+---+-----+-------------+|   x|  c|c_idx|    c_idx_vec|+----+---+-----+-------------+| 1.0|  a|  0.0|(2,[0],[1.0])|| 1.5|  a|  0.0|(2,[0],[1.0])||10.0|  b|  1.0|(2,[1],[1.0])|| 3.2|  c|  2.0|    (2,[],[])|+----+---+-----+-------------+

当然,这种行为是可以改变的:

>>> oe.setDropLast(False)>>> fl = oe.transform(ff)>>> fl.show()+----+---+-----+-------------+|   x|  c|c_idx|    c_idx_vec|+----+---+-----+-------------+| 1.0|  a|  0.0|(3,[0],[1.0])|| 1.5|  a|  0.0|(3,[0],[1.0])||10.0|  b|  1.0|(3,[1],[1.0])|| 3.2|  c|  2.0|(3,[2],[1.0])|+----+---+-----+-------------+

问题:

  • 在什么情况下默认行为是可取的?
  • 盲目调用setDropLast(False)可能会忽略哪些问题?
  • 作者在文档中提到的以下陈述是什么意思?

默认情况下不包括最后一个类别(可以通过dropLast配置),因为这样可以使向量条目之和为1,从而线性相关。


回答:

根据文档,这是为了保持列的独立性:

一个一热编码器,将一列类别索引映射到一列二进制向量,每行最多只有一个值为1,表示输入类别索引。例如,对于5个类别,输入值2.0将映射到输出向量[0.0, 0.0, 1.0, 0.0]。默认情况下不包括最后一个类别(可以通过OneHotEncoder!.dropLast配置),因为这样可以使向量条目之和为1,从而线性相关。因此,输入值4.0映射到[0.0, 0.0, 0.0, 0.0]。请注意,这与scikit-learn的OneHotEncoder不同,后者保留所有类别。输出向量是稀疏的。

https://spark.apache.org/docs/1.5.2/api/java/org/apache/spark/ml/feature/OneHotEncoder.html

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注