1. 程式人生 > 實用技巧 >Mahout介紹和簡單應用

Mahout介紹和簡單應用

Mahout介紹和簡單應用

個人實踐以後,發現寫的很好轉至:https://www.cnblogs.com/ahu-lichang/p/7073836.html

Mahout學習(主要學習內容是Mahout中推薦部分的ItemCF、UserCF、Hadoop叢集部署執行)

1、Mahout是什麼?

  • Mahout是一個演算法庫,集成了很多演算法。
  • ApacheMahout是ApacheSoftwareFoundation(ASF)旗下的一個開源專案,提供一些可擴充套件的機器學習領域經典演算法的實現,旨在幫助開發人員更加方便快捷地建立智慧應用程式。
  • Mahout專案目前已經有了多個公共發行版本。Mahout包含許多實現,包括聚類、分類、推薦過濾、頻繁子項挖掘。
  • 通過使用ApacheHadoop庫,Mahout可以有效地擴充套件到Hadoop叢集。
  • Mahout的創始人GrantIngersoll介紹了機器學習的基本概念,並演示瞭如何使用Mahout來實現文件叢集、提出建議和組織內容。

2、Mahout是用來幹嘛的?

2.1 推薦引擎

服務商或網站會根據你過去的行為為你推薦書籍、電影或文章。

2.2 聚類

Googlenews使用聚類技術通過標題把新聞文章進行分組,從而按照邏輯線索來顯示新聞,而並非給出所有新聞的原始列表。

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應用場景: