Apache Mahout基于商品的协同过滤算法流程分析

 2023-02-26    294  

最近使用mahout的itemBase协同过滤算法,研究了下他的源码,记录如下,以备后忘……

其算法实现大致分四个主要的部分:

Apache Mahout基于商品的协同过滤算法流程分析

1.将输入数据转化成矩阵

2.计算相似性

3.还是转化数据格式,为计算预测、推荐做准备

4.预测评分并做推荐

下面分别详细介绍:

  1. PreparePreferenceMatrixJob

1.1 itemIDIndex

input:启动计算时指定的–input路径  output***/preparePreferenceMatrix/itemIDIndex

mapper:ItemIdIndexMapper,将输入中的userIDitemIDpref分隔后,将LongitemID转化成int型 的index。输出类型(new VarIntWritable(index), new VarLongWritable(itemID));

reducerItemIDIndexReducer,indexkey聚合itemID取出最小的itemID输出。输出类型同mapper

1.2 toUserVectors

input:启动计算时指定的–input路径  output***/preparePreferenceMatrix/userVectors

mapper:ToEntityPrefsMapper,输出类型(new VarLongWritable(userID), new EntityPrefWritable(itemID, prefValue))

reducer:ToUserVectorsReducer,map输出中的itemID转成index,通过userID聚合<itemIDpref>,输出类型:VarLongWritable,VectorWritable

注:在此jobreducer中会累加计数user的数量到一个变量中。然后在此job完成后将用户数写到numUsers.bin中,便于后续job读取用户数。

1.3 toItemVectors

input1.2的输出  output***/preparePreferenceMatrix/ratingMatrix

mapperToItemVectorsMapper,将1.2<userID,VectorWritable<index,pref>……>,遍历Vector输出成<index,VectorWritable<userID,pref>……>

reducer:ToItemVectorsReducer,由于mapkey是不知道是不是到下一个key的,所以map中写文件的方式是map中每一个userID(是key)的每个评分(是VectorWritable)都写一次,并以index作为key,并将此时的userID,prefsetVector中这样同一个index中的vectorreduce聚合到一起中必有重复的,所以此处reduce就是做merge的。

至此准备工作就已经完成了

2. 计算相似度RowSimilarityJob

2.1 normsAndTranspose

input1.3的输出(***/preparePreferenceMatrix/ratingMatrix)  output***/weights

mapper:VectorNormMapper,ratingMatrix中的<itemID,<userID,pref>……>形式的数据,再转化成<userID,<itemID,pref>……>的形式,同时记录每个itemnormsdouble类型,如欧氏距离的话就是平方和),如果需要过滤最小评分的话会记录item的评分数量和最大评分。最后将normsnonZeroEntriesmaxValues输出

reducerMergeVectorsReducer

1.3mapper中输出的vector会有重复的,在此进行merge输出,并将mapnormsnonZeroEntriesmaxValues的输出写入相应的hdfs文件中。

这个job同时有一个MergeVectorsCombiner,只是为了merge的。

2.2 pairwiseSimilarity

input2.1的输出(***/weights)  output***/pairwiseSimilarity

mapperCooccurrencesMapper

由于2.1的输出是<userID,<itemID,pref>……>形式的,所以一个人同时对某两个商品的评分就很容易得到,so,两个循环遍历每个用户的评分列表,计算评分商品两两间的相似(多种相似度算法),输出:<itemID,<itemID,aggregateValue>……> (aggregateValue取的是乘积,[X1-X2]2=X12-2*X1X2+X22,此处计算乘积是为了便于reducer计算两两之间的相似度)

reducerSimilarityReducer

同样是先mager,但么有调用Vectors中的方法,而是从新写了一个不知道为什么?

然后调用相应的相似度算法计算两两之间的相似度,以欧氏距离为例(较简单)会调用norms中计算好的平方和。输出为两两间的相似度<itemID,<itemID,pref>……>

2.3 asMatrix

input2.2的输出(***/pairwiseSimilarity)  output***/similarityMatrix

mapper:UnsymmetrifyMapper

2.2中输出的两两之间的相似度,此处取出topK个输出,但这只是整个相似度矩阵的一半,所以需要输出另一半,在此是和上面的一样,每一个item都会输出一个vector出来,这样reducer必要做merge,当然另一半是输出全部的,topK要到reducermerge后做。

reducerMergeToTopKSimilaritiesReducer

mapper中所说,此处完成merge和取topK,实际上就一半的矩阵需要处理。

至此相似度就已经算完了

下面开始为推荐做准备

3.1 prePartialMultiply1

input2.3的输出(***/similarityMatrixPath)  output***/prePartialMultiplyPath1

mapperSimilarityMatrixRowWrapperMapper,直接输出,只是添加了自身的相似度为NAN,输出类型VectorOrPrefWritable,这里是前者Vecotr

reducerReducerhadoop自身的,没啥说的,正常聚合。

3.2 prePartialMultiply2

input1.2的输出(***/preparePreferenceMatrix/userVectors)  output***/prePartialMultiplyPath2

mapperUserVectorSplitterMapper

在此只是如果有usersToRecommendFor的话就只输出usersToRecommendFor中的用户的评分向量,没有的话默认是输出全部的用户评分向量。还有过滤下每个用户的评分数量,默认是去10个评分,来预测。

reducerReducer,同上

其实prePartialMultiply1prePartialMultiply2只是将数据稍做处理,然后输出相同的数据类型,这样便于下步将评分数据和item的相似数据聚合。

3.3 partialMultiply

input3.13.2的输出(***/prePartialMultiplyPath12)  output***/prePartialMultiplyPath

mapperMapper

reducerToVectorAndPrefReducer,将聚合在一起的VectorOrPrefsWritable类型,封装成VectorAndPrefsWritable类型。

预测并推荐

4.1 itemFiltering 推荐商品过滤

input:启动时指定的路径(***/filterFile)  output***/explicitFilterPath

mapperItemFilterMapper

reducerItemFilterAsVectorAndPrefsReducer

较简单,只是最后聚合输出成VectorAndPrefsWritable类型,跟3.3保持一致

4.2 aggregateAndRecommend 聚合推荐(关键的一步)

input3.3的输出(***/prePartialMultiplyPath)  output:启动时指定的路径

mapperPartialMultiplyMapper

VectorAndPrefsWritable保存的是对同一个item评过分的用户的评分及此item的相似矩阵,此map输出以userIDkey,以PrefAndSimilarityColumnWritable<pref,simiMartixVactor>类型为value,这样同一个user评过分的商品评分及相似矩阵都可以聚到一起,供reducer做预测评分。

reducerAggregateAndRecommendReducer

reduce声明了Vector numerators(分子) 和Vector denominators(分母),numerators使用相似向量乘以评分,得到多个向量,再将向量相加得到,denominators是直接将多个评分得到的向量相加得到,预测评分是用numerators/denominators

最后通过writeRecommendedItems(userID, recommendationVector, context)采用优先队列取到topK的推荐数据

 

以上所述是小编给大家介绍的Apache Mahout基于商品的协同过滤算法流程分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:http://www.77isp.com/post/34625.html

=========================================

http://www.77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。