Spark之K-均值算法中的一些问题
今天看了一个千人千面推荐系统的公开课,原理上来说并不难,主要是使用K均值算法,在之前学过了Spark下K均值算法之后,便尝试使用K均值算法去模拟简单的千人千面推荐系统,以后有时间在慢慢研究用户画像
数据
数据由用户id,该用户访问19个网站的次数组成,如下所示
1,83,92,72,62,71,0,49,0,10,0,0,0,0,26,84,0,3,0,0
2,81,91,71,61,71,0,0,6,39,3,0,0,0,0,107,1,107,4,0
3,84,92,74,62,122,123,0,63,42,0,0,0,1,81,0,0,0,0,0
4,82,92,72,62,9,0,0,0,11,0,0,0,62,62,0,0,0,0,33
5,81,91,71,61,167,0,25,0,114,0,0,0,0,0,167,0,0,0,0
6,82,92,72,115,134,3,0,0,62,0,0,167,0,0,169,0,0,0,0
7,83,93,73,63,46,0,0,0,43,0,10,0,0,0,27,0,5,0,0
8,82,92,72,62,49,0,0,0,44,0,0,0,0,0,75,0,3,0,0
数据总共两万条
完整代码
直接使用Spark Mllib的API,还是比较方便的,中间遇到了一些问题,例如
java.lang.NumberFormatException: empty String
检查文件路径并没有问题,百度后明白了在数据切割的时候产生的空字符串也会导致提示empty string,处理空数据掉就行了,在这里将空值默认为"0",修改后的代码如下
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
object justTest {
def main(args: Array[String]): Unit={
val sparkConf=new SparkConf().setAppName("justTest").setMaster("local").set("spark.executor.memory", "3g")
val sc=new SparkContext(sparkConf)
val input="file:///media/hadoop/文档/KmeanData.txt"
val k=10
val iterations=100
val data=sc.textFile(input)
val parsedData=data.map(s=>{
val ned=s.split(",").drop(1)
// 过滤空值
for(i<- 0 to ned.length-1){
if(ned(i).isEmpty) ned(i)="0"
}
Vectors.dense(ned.map(_.toDouble))
}).cache()
val model=KMeans.train(parsedData,k,iterations,KMeans.K_MEANS_PARALLEL)
//k个簇心
println("Cluster centers: ")
model.clusterCenters.foreach(println)
val cost=model.computeCost(parsedData)
print(s"Cost :${cost}")
sc.stop()
}
}
运行成功,得出K个簇心
完整数据集就不上传了(不会上传QAQ)