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

How to find distinct ngrams in scala?

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

email_alias 是 xyz 。

所以它必须给出不同 ngram 的计数是 2 如果这里的 n 是 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))

第一个问题是你的 return 类型。

你有 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))

如果我没理解错的话,这就是你要找的:

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)
}