Spark MLlib / K-Means 直觉

Posted

技术标签:

【中文标题】Spark MLlib / K-Means 直觉【英文标题】:Spark MLlib / K-Means intuition 【发布时间】:2015-05-09 21:11:38 【问题描述】:

我对机器学习算法和 Spark 非常陌生。我跟着 在此处找到 Twitter 流语言分类器:

http://databricks.gitbooks.io/databricks-spark-reference-applications/content/twitter_classifier/README.html

具体这段代码:

http://databricks.gitbooks.io/databricks-spark-reference-applications/content/twitter_classifier/scala/src/main/scala/com/databricks/apps/twitter_classifier/ExamineAndTrain.scala

除了我试图在它拉出的一些推文上以批处理模式运行它 Cassandra,在这种情况下总共有 200 条推文。

如示例所示,我正在使用此对象“矢量化”一组推文:

object Utils
  val numFeatures = 1000
  val tf = new HashingTF(numFeatures)

  /**
   * Create feature vectors by turning each tweet into bigrams of
   * characters (an n-gram model) and then hashing those to a
   * length-1000 feature vector that we can pass to MLlib.
   * This is a common way to decrease the number of features in a
   * model while still getting excellent accuracy (otherwise every
   * pair of Unicode characters would potentially be a feature).
   */
  def featurize(s: String): Vector = 
    tf.transform(s.sliding(2).toSeq)
  

这是我从 ExaminAndTrain.scala 修改的代码:

 val noSets = rawTweets.map(set => set.mkString("\n"))

val vectors = noSets.map(Utils.featurize).cache()
vectors.count()

val numClusters = 5
val numIterations = 30

val model = KMeans.train(vectors, numClusters, numIterations)

  for (i <- 0 until numClusters) 
    println(s"\nCLUSTER $i")
    noSets.foreach 
        t => if (model.predict(Utils.featurize(t)) == 1) 
          println(t)
        
      
    

此代码运行,每个集群打印“集群 0”“集群 1”等 下面没有打印。如果我翻转

models.predict(Utils.featurize(t)) == 1 

models.predict(Utils.featurize(t)) == 0

除了每条推文都打印在每个集群下方之外,发生同样的事情。

这是我直觉认为正在发生的事情(请纠正我的 思考是否错误):这段代码将每条推文变成一个向量, 随机挑选一些集群,然后运行 ​​kmeans 对推文进行分组(在 一个非常高的水平,我认为集群很常见 “话题”)。因此,当它检查每条推文以查看 models.predict 是否 == 1,不同的推文集应该出现在每个集群下(并且 因为它会根据自己检查训练集,每条推文 应该在一个集群中)。为什么不这样做?无论是我的 对kmeans的理解是错误的,我的训练集也是 小,否则我错过了一步。

非常感谢任何帮助

【问题讨论】:

【参考方案1】:

首先,KMeans 是一种聚类算法,因此是无监督的。所以没有“针对自身检查训练集”(好吧,你可以手动进行;)。

实际上,您的理解非常好,只是您错过了 model.predict(Utils.featurize(t)) 为您提供了由 KMeans 分配的 t 所属的集群。我想你想检查一下

models.predict(Utils.featurize(t)) == i

在您的代码中,因为我遍历所有集群标签。

还有一点说明:特征向量是在推文的 字符 的 2-gram 模型上创建的。这个中间步骤很重要;)

2-gram (for words) 意思是:“一只熊对着一只熊大喊” => (A, Bear), (bear, throws), (shouts, at), (at, a), (a bear ) 即“一只熊”被计算两次。字符将是 (A,[space]), ([space], b), (b, e) 等等。

【讨论】:

它是bigrams of characters,所以它应该是("A ", " b", "be" ... 感谢您对 uberwatch 的回复。我进行了更改并打印了 5 个集群,除了集群 0 下有所有推文,而其余集群没有,我认为这意味着所有推文都被分配给集群 0。这是因为数据集太小了吗? (我认为在 databricks 提供的示例中,他们在大约 1200 万条推文上训练了 kmeans 模型,而我只使用了 200 条)。还是应该调整 numClusters/numIterations? 还是因为它根据语言对推文进行分类(就像在 databricks 示例中一样)?也许他们都被分配到集群 0,因为从高层次上讲,这是“英语”集群。这是因为它正在查看字符的二元组吗?查看二元组单词是否更类似于查看推文中的“主题”?如果是这样,如何修改 Utils 以使其创建单词而不是字符的二元组? 别在意最后一个问题,我看到 HashingTF.transform 接受推文字符串,您可以使用常见的字符串方法对其进行操作。最后一个问题,有没有办法查看集群选择了哪些点?我可以看到他们的向量然后从向量回到它对应的单词吗? 我不确定我是否正确理解了您的问题,但没有。散列应该是不可逆的。

以上是关于Spark MLlib / K-Means 直觉的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spark MLlib 做 K-means 聚类分析[转]

Spark MLlib K-Means 聚类

Spark 的 MLlib 库中预定义的 Streaming k-means 聚类是有监督的还是无监督的?

Java应用XIV使用Apache Spark MLlib构建机器学习模型下

使用 Mahout 向量训练 Spark k-means

Spark MLlib(下)--机器学习库SparkMLlib实战