Mahout學習(主要學習內容是Mahout中推薦部分的ItemCF、UserCF、Hadoop集群部署運行)
1、Mahout是什么?
- Mahout是一個算法庫,集成了很多算法。
- Apache Mahout 是 Apache Software Foundation(ASF)旗下的一個開源項目,提供一些可擴展的機器學習領域經典算法的實現,旨在幫助開發人員更加方便快捷地創建智能應用程序。
- Mahout項目目前已經有了多個公共發行版本。Mahout包含許多實現,包括聚類、分類、推薦過濾、頻繁子項挖掘。
- 通過使用 Apache Hadoop 庫,Mahout 可以有效地擴展到Hadoop集群。
- Mahout 的創始人 Grant Ingersoll 介紹了機器學習的基本概念,並演示了如何使用 Mahout 來實現文檔集群、提出建議和組織內容。
2、Mahout是用來干嘛的?
2.1 推薦引擎
服務商或網站會根據你過去的行為為你推薦書籍、電影或文章。
2.2 聚類
Google news使用聚類技術通過標題把新聞文章進行分組,從而按照邏輯線索來顯示新聞,而並非給出所有新聞的原始列表。
2.3 分類
雅虎郵箱基於用戶以前對正常郵件和垃圾郵件的報告,以及電子郵件自身的特征,來判別到來的消息是否是垃圾郵件。
3、Mahout協同過濾算法
Mahout使用了Taste來提高協同過濾算法的實現,它是一個基於Java實現的可擴展的,高效的推薦引擎。Taste既實現了最基本的基於用戶的和基於內容的推薦算法,同時也提供了擴展接口,使用戶可以方便的定義和實現自己的推薦算法。同時,Taste不僅僅只適用於Java應用程序,它可以作為內部服務器的一個組件以HTTP和Web Service的形式向外界提供推薦的邏輯。Taste的設計使它能滿足企業對推薦引擎在性能、靈活性和可擴展性等方面的要求。
Taste主要包括以下幾個接口:
- DataModel 是用戶喜好信息的抽象接口,它的具體實現支持從任意類型的數據源抽取用戶喜好信息。Taste 默認提供 JDBCDataModel 和 FileDataModel,分別支持從數據庫和文件中讀取用戶的喜好信息。
- UserSimilarity 和 ItemSimilarity 。UserSimilarity 用於定義兩個用戶間的相似度,它是基於協同過濾的推薦引擎的核心部分,可以用來計算用戶的“鄰居”,這里我們將與當前用戶口味相似的用戶稱為他的鄰居。ItemSimilarity 類似的,計算Item之間的相似度。
- UserNeighborhood 用於基於用戶相似度的推薦方法中,推薦的內容是基於找到與當前用戶喜好相似的鄰居用戶的方式產生的。UserNeighborhood 定義了確定鄰居用戶的方法,具體實現一般是基於 UserSimilarity 計算得到的。
- Recommender 是推薦引擎的抽象接口,Taste 中的核心組件。程序中,為它提供一個 DataModel,它可以計算出對不同用戶的推薦內容。實際應用中,主要使用它的實現類 GenericUserBasedRecommender 或者 GenericItemBasedRecommender,分別實現基於用戶相似度的推薦引擎或者基於內容的推薦引擎。
- RecommenderEvaluator :評分器。
- RecommenderIRStatsEvaluator :搜集推薦性能相關的指標,包括准確率、召回率等等。
4、Mahout協同過濾算法編程
1、創建maven項目
2、導入mahout依賴
<dependencies> <dependency> <groupId>org.apache.mahout</groupId> <artifactId>mahout</artifactId> <version>0.11.1</version> </dependency> <dependency> <groupId>org.apache.mahout</groupId> <artifactId>mahout-examples</artifactId> <version>0.11.1</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
3、下載電影評分數據
下載地址:http://grouplens.org/datasets/movielens/
數據類別:7.2萬用戶對1萬部電影的百萬級評價和10萬個標簽數據
4、基於用戶的推薦
1 package com.ahu.learnmahout; 2 3 import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; 4 import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; 5 import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; 6 import org.apache.mahout.cf.taste.model.DataModel; 7 import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; 8 import org.apache.mahout.cf.taste.recommender.RecommendedItem; 9 import org.apache.mahout.cf.taste.recommender.Recommender; 10 import org.apache.mahout.cf.taste.similarity.UserSimilarity; 11 import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel; 12 13 import java.io.File; 14 import java.util.List; 15 16 /** 17 * Created by ahu_lichang on 2017/6/23. 18 */ 19 public class BaseUserRecommender { 20 public static void main(String[] args) throws Exception { 21 //准備數據 這里是電影評分數據 22 File file = new File("E:\\ml-10M100K\\ratings.dat"); 23 //將數據加載到內存中,GroupLensDataModel是針對開放電影評論數據的 24 DataModel dataModel = new GroupLensDataModel(file); 25 //計算相似度,相似度算法有很多種,歐幾里得、皮爾遜等等。 26 UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel); 27 //計算最近鄰域,鄰居有兩種算法,基於固定數量的鄰居和基於相似度的鄰居,這里使用基於固定數量的鄰居 28 UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(100, similarity, dataModel); 29 //構建推薦器,協同過濾推薦有兩種,分別是基於用戶的和基於物品的,這里使用基於用戶的協同過濾推薦 30 Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity); 31 //給用戶ID等於5的用戶推薦10部電影 32 List<RecommendedItem> recommendedItemList = recommender.recommend(5, 10); 33 //打印推薦的結果 34 System.out.println("使用基於用戶的協同過濾算法"); 35 System.out.println("為用戶5推薦10個商品"); 36 for (RecommendedItem recommendedItem : recommendedItemList) { 37 System.out.println(recommendedItem); 38 } 39 } 40 }
運行結果:
5、基於物品的推薦
package com.ahu.learnmahout; import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender; import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; import org.apache.mahout.cf.taste.model.DataModel; import org.apache.mahout.cf.taste.recommender.RecommendedItem; import org.apache.mahout.cf.taste.similarity.ItemSimilarity; import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel; import java.io.File; import java.util.List; /** * Created by ahu_lichang on 2017/6/24. */ public class BaseItemRecommender { public static void main(String[] args) throws Exception { //准備數據 這里是電影評分數據 File file = new File("E:\\ml-10M100K\\ratings.dat"); //將數據加載到內存中,GroupLensDataModel是針對開放電影評論數據的 DataModel dataModel = new GroupLensDataModel(file); //計算相似度,相似度算法有很多種,歐幾里得、皮爾遜等等。 ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel); //構建推薦器,協同過濾推薦有兩種,分別是基於用戶的和基於物品的,這里使用基於物品的協同過濾推薦 GenericItemBasedRecommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity); //給用戶ID等於5的用戶推薦10個與2398相似的商品 List<RecommendedItem> recommendedItemList = recommender.recommendedBecause(5, 2398, 10); //打印推薦的結果 System.out.println("使用基於物品的協同過濾算法"); System.out.println("根據用戶5當前瀏覽的商品2398,推薦10個相似的商品"); for (RecommendedItem recommendedItem : recommendedItemList) { System.out.println(recommendedItem); } long start = System.currentTimeMillis(); recommendedItemList = recommender.recommendedBecause(5, 34, 10); //打印推薦的結果 System.out.println("使用基於物品的協同過濾算法"); System.out.println("根據用戶5當前瀏覽的商品34,推薦10個相似的商品"); for (RecommendedItem recommendedItem : recommendedItemList) { System.out.println(recommendedItem); } System.out.println(System.currentTimeMillis() -start); } }
運行結果:
6、評估推薦模型
package com.ahu.learnmahout; import org.apache.mahout.cf.taste.common.TasteException; import org.apache.mahout.cf.taste.eval.RecommenderBuilder; import org.apache.mahout.cf.taste.eval.RecommenderEvaluator; import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator; import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; import org.apache.mahout.cf.taste.model.DataModel; import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; import org.apache.mahout.cf.taste.recommender.Recommender; import org.apache.mahout.cf.taste.similarity.UserSimilarity; import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel; import java.io.File; /** * Created by ahu_lichang on 2017/6/24. */ public class MyEvaluator { public static void main(String[] args) throws Exception { //准備數據 這里是電影評分數據 File file = new File("E:\\ml-10M100K\\ratings.dat"); //將數據加載到內存中,GroupLensDataModel是針對開放電影評論數據的 DataModel dataModel = new GroupLensDataModel(file); //推薦評估,使用均方根 //RecommenderEvaluator evaluator = new RMSRecommenderEvaluator(); //推薦評估,使用平均差值 RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator(); RecommenderBuilder builder = new RecommenderBuilder() { public Recommender buildRecommender(DataModel dataModel) throws TasteException { UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel); UserNeighborhood neighborhood = new NearestNUserNeighborhood(2, similarity, dataModel); return new GenericUserBasedRecommender(dataModel, neighborhood, similarity); } }; // 用70%的數據用作訓練,剩下的30%用來測試 double score = evaluator.evaluate(builder, null, dataModel, 0.7, 1.0); //最后得出的評估值越小,說明推薦結果越好 System.out.println(score); } }
7、獲取推薦的准確率和召回率
package com.ahu.learnmahout; import org.apache.mahout.cf.taste.common.TasteException; import org.apache.mahout.cf.taste.eval.IRStatistics; import org.apache.mahout.cf.taste.eval.RecommenderBuilder; import org.apache.mahout.cf.taste.eval.RecommenderIRStatsEvaluator; import org.apache.mahout.cf.taste.impl.eval.GenericRecommenderIRStatsEvaluator; import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood; import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; import org.apache.mahout.cf.taste.model.DataModel; import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; import org.apache.mahout.cf.taste.recommender.Recommender; import org.apache.mahout.cf.taste.similarity.UserSimilarity; import org.apache.mahout.cf.taste.similarity.precompute.example.GroupLensDataModel; import java.io.File; /** * Created by ahu_lichang on 2017/6/24. */ public class MyIRStatistics { public static void main(String[] args) throws Exception { //准備數據 這里是電影評分數據 File file = new File("E:\\ml-10M100K\\ratings.dat"); //將數據加載到內存中,GroupLensDataModel是針對開放電影評論數據的 DataModel dataModel = new GroupLensDataModel(file); RecommenderIRStatsEvaluator statsEvaluator = new GenericRecommenderIRStatsEvaluator(); RecommenderBuilder recommenderBuilder = new RecommenderBuilder() { public Recommender buildRecommender(DataModel model) throws TasteException { UserSimilarity similarity = new PearsonCorrelationSimilarity(model); UserNeighborhood neighborhood = new NearestNUserNeighborhood(4, similarity, model); return new GenericUserBasedRecommender(model, neighborhood, similarity); } }; // 計算推薦4個結果時的查准率和召回率 //使用評估器,並設定評估期的參數 //4表示"precision and recall at 4"即相當於推薦top4,然后在top-4的推薦上計算准確率和召回率 IRStatistics stats = statsEvaluator.evaluate(recommenderBuilder, null, dataModel, null, 4, GenericRecommenderIRStatsEvaluator.CHOOSE_THRESHOLD, 1.0); System.out.println(stats.getPrecision()); System.out.println(stats.getRecall()); } }
5、Mahout運行在Hadoop集群
1、Hadoop 執行腳本
hadoop jar mahout-examples-0.9-job.jar org.apache.mahout.cf.taste.hadoop.item.RecommenderJob --input /sanbox/movie/10M.txt --output /sanbox/movie/r -s SIMILARITY_LOGLIKELIHOOD
參數說明
- --input(path) : 存儲用戶偏好數據的目錄,該目錄下可以包含一個或多個存儲用戶偏好數據的文本文件;
- --output(path) : 結算結果的輸出目錄
- --numRecommendations (integer) : 為每個用戶推薦的item數量,默認為10
- --usersFile (path) : 指定一個包含了一個或多個存儲userID的文件路徑,僅為該路徑下所有文件包含的userID做推薦計算 (該選項可選)
- --itemsFile (path) : 指定一個包含了一個或多個存儲itemID的文件路徑,僅為該路徑下所有文件包含的itemID做推薦計算 (該選項可選)
- --filterFile (path) : 指定一個路徑,該路徑下的文件包含了[userID,itemID] 值對,userID和itemID用逗號分隔。計算結果將不會為user推薦 [userID,itemID] 值對中包含的item (該選項可選)
- --booleanData (boolean) : 如果輸入數據不包含偏好數值,則將該參數設置為true,默認為false
- --maxPrefsPerUser (integer) : 在最后計算推薦結果的階段,針對每一個user使用的偏好數據的最大數量,默認為10
- --minPrefsPerUser (integer) : 在相似度計算中,忽略所有偏好數據量少於該值的用戶,默認為1
- --maxSimilaritiesPerItem (integer) : 針對每個item的相似度最大值,默認為100
- --maxPrefsPerUserInItemSimilarity (integer) : 在item相似度計算階段,針對每個用戶考慮的偏好數據最大數量,默認為1000
- --similarityClassname (classname) : 向量相似度計算類
- outputPathForSimilarityMatrix :SimilarityMatrix輸出目錄
- --randomSeed :隨機種子 -- sequencefileOutput :序列文件輸出路徑
- --tempDir (path) : 存儲臨時文件的目錄,默認為當前用戶的home目錄下的temp目錄
- --threshold (double) : 忽略相似度低於該閥值的item對
2、 執行結果
上面命令運行完成之后,會在當前用戶的hdfs主目錄生成temp目錄,該目錄可由 --tempDir (path) 參數設置.
后期學習補充:
Mahout 是基於Hadoop的機器學習和數據挖掘的一個分布式框架。Mahout用MapReduce實現了部分數據挖掘算法,解決了並行挖掘的問題。
Mahout應用場景: