Apache Spark ML Pipeline: фильтрация пустых строк в наборе данных - PullRequest
0 голосов
/ 19 ноября 2018

В моем Spark ML Pipeline (Spark 2.3.0) я использую RegexTokenizer следующим образом:

val regexTokenizer = new RegexTokenizer()
      .setInputCol("text")
      .setOutputCol("words")
      .setMinTokenLength(3)

Он преобразует DataFrame в тот, у которого есть массивы слов, например:

text      | words
-------------------------
a the     | [the]
a of to   | []
big small | [big,small]

Как отфильтровать строки с пустыми [] массивами?Должен ли я создать собственный преобразователь и передать его в конвейер?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы можете использовать SQLTransformer:

import org.apache.spark.ml.feature.SQLTransformer

val emptyRemover = new SQLTransformer().setStatement(
  "SELECT * FROM __THIS__ WHERE size(words) > 0"
)

, который может применяться непосредственно

val df = Seq(
  ("a the", Seq("the")), ("a of the", Seq()), 
  ("big small", Seq("big", "small"))
).toDF("text", "words")

emptyRemover.transform(df).show
+---------+------------+
|     text|       words|
+---------+------------+
|    a the|       [the]|
|big small|[big, small]|
+---------+------------+

или используется в Pipeline.

Тем не менее, я бы дважды подумал, прежде чем использовать это в процессе Spark ML. Инструменты, обычно используемые в нисходящем направлении, такие как CountVectorizer, могут нормально обрабатывать пустой ввод:

import org.apache.spark.ml.feature.CountVectorizer

val vectorizer = new CountVectorizer()
  .setInputCol("words")
  .setOutputCol("features")
+---------+------------+-------------------+                 
|     text|       words|           features|
+---------+------------+-------------------+
|    a the|       [the]|      (3,[2],[1.0])|
| a of the|          []|          (3,[],[])|
|big small|[big, small]|(3,[0,1],[1.0,1.0])|
+---------+------------+-------------------+

и отсутствие определенных слов часто может предоставить полезную информацию.

0 голосов
/ 19 ноября 2018
df
  .select($text, $words)
  .where(size($words) > 0)
...