【问题标题】:Spark/Scala group similar words and countSpark/Scala 对相似词进行分组并计数
【发布时间】:2019-12-17 07:46:11
【问题描述】:

我正在尝试对 rdd 中的单词进行分组和计数,这样如果单词以 s/ly 结尾,则将其计为同一个单词。

hi
yes
love
know
hi
knows
loves
lovely

预期输出:

hi 2
yes 1
love 3
know 2

这是我目前拥有的:

data.map(word=>(word,1)).reduceByKey((a,b)=>(a+b+).collect

感谢任何有关添加 s/ly 条件的帮助。

【问题讨论】:

  • 其实你的问题是模棱两可的。如果一个单词以 s 或 ly 结尾,它应该被视为没有 s 或 ly 的确切单词?例如可爱应该算爱情吗?
  • 添加了预期输出

标签: scala apache-spark apache-spark-sql rdd scala-collections


【解决方案1】:

您似乎想计算输入列表中的词干。在计算语言学中寻找词干的过程称为词干提取。如果您的目标是处理输入列表中单词末尾的 s 和 ly,您可以在 map 步骤中删除,然后计算剩余部分。事实上,盲目地去掉 s 和 ly 会有一些副作用。例如,如果有一个以 s 结尾的单词,例如“is”,您将在末尾数“i”。使用一些可用的词干分析器(如 Porter)或 Stanford Corenlp 中可用的词干分析器是一个更好的解决方案。

listRdd.mapToPair(t -> new Tuple2(t.replayAll("(ly|s)$", ""), 1))
.reduceByKey((a,b) -> a+b).collect()

第二种也可以帮助克服其他后缀的解决方案是使用词干分析器:

listRdd.mapToPair(t -> {
        Stemmer stemmer = new Stemmer();
        return new Tuple2(stemmer.stem(t), 1));
}).reduceByKey((a,b) -> a+b).collect();

about 词干分析器可以替换为词干分析器的任何实现。 有关词干分析器和词形还原器的更多信息,您可以使用https://nlp.stanford.edu/IR-book/html/htmledition/stemming-and-lemmatization-1.html

【讨论】:

    【解决方案2】:

    如果您想将以“s”或“ly”结尾的单词组合在一起,我会这样做:

    data
      .map(word => (if (word.endsWith('s') || word.endsWith('ly')) 's/ly-words' else word, 1))
      .reduceByKey(_+_)
      .collect
    

    如果您想将 'ly' 单词与 's' 单词与其他单词分开:

    data
      .map(word => (if (word.endsWith('s')) 's-words' else if (word.endsWith('ly')) 'ly-words' else word, 1))
      .reduceByKey(_+_)
      .collect
    

    如果您想计算以 'ly' 或 's' 结尾的单词,就好像它们不以它结尾一样(例如,'love'、'lovely'、'loves' 被视为 'love'):

    data
      .map(word => (if (word.endsWith('s')) word.slice(0, word.length-1) else if (word.endsWith('ly')) word.slice(0, word.length-2) else word, 1))
      .reduceByKey(_+_)
      .collect
    

    【讨论】:

      猜你喜欢
      • 2020-12-12
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 2023-01-04
      • 2012-07-17
      • 2018-11-20
      • 2015-03-13
      • 2015-02-14
      相关资源
      最近更新 更多