我对机器学习算法和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个推文。正如示例所示,我正在使用此对象对一组推文进行“向量化”:
除了每个聚类下面打印出每条推文,其他事情都是一样的。
这里是我直觉上认为正在发生的事情(如果我错了,请纠正我的想法):此代码将每个推文转换为向量,随机选择一些聚类,然后运行kmeans以对推文进行分组(在非常高的层面上,我认为聚类应该是常见的“主题”)。因此,当它检查每个推文以查看models.predict == 1时,不同的推文集应该出现在每个聚类下面(并且因为它正在将训练集与自身进行比较,所以每个推文都应该在一个聚类中)。为什么它没有这样做?要么是我对kmeans的理解有误,要么是我的训练集太小,要么是我错过了某个步骤。
非常感谢任何帮助。
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)
}
}
}
这段代码运行后,每个聚类都会打印出“Cluster 0”、“Cluster 1”等,下面不会有任何内容打印。如果我翻转
models.predict(Utils.featurize(t)) == 1
to
models.predict(Utils.featurize(t)) == 0
除了每个聚类下面打印出每条推文,其他事情都是一样的。
这里是我直觉上认为正在发生的事情(如果我错了,请纠正我的想法):此代码将每个推文转换为向量,随机选择一些聚类,然后运行kmeans以对推文进行分组(在非常高的层面上,我认为聚类应该是常见的“主题”)。因此,当它检查每个推文以查看models.predict == 1时,不同的推文集应该出现在每个聚类下面(并且因为它正在将训练集与自身进行比较,所以每个推文都应该在一个聚类中)。为什么它没有这样做?要么是我对kmeans的理解有误,要么是我的训练集太小,要么是我错过了某个步骤。
非常感谢任何帮助。