日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mahout基于Hadoop的CF代码分析(转)

發布時間:2025/3/19 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mahout基于Hadoop的CF代码分析(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

來自:http://www.codesky.net/article/201206/171862.html

mahout的taste框架是協同過濾算法的實現。它支持DataModel,如文件、數據庫、NoSQL存儲等,也支持Hadoop的MapReduce。這里主要分析的基于MR的實現。

基于MR的CF實現主要流程就在 org.apache.mahout.cf.taste.Hadoop.item.RecommenderJob類中(注意mahout有兩個 RecommendJob,要看清楚是哪一個包)。這 個類的run方法就包含了所有的步驟。從上到下,完整的其實有10步(中間計算item相似度其實拆分成了3個job,我們也當做是一個phase吧), 也就是說,如果指定了所有的必要參數,運行一次item-based CF算法,會執行12個JOB,當然有的步驟是可以忽略的,下面會講。以下就是詳細的每一步驟的分析:

phase1: itemIDIndex

這步主要是將itemId轉成一個int。這里設計上其實有點小問題,如果item的數量非常多,比如超過int的最大值,那就有可能會出現重合了。所以用long其實更為合適。

?? input:用戶評分文件(這也是我們最原始的輸入了),格式一般為:userId t itemId t score。注意輸入必須是textfile的。可能是為了方便測試吧,mahout的很多包默認輸出都是textfile格式的。

???map:(index,?itemId)

???reduce: (index, itemId)

phase2: toUserVector

?? input:用戶評分文件

? ?param: --userBooleanData如果這個參數為true,則會忽略評分列,對于買或不買這類數據有時需要指這定這個值。

???map: (userId, itemId,pref)

? ?reduce: 以用戶為key,輸出成向量形式è (userId, VectorWritable<itemId, pref>)

phase3: countUser,計算用戶數

? ?map: (userId)

? ?reduce: 輸出總用戶數count

phase4: maybePruneAndTranspose

? ?input: phase2的輸出:userVector

? ?param: --maxCooccurrences

? ?map: (userId,Vector<itemId, pref>) è(itemId,DistributedRowMatrix<userId,pref>),注意如果指定了—maxCooccurrences參數,這里會有裁剪,www.codesky.net?每個userId最多對maxCooccurrencesitemId打分

?? 這里的DistributedRowMatrix,分布式行矩陣:行:itemId, 列:userId

? ?reduce: (itemId, VectorWritable<userId,pref>)

phase5: RowSimilarityJob

這一步比較關鍵,計算item相似度,它拆分成了三個JOB

? ?param: --numberOfColumns, --similarityClassname,--maxSimilaritiesPerRow(默認:100)

???job1:weight

????? input:phase4的輸出

? ? ? ?map: (itemId, VectorWritable <userId, pref>) ==>(userId, WeightedOccurrence<itemId, pref, weight>)

? ? ? ?這里的weight,對于歐氏向量距離,或者Pearson距離等,均為Double.NaN,即無效。在LoglikelihoodVectorSimilarity中有用到weight的值。

? ?? ? reduce:(userId,?WeightedOccurrenceArray<itemId, pref, weight>)

???job2:pairwise similarity?*item相似度計算*

?? ? ?map: 對同一用戶的所有item-rating,輸出兩兩item之間的關系 ==>(WeightedRowPair<itemA, itemB, weightA, weightB>, coocurrence<userId,valueA, valueB>) (同上,這里的權重weightA,B對于歐氏距離等可以忽略)

?? ? ? reduce: 在這端,以<itemA,itemB>為key聚合了來自不同map的所有用戶的 打分,最后輸出itemA和B的對稱相似度(即以itemA為key或以itemB為key)==> (SimilarityMatrixEntryKey<itemA,similarity>, MatrixEntryWritable<WeightedRowPair<itemA, itemB,weightA, weightB>>)?, (SimilarityMatrixEntryKey<itemB,similarity>,?MatrixEntryWritable<WeightedRowPair<itemB, itemA,weightB, weightA>>)

???job3:entries2vectors?*匯總item的相似items*

????? param: --maxSimilaritiesPerRow

?? ?? map:?(itemA, itemB,?similarity) & (itemB,itemA,?similarity) 這里在group的時候按相似度降序做了排序,如果有--maxSimilaritiesPerRow參數,則會做裁剪。

?? ?? reduce: (itemA, VectorWritable <item,similarity>)

至此,item相似度計算完畢。

phase6:?prePartialMultiply1?

?? input: phase5的最后輸出(即item相似度)

?? map: 直接輸出item對應的相似items,這里用VectorOrPrefWritable做了封裝,表明有可能是相似度向量,也有可能是對item的打分,并且對item為自己的,將相似度設為Double.NaN,以過濾自身。è(itemId,VectorOrPrefWritable<item, similarity>)

? ? reduce: IdentityReducer

phase7:?prePartialMultiply2

? ?input: phase2的輸出userVectors

? ?map: 輸出:(itemId, VectorOrPrefWritable<userId, pref>)

???這里默認考慮用戶對10個item的評分,可以通過maxPrefsPerUserConsidered參數調整。

? ?如果指定了usersFile,則在setup時會把所有的userId讀入內存,用于過濾。如果map輸入數據的userID不在usersFile中,則會被忽略。注意,這是mahout的設計bug,對于比較大的數據集,很有可能造成OOM(事實上在我的測試程序中已經出現OOM了…),這種bug下面還會出現。輸出的是用戶的評分,同phase6的VectorOrPrefWritable的封裝。

? ?reduce:?IdentityReducer

phase8:?partialMultiply

? ? ?input: 6和7的輸出:prePartialMultiply1,?prePartialMultiply2

? ? ?map:?Identity。由于6和7的輸出的key均為itemId,因而在reduce端同一item的相似item以及對應的用戶評分會聚合到一起。

? ? ?reduce:(itemId,?VectorAndPrefsWritable<similarityMatrix, List<userId>,List<pref>>) 沒做特殊處理,直接合在一起,輸出相似度矩陣,所有的userId及對item的打分。

phase9:?itemFiltering?

? ? 將過濾文件輸出成<userId, itemId>。如果指定了--filterFile參數,則在最后的聚合推薦中會過濾userId對應的items。這一步在實際中多數是可以忽略的,只要不指定這個參數即可。

phase10:?aggregateAndRecommend

? ? map: 對每個用戶,輸出對當前item的評分,以及與當前item的所有相似 itemsè(userId,?PrefAndSimilarityColumnWritable<pref,vector<item, similarity>>)

? ?reduce: 聚合了這個用戶所有的評分歷史,以及相似items,計算對該用戶的推薦結果 è (userId, List<itemId>)。

注意在reduce的setup中,會將phase1產生的所有itemId到index的映射讀入內存,這里只要Item數據集稍大,就會OOM。這是比較嚴重的設計bug

事實上,如果item是正規的整數,而不是guid之類的,phase1和這一步的讀入內存是完全可以略掉的。這樣的話 就完全可以在企業級的數據集上使用(我的測試數據集是15億+的user-item-rating,1.5億+的用戶,在最后這一步掛掉了,前面所有 phase都能跑成功)。

至此,已經形成了推薦結果,CF完成。

以上的所有步驟中,phase5的計算item相似度是最慢的(這個其實也很直覺)。

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的mahout基于Hadoop的CF代码分析(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。