協同過濾算法——推薦引擎比你更瞭解你本身


1. 背景
  在數據爆炸咱們天天被數據困擾的今天,數據量發生指數級的增加,每年產生的大數據是過去歷史的總和。那麼在茫茫數據大海中,對於數據生產者,怎麼將本身的信息精準投放給所需的用戶呢?而對於數據消費者,怎麼從海量數據中快速獲取本身須要的信息呢?這時推薦引擎應運而生。
  推薦應用其實已經走進咱們的生活,典型的推薦應用:
a. 豆瓣網站
  豆瓣根據個人讀書列表,及相應評論,爲我推薦出以下結果:java

                       
b. 購物網站
  亞馬孫根據個人購書清單和相應書評,爲我推薦的以下結果:
                      web


1.1 問題抽象
    咱們能夠把推薦模型進行數據的抽象,假設有1,2,3,4和5個用戶分別各自購買了101,102,103至107物品中的物品,並對其進行了各自購買的物品進行評分,那麼推薦引擎如何根據用戶喜愛,推薦他們各自未買的物品呢?以下數據集:
           
算法

2. 推薦引擎背景及算法api

      若是你最近想看電影,你可能諮詢周圍的人,並且一般你更傾向詢問與「興趣相投」的人,從他們的口味中,得出一個最近電影排名集,來敲定你想看的電影,這是協同過濾的基本思想。圖解:ide

                   

 

  算法具體解決的兩個問題:
  a. 如何找到「興趣相投的」人羣,造成一個羣體,咱們稱之爲鄰域「neighborhood「。
  b. 如何從既定的鄰域中,排序出喜愛的項目列表?大數據

2.1 類似度
  若是咱們把每一個用戶的評分列表當作一個一維度向量,那麼能夠根據向量的類似度定量化用戶之間的類似性。類似度分類主要有:網站

 a. 基於歐幾里德距離計算類似度ui

  

 b. 基於 Cosine 類似度idea

  

 c. 基於皮爾遜相關係數計算類似度spa

 

 d. 基於 Tanimoto 係數計算類似度

 


2.2 鄰域
  物以類聚,既然咱們獲取了用戶之間的類似度值,那麼那些人羣歸爲一個鄰域呢?一般有兩種方法:

 a.  規定 Fix-size,根據類似度值排名,取前fix-size的個數做爲一個鄰域

 b. 規定threshold,類似度值大於規定值歸爲一個鄰域


              

2.3 推薦值計算
  定量的計算推測用戶a對某個物品v的喜愛程度,公式以下: ΣSim(i,j)Vi

  即爲其它各位用戶對物品v的評分值的線性加權平均,其中,權重是類似度值sim,v表示對各物品的評分。

     因此整個計算的過程是經過2.1和2.2解決問題a,而後根據2.3解決問題b的過程。 

2.4 推薦算法分類
  典型的推薦算法有:基於用戶的推薦和基於物品的推薦兩種。
  上述的思路從基於用戶的推薦方法講解的,而在實際電商網站應用中,因爲物品數量是遠遠大於每位用戶的購買數量的,並且用戶之間購買的物品重疊性較低,很難找到鄰域。這時,能夠換個從商品的角度思考,商品間的類似性。根據用戶購物歷史偏好,計算物品間的類似性,流程和基於用戶的推薦同樣。 

3. mahout協同過濾的應用接口

3.1 類似度
  類似度接口有UserSimilarity和ItemSimilarity,其主要方法以下:

double userSimilarity(long userID1, long userID2) double itemSimilarity(long itemID1, long itemID2)

  其繼承類分別:

a. PearsonCorrelationSimilarity:基於皮爾遜相關係數計算類似度
b. EuclideanDistanceSimilarity:基於歐幾里德距離計算類似度
c. TanimotoCoefficientSimilarity:基於 Tanimoto 係數計算類似度
d. UncerteredCosineSimilarity:計算 Cosine 類似度

3.2 鄰域
   鄰域類UserNeighborhood,其主要接口以下:

 long[] getUserNeighborhood(long userID) 

輸入給定用戶,給出與其類似的用戶列表

其繼承類分別:
a. NearestNUserNeighborhood:對每一個用戶取固定數量 N 的最近鄰居
b. ThresholdUserNeighborhood:對每一個用戶基於必定的限制,取落在類似度門限內的全部用戶爲鄰居。

3.3 Recommender

  關聯數據模型和類似度算法模型,進行具體的計算,接口以下:

List<RecommendedItem> recommend(long userID, int howMany)

   給定用戶id和推薦的結果個數,返回推薦的結果

3.4 各種圖關係以下:

               

4. 代碼樣例和推薦結果
4.1 mahout代碼樣例

 public static void main(String[] args) throws IOException, TasteException {
        // TODO Auto-generated method stub
        System.out.println("starting ");

        String file = "item.csv";
        DataModel model = new FileDataModel(new File(file));

        System.out.println("starting userCF ");
        userCF(model);

        System.out.println();
        System.out.println("starting itemCF");
        itemCF(model);
    }

    public static void userCF(DataModel model) {
        try {
            UserSimilarity user = new UncenteredCosineSimilarity(model);
            NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model);
            Recommender r = new GenericUserBasedRecommender(model, neighbor, user);
            LongPrimitiveIterator iter = model.getUserIDs();

            while (iter.hasNext()) {
                long uid = iter.nextLong();
                List<RecommendedItem> list = r.recommend(uid, RECOMMENDER_NUM);

                System.out.printf("user:%s", uid);
                for (RecommendedItem rItem : list) {
                    System.out.printf("(%s,%f)", rItem.getItemID(), rItem.getValue());
                }
                System.out.println();
            }

        } catch (TasteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void itemCF(DataModel dataModel) {
        try {
            ItemSimilarity itemSimilarity = new UncenteredCosineSimilarity(dataModel);
            Recommender recommender = new GenericItemBasedRecommender(dataModel, itemSimilarity);
            Recommender cachingRecommender = new CachingRecommender(recommender);

            LongPrimitiveIterator iter = dataModel.getUserIDs();
            while (iter.hasNext()) {
                long uid = iter.nextLong();
                List<RecommendedItem> list = cachingRecommender.recommend(uid, RECOMMENDER_NUM);

                System.out.printf("user:%s", uid);
                for (RecommendedItem rItem : list) {
                    System.out.printf("(%s,%f)", rItem.getItemID(), rItem.getValue());
                }
                System.out.println();
            }

        } catch (TasteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

4.2 推薦結果

            

5. 評估標準
     結果推薦出來,天然須要一套標準評判各自方法推薦的結果好壞。評價標準能夠參考http://blog.fens.me/mahout-recommendation-api/#gsc.tab=0的2節。

 

  參考

1. http://en.wikipedia.org/wiki/Collaborative_filtering

2. http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy1/

3. https://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy2/

4. http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy3/

5. http://blog.csdn.net/huagong_adu/article/details/7362908

6. http://blog.fens.me/mahout-recommendation-api/#gsc.tab=0

相關文章
相關標籤/搜索