Apache Mahout基于商品的协同过滤算法流程分析
最近使用mahout的itemBase協同過濾算法,研究了下他的源碼,記錄如下,以備后忘……
其算法實現大致分四個主要的部分:
1.將輸入數據轉化成矩陣
2.計算相似性
3.還是轉化數據格式,為計算預測、推薦做準備
4.預測評分并做推薦
下面分別詳細介紹:
1.1?itemIDIndex
input:啟動計算時指定的--input路徑??output:***/preparePreferenceMatrix/itemIDIndex
mapper:ItemIdIndexMapper,將輸入中的userID,itemID,pref分隔后,將Long型itemID轉化成int型?的index。輸出類型(new?VarIntWritable(index),?new?VarLongWritable(itemID));
reducer:ItemIDIndexReducer,index為key聚合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聚合<itemID,pref>,輸出類型:VarLongWritable,VectorWritable
注:在此job的reducer中會累加計數user的數量到一個變量中。然后在此job完成后將用戶數寫到numUsers.bin中,便于后續job讀取用戶數。
1.3?toItemVectors
input:1.2的輸出??output:***/preparePreferenceMatrix/ratingMatrix
mapper:ToItemVectorsMapper,將1.2中<userID,VectorWritable<index,pref>……>,遍歷Vector輸出成<index,VectorWritable<userID,pref>……>
reducer:ToItemVectorsReducer,由于map中key是不知道是不是到下一個key的,所以map中寫文件的方式是map中每一個userID(是key)的每個評分(是VectorWritable)都寫一次,并以index作為key,并將此時的userID,pref給set到Vector中這樣同一個index中的vector在reduce聚合到一起中必有重復的,所以此處reduce就是做merge的。
至此準備工作就已經完成了
2.?計算相似度RowSimilarityJob
2.1?normsAndTranspose
input:1.3的輸出(***/preparePreferenceMatrix/ratingMatrix)??output:***/weights
mapper:VectorNormMapper,將ratingMatrix中的<itemID,<userID,pref>……>形式的數據,再轉化成<userID,<itemID,pref>……>的形式,同時記錄每個item的norms(double類型,如歐氏距離的話就是平方和),如果需要過濾最小評分的話會記錄item的評分數量和最大評分。最后將norms,nonZeroEntries,maxValues輸出
reducer:MergeVectorsReducer
同1.3mapper中輸出的vector會有重復的,在此進行merge輸出,并將map中norms,nonZeroEntries,maxValues的輸出寫入相應的hdfs文件中。
這個job同時有一個MergeVectorsCombiner,只是為了merge的。
2.2?pairwiseSimilarity
input:2.1的輸出(***/weights)??output:***/pairwiseSimilarity
mapper:CooccurrencesMapper
由于2.1的輸出是<userID,<itemID,pref>……>形式的,所以一個人同時對某兩個商品的評分就很容易得到,so,兩個循環遍歷每個用戶的評分列表,計算評分商品兩兩間的相似(多種相似度算法),輸出:<itemID,<itemID,aggregateValue>……>?(aggregateValue取的是乘積,[X1-X2]2=X12-2*X1X2+X22,此處計算乘積是為了便于reducer計算兩兩之間的相似度)
reducer:SimilarityReducer
同樣是先mager,但么有調用Vectors中的方法,而是從新寫了一個不知道為什么?
然后調用相應的相似度算法計算兩兩之間的相似度,以歐氏距離為例(較簡單)會調用norms中計算好的平方和。輸出為兩兩間的相似度<itemID,<itemID,pref>……>
2.3?asMatrix
input:2.2的輸出(***/pairwiseSimilarity)??output:***/similarityMatrix
mapper:UnsymmetrifyMapper
2.2中輸出的兩兩之間的相似度,此處取出topK個輸出,但這只是整個相似度矩陣的一半,所以需要輸出另一半,在此是和上面的一樣,每一個item都會輸出一個vector出來,這樣reducer必要做merge,當然另一半是輸出全部的,topK要到reducermerge后做。
reducer:MergeToTopKSimilaritiesReducer
同mapper中所說,此處完成merge和取topK,實際上就一半的矩陣需要處理。
至此相似度就已經算完了
3?下面開始為推薦做準備
3.1?prePartialMultiply1
input:2.3的輸出(***/similarityMatrixPath)??output:***/prePartialMultiplyPath1
mapper:SimilarityMatrixRowWrapperMapper,直接輸出,只是添加了自身的相似度為NAN,輸出類型VectorOrPrefWritable,這里是前者Vecotr
reducer:Reducer,hadoop自身的,沒啥說的,正常聚合。
3.2?prePartialMultiply2
input:1.2的輸出(***/preparePreferenceMatrix/userVectors)??output:***/prePartialMultiplyPath2
mapper:UserVectorSplitterMapper
在此只是如果有usersToRecommendFor的話就只輸出usersToRecommendFor中的用戶的評分向量,沒有的話默認是輸出全部的用戶評分向量。還有過濾下每個用戶的評分數量,默認是去10個評分,來預測。
reducer:Reducer,同上
其實prePartialMultiply1和prePartialMultiply2只是將數據稍做處理,然后輸出相同的數據類型,這樣便于下步將評分數據和item的相似數據聚合。
3.3?partialMultiply
input:3.1和3.2的輸出(***/prePartialMultiplyPath1、2)??output:***/prePartialMultiplyPath
mapper:Mapper
reducer:ToVectorAndPrefReducer,將聚合在一起的VectorOrPrefsWritable類型,封裝成VectorAndPrefsWritable類型。
4?預測并推薦
4.1?itemFiltering?推薦商品過濾
input:啟動時指定的路徑(***/filterFile)??output:***/explicitFilterPath
mapper:ItemFilterMapper
reducer:ItemFilterAsVectorAndPrefsReducer
較簡單,只是最后聚合輸出成VectorAndPrefsWritable類型,跟3.3保持一致
4.2?aggregateAndRecommend?聚合推薦(關鍵的一步)
input:3.3的輸出(***/prePartialMultiplyPath)??output:啟動時指定的路徑
mapper:PartialMultiplyMapper
VectorAndPrefsWritable保存的是對同一個item評過分的用戶的評分及此item的相似矩陣,此map輸出以userID為key,以PrefAndSimilarityColumnWritable<pref,simiMartixVactor>類型為value,這樣同一個user評過分的商品評分及相似矩陣都可以聚到一起,供reducer做預測評分。
reducer:AggregateAndRecommendReducer
reduce聲明了Vector?numerators(分子)?和Vector?denominators(分母),numerators使用相似向量乘以評分,得到多個向量,再將向量相加得到,denominators是直接將多個評分得到的向量相加得到,預測評分是用numerators/denominators
最后通過writeRecommendedItems(userID,?recommendationVector,?context)采用優先隊列取到topK的推薦數據
?
轉載于:https://www.cnblogs.com/zeng-wei/archive/2013/05/31/3110313.html
總結
以上是生活随笔為你收集整理的Apache Mahout基于商品的协同过滤算法流程分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Svn 中 Bin ,
- 下一篇: android-apt-compiler