ALS 是什么?
ALS 是交替最小二乘 (alternating least squares)的简称。
在机器学习的上下文中,ALS 特指使用交替最小二乘求解的一个协同推荐算法。
它通过观察到的所有用户给产品的打分,来推断每个用户的喜好并向用户推荐适合的产品。
协同过滤 常被应用于推荐系统,旨在补充用户-商品关联矩阵中所缺失的部分。
MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐语义因子进行表达,
并且这些因子也用于预测缺失的元素。Spark MLlib实现了 交替最小二乘法 (ALS)
来学习这些隐性语义因子。在 MLlib 中的实现有如下的参数:
•numBlocks 是用于并行化计算的分块个数 (设置为-1,为自动配置)。
•rank 是模型中隐语义因子的个数。
•iterations 是迭代的次数。
•lambda 是ALS的正则化参数。
•implicitPrefs 决定了是用显性反馈ALS的版本还是用适用隐性反馈数据集的版本。
•alpha 是一个针对于隐性反馈 ALS 版本的参数,这个参数决定了偏好行为强度的基准。
可以调整这些参数,不断优化结果,使均方差变小。比如:iterations越多,lambda较小,均方差会较小,推荐结果较优。
注意上面说可以利用隐性因子预测缺失元素。下面结合数据讲解下:
1,1,5.0
1,2,1.0
1,3,5.0
1,4,1.0
2,2,1.0
2,3,5.0
2,4,1.0
3,1,1.0
3,2,5.0
3,3,1.0
3,4,5.0
4,1,1.0
4,2,5.0
4,3,1.0
4,4,5.0
第一个数据,表示用户id,第二数据则表示,产品id,第三则是评分。
注意这里缺失第二个用户对第一个产品的评分,算法仍然可以根据第二用户与其他用户的评分相似度,从而预测对第一个产品的评分,从而根据评分是否要将产品进行推送。
import org.apache.spark.{SparkContext, SparkConf}
import org.apache.spark.mllib.recommendation.{ALS, Rating}
/**
* Created by Administrator on 2016/8/16.
*/
object RecommendationExample2 {
def main(args: Array[String]) {
val conf =new SparkConf().setAppName("RecommendationExample2").setMaster("local");
val sc = new SparkContext(conf)
//加载数据
val data = sc.textFile("file///F:/1/alstest.txt")
val ratings=data.map(_.split(",")match{case Array(user,item,rate)=>
Rating(user.toInt,item.toInt,rate.toDouble)
})
// 训练模型
val rank = 10//是模型中隐语义因子的个数。
val numIterations = 5
val lambda =0.01 //是ALS的正则化参数。
val model=ALS.train(ratings,rank,numIterations,lambda)
val usersProducts=ratings.map{case Rating(user,item,rate)=>
(user,item)
}
val predictions =model.predict(usersProducts)
// println("_----------------------------------predictions-------------------------------")
//predictions.foreach(println)
//这里的结果其实和上面的结果没有太多的不同,只是将评分与用户id产品id分割了下
val predictions2=model.predict(usersProducts).map{case Rating(user,item,rate)=>
((user,item),rate)
}
//println("------------------------------predictions2-------------------------------")
// predictions2.foreach(println)
//合并原始数据和评分
val ratesAndPreds=ratings.map{case Rating(user,item,rate)=>
((user,item),rate)
}.join(predictions2)//注意要是同类的才能合并,这里就不能直接合并predictions
// println("=========================ratesAndPreds=========================")
// ratesAndPreds foreach(println)
//然后计算均方差,注意这里没有调用 math.sqrt方法
val MSE=ratesAndPreds.map{case((user,item),(r1,r2))=>
val err=r1-r2
err*err
}.mean()
//打印出方差结果
println("Mean Squared Error = " + MSE)
//获得用户的id
val users=data.map(_.split(",")match {
case Array(user,item,rate)=>(user)
}).distinct().collect()
//循环用户,将id传给模型
users.foreach(
user=>{
var rs=model.recommendProducts(user.toInt,numIterations)//通过模型对用户进行商品的评分推送
var value = ""
var key = 0
rs.foreach(
r=>{
key=r.user
value=value+r.product+":"+r.rating+","
})
println(key.toString+" " + value)
})
/*val rs=model.recommendProductsForUsers(numIterations)
rs.foreach(r=>
r._2.foreach(x=>
print(x.toString)
)
//println(r._1+":"+r._2.toString)
)*/
}
}
转自:http://blog.csdn.net/young_so_nice/article/details/52221324