使用Apache Mahout创建在线推荐系统
最近, 我們一直在為Yap.TV實施推薦系統:在安裝應用程序并轉到“ Just for you”選項卡后,您可以看到它的運行情況。 我們以Apache Mahout為基礎進行建議。 Mahout是一個“可擴展的機器學習庫”,其中包含使用協作過濾算法的基于用戶和項目的推薦者的本地和分布式實現。
現在,我們將專注于本地單機實施。 如果您擁有數千萬的首選項值,它應該會很好地工作。 除此之外,您可能應該考慮基于Hadoop的實現,因為數據根本無法放入內存中。
用Mahout編寫基本的推薦器非常簡單; 由于Mahout的可配置性很強,因此通常有不同的實現方式可供選擇。 我只描述我認為是“好的起點”。
基本
首先,您需要一個包含輸入數據的文件。 格式非常簡單:以逗號分隔的(用戶ID,商品ID)對或(用戶ID,商品ID,偏好值)三倍。 這表示您已經知道:哪些用戶喜歡哪些項目,以及可選多少(例如1-5級)。 id必須為整數,首選項值被視為浮點型。
讓我們首先創建一個基于用戶的推薦器:這是一個推薦器,當被問到對用戶A的推薦時,它首先會查找與“ A”相似的用戶,然后嘗試查找這些相似的用戶已評價過的最佳商品,但A還沒有。 為此,我們需要創建4個組件:
- 數據模型 :這將使用文件
- 用戶相似度 :給定兩個用戶的度量,將返回一個數字,表示他們的相似度
- 鄰域 :用于查找給定用戶的鄰域
- 推薦器 :將這些片段組合在一起以產生推薦
對于一元輸入數據(用戶喜歡項目或我們不知道的數據),一個好的起點是:
val dataModel = new FileDataModel(file) val userSimilarity = new LogLikelihoodSimilarity(dataModel) val neighborhood = new NearestNUserNeighborhood(25, userSimilarity, dataModel) val recommender = new GenericBooleanPrefUserBasedRecommender(dataModel, neighborhood, userSimilarity)如果我們有偏好值(輸入數據中的三倍):
val dataModel = new FileDataModel(file) val userSimilarity = new PearsonCorrelationSimilarity(dataModel) val neighborhood = new NearestNUserNeighborhood(25, userSimilarity, dataModel) val recommender = new GenericUserBasedRecommender(dataModel, neighborhood, userSimilarity)現在我們準備得到一些建議; 這很簡單:
// Gets 10 recommendations val result = recommender.recommend(userId, 10)// We get back a list of item-estimated preference value, // sorted from the highest score result.foreach(r => println(r.getItemID() + ": " + r.getValue()))線上
在線方面呢? 以上內容對現有用戶非常有用; 在服務中注冊的新用戶呢? 當然,我們也想為他們提供一些合理的建議。 創建推薦器實例非常昂貴(肯定會比“正常”網絡請求花費更長的時間),因此我們不能每次都創建一個新的推薦器。
幸運的是Mahout可以將臨時用戶添加到數據模型中。 常規設置如下:
- 使用當前數據定期重新創建整個推薦器(例如每天或每小時-取決于需要多長時間)
- 進行推薦時,請檢查用戶是否存在于系統中
- 如果是,請像往常一樣做建議
- 如果不是,請創建一個臨時用戶,填寫首選項,然后進行建議
如果內存有限,第一部分(定期重新創建推薦器)實際上可能會很棘手:創建新推薦器時,您需要在內存中保存兩個數據副本(以便仍然能夠處理來自服務器的請求老)。 但這實際上與建議沒有任何關系,因此在這里我將不做詳細介紹。
對于臨時用戶,我們可以使用PlusAnonymousConcurrentUserDataModel實例包裝數據模型。 此類允許獲取臨時用戶ID。 該ID必須稍后發布,以便可以重復使用(此類ID的數量有限)。 獲取ID后,我們必須填寫首選項,然后我們可以像往常一樣繼續進行推薦:
val dataModel = new PlusAnonymousConcurrentUserDataModel(new FileDataModel(file),100)val recommender: org.apache.mahout.cf.taste.recommender.Recommender = ...// we are assuming a unary model: we only know which items a user likes def recommendFor(userId: Long, userPreferences: List[Long]) = {if (userExistsInDataModel(userId)) {recommendForExistingUser(userId)} else {recommendForNewUser(userPreferences)} }def recommendForNewUser(userPreferences: List[Long]) = {val tempUserId = dataModel.takeAvailableUser()try {// filling in a Mahout data structure with the user's preferencesval tempPrefs = new BooleanUserPreferenceArray(userPreferences.size)tempPrefs.setUserID(0, tempUserId)userPreferences.zipWithIndex.foreach { case (preference, idx) => tempPrefs.setItemID(idx, preference) }dataModel.setTempPrefs(tempPrefs, tempUserId)recommendForExistingUser(tempUserId)} finally {dataModel.releaseUser(tempUserId)} }def recommendForExistingUser(userId: Long) = {recommender.recommend(userId, 10) }整合業務邏輯
由于某些業務規則,我們經常想提高所選項目的得分。 在我們的用例中,例如,如果某節目有新劇集,我們希望給它更高的分數。 使用Mahout的IDRescorer接口可以實現。 調用Recommender.recommend時,提供了一個rescorer實例。 例如:
val rescorer = new IDRescorer {def rescore(id: Long, originalScore: Double) = {if (showIsNew(id)) {originalScore * 1.2 } else {originalScore}}def isFiltered(id: Long) = false }// Gets 10 recommendations val result = recommender.recommend(userId, 10, rescorer)摘要
Mahout是創建推薦器的重要基礎。 它是非常可配置的,并提供許多擴展點。 選擇正確的配置參數值,設置評分和評估推薦結果還有很多工作要做,但是算法是可靠的,因此無需擔心。
還有一本非常好的書,《 Mahout in Action》 ,涵蓋了推薦系統和Mahout的其他組件。 它基于版本0.5(當前版本為0.8),但是代碼示例大部分都可以工作,并且項目的主要邏輯是相同的。
翻譯自: https://www.javacodegeeks.com/2013/10/creating-an-on-line-recommender-system-with-apache-mahout.html
總結
以上是生活随笔為你收集整理的使用Apache Mahout创建在线推荐系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里 ddos(阿里ddos比赛)
- 下一篇: Stacktraces告诉了事实。 但事