如何使用Spark ML推荐大多数类似用户

时间:2016-07-12 04:57:17

标签: apache-spark machine-learning apache-spark-mllib recommendation-engine

我有一个关于表格中特定项目的用户偏好的数据:

user, item, preference  
1,    75,   0.89  
2,    168,  0.478  
2,    99,   0.321  
3,    31,   0.012

对于每个用户,我需要根据他们的偏好建立前N个最相似的用户。该系统有数千个用户和项目。建议将在批处理过程中生成,并在Elasticsearch上提供。 在Mahout中,简单的算法可能会像:

  val similarity:UserSimilarity=new PearsonCorrelationSimilarity(dataModel)
  val neighborhood:UserNeighborhood  = new ThresholdUserNeighborhood(0.75, similarity, dataModel)
  val userBasedRecommender:UserBasedRecommender  = new GenericUserBasedRecommender(dataModel, neighborhood, similarity);
  val userid=1
  val howMany=10
  val mostSimilarUserIDs = userBasedRecommender.mostSimilarUserIDs(userid, howMany);

我想使用Spark ML实现它,但找不到任何可以帮助我继续前进的类似示例。

到目前为止,我实现了使用余弦相似性的方法,将一个用户特征向量与其他用户进行比较:

def cosineSimilarity(vec1: DoubleMatrix, vec2: DoubleMatrix): Double=
{
    vec1.dot(vec2)/(vec1.norm2()*vec2.norm2())
}
def user2usersimilarity(userid:Integer, recNumber:Integer): Unit ={
    val userFactor=model.userFeatures.lookup(userid).head
    val userVector=new DoubleMatrix(userFactor)
    val s1=cosineSimilarity(userVector,userVector)
    val sims=model.userFeatures.map{case(id,factor)=>
        val factorVector=new DoubleMatrix(factor)
        val sim=cosineSimilarity(factorVector, userVector)
        (id,sim)
    }
    val sortedSims=sims.top(recNumber+1)(Ordering.by[(Int, Double),Double] {case(id, similarity)=>similarity})
    println(sortedSims.slice(1,recNumber+1).mkString("\n"))
 }

此方法适用于MovieLens数据集的推荐质量。但是,我关心的是这种算法的性能。由于我必须为系统中的所有用户生成建议,因此我将使用此方法将每个用户与系统中的所有其他用户进行比较。

如果有人可以建议如何限制用户与前N个邻居的比较,或者其他一些在我的用例中效果更好的算法,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

如何使用聚类算法?,训练一次,部署模型,使用模型识别新示例所属的集群,然后随机推荐同一集群中的用户?这只是一个想法...

答案 1 :(得分:0)

使用交替最小二乘法查看Spark 协作过滤http://spark.apache.org/docs/latest/ml-collaborative-filtering.html

它是为这种情况精心打造的。

  

协作过滤

     

协同过滤通常用于推荐系统。   这些技术旨在填写用户项的缺失条目   关联矩阵。 spark.ml目前支持基于模型   协同过滤,其中描述了用户和产品   一小组可用于预测失踪的潜在因素   条目。 spark.ml使用交替最小二乘(ALS)算法   了解这些潜在因素。

鉴于您有实际的偏好/评分,您可以使用 显式偏好 方法(而不是隐式)。