Почему OneHotEncoder от Spark по умолчанию отбрасывает последнюю категорию?

Я хотел бы понять, почему в OneHotEncoder Spark по умолчанию отбрасывается последняя категория.

Например:

>>> 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 ответ

Решение

Согласно документу, колонка должна быть независимой:

Одноразовый кодировщик, который отображает столбец индексов категории в столбец двоичных векторов, самое большее с одним значением в строке, которое указывает индекс входной категории. Например, для 5 категорий входное значение 2,0 будет соответствовать выходному вектору [0,0, 0,0, 1,0, 0,0]. Последняя категория не включена по умолчанию (настраивается через OneHotEncoder!.DropLast, потому что она делает векторные записи суммирующими до единицы и, следовательно, линейно зависимыми. Таким образом, входное значение 4,0 отображается на [0,0, 0,0, 0,0, 0,0]. Примечание то, что это отличается от OneHotEncoder scikit-learn, который сохраняет все категории. Выходные векторы редки.

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

Другие вопросы по тегам