6

我有一个要求,我必须在词形还原步骤中添加字典。在尝试在管道中使用它并执行 pipeline.fit() 时,我得到一个 arrayIndexOutOfBounds 异常。实现这一点的正确方法是什么?有什么例子吗?

我将令牌作为输入列进行词形还原,将引理作为输出列。以下是我的代码:

    // DocumentAssembler annotator
    val document = new DocumentAssembler()
        .setInputCol("text")
        .setOutputCol("document")
    // SentenceDetector annotator
    val sentenceDetector = new SentenceDetector()
        .setInputCols("document")
        .setOutputCol("sentence")
    // tokenizer annotaor
    val token = new Tokenizer()
        .setInputCols("sentence")
        .setOutputCol("token")
    import com.johnsnowlabs.nlp.util.io.ExternalResource
     // lemmatizer annotator
    val lemmatizer = new Lemmatizer()
        .setInputCols(Array("token"))
        .setOutputCol("lemma")
     .setDictionary(ExternalResource("C:/data/notebook/lemmas001.txt","LINE_BY_LINE",Map("keyDelimiter"->",","valueDelimiter"->"|")))
    val pipeline = new Pipeline().setStages(Array(document,sentenceDetector,token,lemmatizer))
    val result= pipeline.fit(df).transform(df)

错误信息是:

    Name: java.lang.ArrayIndexOutOfBoundsException
    Message: 1
    StackTrace:   at com.johnsnowlabs.nlp.util.io.ResourceHelper$$anonfun$flattenRevertValuesAsKeys$1$$anonfun$apply$14.apply(ResourceHelper.scala:315)
      at com.johnsnowlabs.nlp.util.io.ResourceHelper$$anonfun$flattenRevertValuesAsKeys$1$$anonfun$apply$14.apply(ResourceHelper.scala:312)
      at scala.collection.Iterator$class.foreach(Iterator.scala:891)
      at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
      at com.johnsnowlabs.nlp.util.io.ResourceHelper$$anonfun$flattenRevertValuesAsKeys$1.apply(ResourceHelper.scala:312)
      at com.johnsnowlabs.nlp.util.io.ResourceHelper$$anonfun$flattenRevertValuesAsKeys$1.apply(ResourceHelper.scala:312)
      at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
      at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
      at com.johnsnowlabs.nlp.util.io.ResourceHelper$.flattenRevertValuesAsKeys(ResourceHelper.scala:312)
      at com.johnsnowlabs.nlp.annotators.Lemmatizer.train(Lemmatizer.scala:52)
      at com.johnsnowlabs.nlp.annotators.Lemmatizer.train(Lemmatizer.scala:19)
      at com.johnsnowlabs.nlp.AnnotatorApproach.fit(AnnotatorApproach.scala:45)
      at org.apache.spark.ml.Pipeline$$anonfun$fit$2.apply(Pipeline.scala:153)
      at org.apache.spark.ml.Pipeline$$anonfun$fit$2.apply(Pipeline.scala:149)
      at scala.collection.Iterator$class.foreach(Iterator.scala:891)
      at scala.collection.AbstractIterator.foreach(Iterator.scala:1334)
      at scala.collection.IterableViewLike$Transformed$class.foreach(IterableViewLike.scala:44)
      at scala.collection.SeqViewLike$AbstractTransformed.foreach(SeqViewLike.scala:37)
      at org.apache.spark.ml.Pipeline.fit(Pipeline.scala:149)
4

1 回答 1

2

您的管道对我来说看起来不错,所以一切都取决于内部的内容lemmas001.txt以及您是否能够在 Windows 上访问它。

注意:我看到 Windows 上的用户在 Apache Spark 中使用它:

"C:\\Users\\something\\Desktop\\someDirectory\\somefile.txt"

如何Lemmatizer在 Spark NLP 中进行训练很简单:

val lemmatizer = new Lemmatizer()
    .setInputCols(Array("token"))
    .setOutputCol("lemma")
    .setDictionary("AntBNC_lemmas_ver_001.txt", "->", "\t")

该文件必须具有以下格式,keyDelimiter在这种情况下是->valueDelimiter\t

abnormal    ->  abnormal    abnormals
abode   ->  abode   abodes
abolish ->  abolishing  abolished   abolish abolishes
abolitionist    ->  abolitionist    abolitionists
abominate   ->  abominate   abominated  abominates
abomination ->  abomination abominations
aboriginal  ->  aboriginal  aboriginals
aborigine   ->  aborigines  aborigine
abort   ->  aborted abort   aborts  aborting
abortifacient   ->  abortifacients  abortifacient
abortionist ->  abortionist abortionists
abortion    ->  abortion    abortions
abo ->  abo abos
abotrite    ->  abotrites   abotrite
abound  ->  abound  abounds abounding   abounded

此外,如果您不想训练自己的 Lemmatizer,可以使用以下预训练模型:

英语

val lemmatizer = new LemmatizerModel.pretrained(name="lemma_antbnc", lang="en")
    .setInputCols(Array("token"))
    .setOutputCol("lemma")

法语

val lemmatizer = new LemmatizerModel.pretrained(name="lemma", lang="fr")
    .setInputCols(Array("token"))
    .setOutputCol("lemma")

意大利语

val lemmatizer = new LemmatizerModel.pretrained(name="lemma", lang="it")
    .setInputCols(Array("token"))
    .setOutputCol("lemma")

德语

val lemmatizer = new LemmatizerModel.pretrained(name="lemma", lang="de")
    .setInputCols(Array("token"))
    .setOutputCol("lemma")

所有预训练模型的列表在这里: https ://nlp.johnsnowlabs.com/docs/en/models

所有预训练管道的列表在这里: https ://nlp.johnsnowlabs.com/docs/en/pipelines

如果您有更多问题,请在评论中告诉我。

全面披露:我是 Spark NLP 库的贡献者之一。

更新:如果您感兴趣,我在 Databricks 上的 Scala 中为您找到了这个示例(这实际上是他们训练意大利 Lemmatizer 模型的方式)

于 2019-09-10T14:51:26.230 回答