如何在Scala中找到不同的ngram?

时间:2018-12-05 08:03:30

标签: scala nlp apache-spark-mllib n-gram

我有一个电子邮件地址,我想在email_alias上查找不同ngram的计数。假设gmail.com上的xyz是电子邮件。

email_alias是xyz。

因此,如果n等于2,则必须给出不同ngram的计数为2

def apply(in1:String,in2:Int):List[(Array[String], Int)] = {
   val email_alias = in1.split("@").toList
   val email_tokens = email_alias(0).split("") 
   val gram=email_tokens.sliding(in2).toList
   val fin=gram.groupBy(identity).mapValues(_.size).toList
   return fin
}


val str="xyzxyz@gmail.com"
apply(str,2)

输出如下。

res121: List[(Array[String], Int)] = List((Array(z, x),1), (Array(x, y),1), (Array(y, z),1), (Array(x, y),1), (Array(y, z),1))

2 个答案:

答案 0 :(得分:0)

第一个问题是您的退货类型。

您有List[(Array[String], Int)],它表示元组列表,其中第一个元素是字符串数组。因此,您将n-gram表示为长度为1的字符串数组。

我建议您将其更改为Seq[(String, Int)],这样您就可以用字符串表示的n-grams。

然后,您将字符串数组组合在一起。您可以使用mkString方法来实现。

最终代码是:

  def apply(in1: String, in2: Int): Seq[(String, Int)] = {
    val email_alias = in1.split("@").toList
    val email_tokens = email_alias(0).split("")
    val gram = email_tokens.sliding(in2).toList.map(_.mkString)
    val fin = gram.groupBy(identity).mapValues(_.size).toList
    return fin
  }


  val str = "xyzxyz@gmail.com"
  println(apply(str, 2))

答案 1 :(得分:0)

如果我正确理解,这就是您要寻找的:

def ngram(emailAddress: String, groupCount: Int): List[(String, Int)] =
  emailAddress
    .takeWhile(_ != '@')
    .sliding(groupCount)
    .toList
    .groupBy(identity)
    .mapValues(_.length)
    .toList

我认为每个步骤都是不言自明的,但是如果您需要更详细的说明,请添加注释。


您在注释中要求的特定值可以如下计算:

def ngramRatio(emailAddress: String, groupCount: Int): Float = {
  val prefix = emailAddress.takeWhile(_ != '@')
  val distinct = prefix.sliding(groupCount).toList.distinct.length

  distinct.toFloat / (prefix.length - groupCount + 1)
}