Mahout推薦算法編程實踐-demo說明

引言java

Taste是曾經風靡一時的推薦算法框架,後來被併入Mahout中,Mahout的部分推薦算法基於Taste實現。算法

下文介紹基於Taste實現最經常使用的UserCF和ItemCF。apache

本文不涉及UserCF和ItemCF算法的介紹,這方面網上資料不少,本文僅介紹如何基於Mahout編程實現。編程

歡迎轉載,請註明來源:框架

http://blog.csdn.net/u010967382/article/details/39183839 ide

步驟一:構建數據模型測試

UserCF和ItemCF算法的輸入數據是用戶偏好,用戶偏好數據能夠有兩種形式:idea

  • 包含用戶對目標評分的【用戶ID,itemID,評分】 
  • 不包含評分的【用戶ID,itemID】 

推薦算法的第一步是基於數據源構建數據模型,Taste構建數據模型的數據源能夠有不少,好比JDBC,文件等。.net

下面僅介紹最經常使用的文件數據源:rest

  • 用戶偏好數據包含評分 

示例代碼:

DataModel dm = new FileDataModel(new File("E:\\testdata\\3columns")); 

  • 用戶偏好數據不包含評分 

示例代碼:

DataModel dm = new  GenericBooleanPrefDataModel(

GenericBooleanPrefDataModel

.toDataMap(new FileDataModel(new File("E:\\testdata\\2columns"))));

步驟二:指定距離(類似度)計算方法

建立好數據模型後,第二步須要指定一種計算「距離」的方法,由於在後續的步驟中須要計算user或item之間的「距離」。

Taste提供的計算距離的方法不少,如下僅介紹經常使用的方法:

  • 用戶偏好數據包含評分    

歐氏距離:EuclideanDistanceSimilarity

皮爾森距離:PearsonCorrelationSimilarity

餘弦距離:UncenteredCosineSimilarity

  • 用戶偏好數據不包含評分   

曼哈頓距離:CityBlockSimilarity

對數似然距離: LogLikelihoodSimilarity

 

示例代碼:

UserSimilarity us = new  CityBlockSimilarity(dm);

ItemSimilarity is  = new  CityBlockSimilarity(dm); 

步驟三(僅UserCF須要):選擇近鄰算法

若是選擇使用UserCF算法作推薦,則在完成類似度計算方法的指定後,須要指定近鄰算法。

 

  • NearestNUserNeighborhood 

指定距離最近的N個用戶做爲鄰居。

示例:UserNeighborhood unb = new NearestNUserNeighborhood(10, us, dm);

三個參數分別是: 鄰居的個數,用戶類似度,數據模型    

  • ThresholdUserNeighborhood 

指定距離最近的必定百分比的用戶做爲鄰居。

示例:UserNeighborhood unb = new ThresholdUserNeighborhood(0.2, us, dm); 

三個參數分別是: 閥值(取值範圍0到1之間),用戶類似度,數據模型

 

步驟四:建立推薦器

實施推薦算法的最後一步就是建立推薦引擎,Taste爲UserCF和ItemCF算法,針對有用戶評分和沒用戶評分的狀況,分別提供了推薦器:

  • 用戶偏好數據包含評分   

示例代碼:

UserCF:Recommender re = new  GenericUserBasedRecommender(dm, unb, us);

ItemCF:Recommender re = new  GenericItemBasedRecommender(dm, is);

 

  • 用戶偏好數據不包含評分   

示例代碼:

UserCF:Recommender re = new  GenericBooleanPrefUserBasedRecommender(dm, unb, us);

ItemCF:Recommender  re = new  GenericBooleanPrefItemBasedRecommender(dm, is);

題外話:

經過召回率和查準率的測試, CityBlockSimilarity + UserCF 的推薦效果最好。

示例代碼:用戶偏好數據不包含評分 + CityBlockSimilarity + UserCF

  • 用戶偏好數據 

1,101

1,102

1,103

2,101

2,102

2,103

2,104

3,101

3,104

3,105

3,107

4,101

4,103

4,104

4,106

5,101

5,102

5,103

5,104

5,105

5,106

 

  • 代碼 

import java.io.File;

import java.util.List;

import org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel;

import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;

import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;

import org.apache.mahout.cf.taste.impl.recommender.GenericBooleanPrefUserBasedRecommender;

import org.apache.mahout.cf.taste.impl.similarity.CityBlockSimilarity;

import org.apache.mahout.cf.taste.model.DataModel;

import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;

import org.apache.mahout.cf.taste.recommender.RecommendedItem;

import org.apache.mahout.cf.taste.recommender.Recommender;

import org.apache.mahout.cf.taste.similarity.UserSimilarity;

public class UserCFRecommender {

     public  static  void main(String[] args)  throws Exception {

        // 建立數據模型,不包含用戶評分

        DataModel dm =  new GenericBooleanPrefDataModel(

                GenericBooleanPrefDataModel

                        .toDataMap( new FileDataModel( new File("E:\\testdata\\2columns"))));

        // 使用曼哈頓距離計算類似度

        UserSimilarity us =  new CityBlockSimilarity(dm);

 

        //指定NearestNUserNeighborhood做爲近鄰算法

        UserNeighborhood unb =  new NearestNUserNeighborhood(10, us, dm);

        

        // 構建不包含用戶評分的UserCF推薦器

        Recommender re =  new GenericBooleanPrefUserBasedRecommender(dm, unb, us);

        

        // 輸出推薦結果,爲1號用戶推薦5個商品

        List<RecommendedItem> list = re.recommend(1, 5);

         for (RecommendedItem recommendedItem : list) {

            System. out.println(recommendedItem.getItemID()+" : "+recommendedItem.getValue());   

        }

    }

}

相關文章
相關標籤/搜索