Об ошибке относительно spark nlp при использовании scala - PullRequest
0 голосов
/ 28 февраля 2020

Я новичок в spark-nlp и изучаю его на следующих примерах в johnsnowlabs . Я использую SCALA в кирпичах данных.

Когда я следую примеру следующим образом,

import com.johnsnowlabs.nlp.base._
import com.johnsnowlabs.nlp.annotator._
import org.apache.spark.ml.Pipeline

val documentAssembler = new DocumentAssembler().
    setInputCol("text").
    setOutputCol("document")

val regexTokenizer = new Tokenizer().
    setInputCols(Array("sentence")).
    setOutputCol("token")
val sentenceDetector = new SentenceDetector().
    setInputCols(Array("document")).
    setOutputCol("sentence")

val finisher = new Finisher()
    .setInputCols("token")
    .setIncludeMetadata(true)


finisher.withColumn("newCol", explode(arrays_zip($"finished_token", $"finished_ner")))

При выполнении последней строки я получаю следующую ошибку:

command-786892578143744:2: error: value withColumn is not a member of com.johnsnowlabs.nlp.Finisher
finisher.withColumn("newCol", explode(arrays_zip($"finished_token", $"finished_ner")))

в чем может быть причина это ?

Когда я пытаюсь сделать пример, просто пропустив эту строку, я добавил следующие строки кода

val pipeline = new Pipeline().
    setStages(Array(
        documentAssembler,
        sentenceDetector,
        regexTokenizer,
        finisher
    ))

val data1 = Seq("hello, this is an example sentence").toDF("text")

pipeline.fit(data1).transform(data1).toDF("text")

При выполнении последней строки я получил еще одну ошибку:

java.lang.IllegalArgumentException: requirement failed: The number of columns doesn't match.

Может кто-нибудь помочь мне решить эту проблему?

Спасибо

Ответы [ 2 ]

2 голосов
/ 20 марта 2020

Вот как должен выглядеть ваш код, сначала создайте конвейер:

import com.johnsnowlabs.nlp.base._
import com.johnsnowlabs.nlp.annotator._
import org.apache.spark.ml.Pipeline

val documentAssembler = new DocumentAssembler().
    setInputCol("text").
    setOutputCol("document")

val regexTokenizer = new Tokenizer().
    setInputCols(Array("sentence")).
    setOutputCol("token")
val sentenceDetector = new SentenceDetector().
    setInputCols(Array("document")).
    setOutputCol("sentence")

val finisher = new Finisher()
    .setInputCols("token")
    .setIncludeMetadata(true)

val pipeline = new Pipeline().
    setStages(Array(
        documentAssembler,
        sentenceDetector,
        regexTokenizer,
        finisher
    ))

Создайте простой DataFrame для тестирования:

val data1 = Seq("hello, this is an example sentence").toDF("text")

Теперь мы подгоняем и преобразовываем ваш DataFrame в этом Конвейер:

val prediction = pipeline.fit(data1).transform(data1)

Переменная prediction - это DataFrame, в котором вы можете взорвать столбец токена. Давайте посмотрим внутрь prediction DataFrame:

scala> prediction.show
+--------------------+--------------------+-----------------------+
|                text|      finished_token|finished_token_metadata|
+--------------------+--------------------+-----------------------+
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|
+--------------------+--------------------+-----------------------+

scala> prediction.withColumn("newCol", explode($"finished_token")).show
+--------------------+--------------------+-----------------------+--------+
|                text|      finished_token|finished_token_metadata|  newCol|
+--------------------+--------------------+-----------------------+--------+
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|   hello|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|       ,|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|    this|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|      is|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|      an|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...| example|
|hello, this is an...|[hello, ,, this, ...|   [[sentence, 0], [...|sentence|
+--------------------+--------------------+-----------------------+--------+

  • Ваша первая проблема, как упомянул Альберто, думает, что finisher был DataFrame. Это аннотатор, пока он не преобразуется.

  • Вторая проблема заключалась в том, что .toDF () находился в месте, где он вам не нужен. (после преобразования конвейера)

  • Если ваша функция разнесения находится в плохом месте, вы архивируете столбец, который даже не существует в вашем конвейере: ner

Пожалуйста, не стесняйтесь задавать любые вопросы, и я соответствующим образом обновлю ответ.

1 голос
/ 13 марта 2020

Я думаю, что у вас есть две проблемы: 1. Во-первых, вы пытаетесь применить withColumn к аннотатору, вместо этого вы должны сделать это на кадре данных. 2. Я думаю, что это проблема, возникающая из toDF () после преобразования. Вам нужно больше столбцов, и вы предоставляете только 1. Также, вероятно, вам вообще не нужен этот toDF ().

Alberto.

...