基於Mahout的電影推薦系統


1.Mahout 簡介

Apache Mahout 是 Apache Software Foundation(ASF) 旗下的一個開源項目,提供一些可擴展的機器學習領域經典算法的實現,旨在幫助開發人員更加方便快捷地創建智能應用程序。經典算法包括聚類、分類、協同過濾、進化編程等等,並且,在 Mahout 的最近版本中還加入了對 Apache Hadoop 的支持,使這些算法可以更高效的運行在雲計算環境中。

2.Taste簡介

Taste 是 Apache Mahout 提供的一個協同過濾算法的高效實現,它是一個基於 Java 實現的可擴展的,高效的推薦引擎。Taste 既實現了最基本的基於用戶的和基於內容的推薦算法,同時也提供了擴展接口,使用戶可以方便的定義和實現自己的推薦算法。同時,Taste 不僅僅只適用於 Java 應用程序,它可以作為內部服務器的一個組件以 HTTP 和 Web Service 的形式向外界提供推薦的邏輯。Taste 的設計使它能滿足企業對推薦引擎在性能、靈活性和可擴展性等方面的要求。

圖 1. Taste 的主要組件圖

Taste 由以下五個主要的組件組成:

  • DataModel:DataModel 是用戶喜好信息的抽象接口,它的具體實現支持從任意類型的數據源抽取用戶喜好信息。Taste 默認提供 JDBCDataModel 和 FileDataModel,分別支持從數據庫和文件中讀取用戶的喜好信息。
  • UserSimilarity 和 ItemSimilarity:UserSimilarity 用於定義兩個用戶間的相似度,它是基於協同過濾的推薦引擎的核心部分,可以用來計算用戶的“鄰居”,這里我們將與當前用戶口味相似的用戶稱為他的鄰居。ItemSimilarity 類似的,計算內容之間的相似度。
  • UserNeighborhood:用於基於用戶相似度的推薦方法中,推薦的內容是基於找到與當前用戶喜好相似的“鄰居用戶”的方式產生的。UserNeighborhood 定義了確定鄰居用戶的方法,具體實現一般是基於 UserSimilarity 計算得到的。
  • Recommender:Recommender 是推薦引擎的抽象接口,Taste 中的核心組件。程序中,為它提供一個 DataModel,它可以計算出對不同用戶的推薦內容。實際應用中,主要使用它的實現類 GenericUserBasedRecommender 或者 GenericItemBasedRecommender,分別實現基於用戶相似度的推薦引擎或者基於內容的推薦引擎。

3.系統介紹

(1)說明:系統制作比較簡單,只為展示mahout的taste推薦算法,算法說明來自http://www.ibm.com/developerworks/cn/java/j-lo-mahout/

(2)准備工作:

       環境:jdk,mysql,mahout-0.5,eclipse;

       數據集:MovieLens 1M - Consists of 1 million ratings from 6000 users on 4000 movies.   數據集鏈接:http://www.grouplens.org/node/12

       數據集說明:

   These files contain 1,000,209 anonymous ratings of approximately 3,900 movies 
   made by 6,040 MovieLens users who joined MovieLens in 2000.

       

       movies.dat的文件描述是 電影編號::電影名::電影類別
       ratings.dat的文件描述是 用戶編號::電影編號::電影評分::時間戳
       users.dat的文件描述是 用戶編號::性別::年齡::職業::Zip-code

(3)實施:

       數據庫錄入:將數據集導入mysql

 1 CREATE DATABASE movie;   
 2  USE movie;   
 3  CREATE TABLE movies (         //對應movies.dat
 4     id INTEGER NOT NULL AUTO_INCREMENT,   
 5     name varchar(100) NOT NULL,   
 6     published_year varchar(4) default NULL,   
 7     type varchar(100) default NULL,   
 8     PRIMARY KEY (id)   
 9  );   
10  CREATE TABLE movie_preferences (   //對應ratings.dat
11     userID INTEGER NOT NULL,   
12     movieID INTEGER NOT NULL,   
13     preference INTEGER NOT NULL DEFAULT 0,   
14     timestamp INTEGER not null default 0,   
15     FOREIGN KEY (movieID) REFERENCES movies(id) ON DELETE CASCADE   
16  ); 

        

       推薦算法介紹:

       基於用戶的協同過濾推薦

       基於用戶的協同過濾推薦的基本原理是,根據所有用戶對物品或者信息的偏好,發現與當前用戶口味和偏好相似的“鄰居”用戶群,在一般的應用中是采用計算“K-       鄰居”的算法;然后,基於這 K 個鄰居的歷史偏好信息,為當前用戶進行推薦。下圖 4 給出了原理圖。

      基於用戶的協同過濾推薦機制的基本原理
      圖 4. 基於用戶的協同過濾推薦機制的基本原理 

            上圖示意出基於用戶的協同過濾推薦機制的基本原理,假設用戶 A 喜歡物品 A,物品 C,用戶 B 喜歡物品 B,用戶 C 喜歡物品 A ,物品 C 和物品 D;從             這些用戶的歷史喜好信息中,我們可以發現用戶 A 和用戶 C 的口味和偏好是比較類似的,同時用戶 C 還喜歡物品 D,那么我們可以推斷用戶 A 可能也喜歡              物品 D,因此可以將物品 D 推薦給用戶 A。

 

            基於項目的協同過濾推薦

            基於項目的協同過濾推薦的基本原理也是類似的,只是說它使用所有用戶對物品或者信息的偏好,發現物品和物品之間的相似度,然后根據用戶的歷史偏好               信息,將類似的物品推薦給用戶,圖 5 很好的詮釋了它的基本原理。

            假設用戶 A 喜歡物品 A 和物品 C,用戶 B 喜歡物品 A,物品 B 和物品 C,用戶 C 喜歡物品 A,從這些用戶的歷史喜好可以分析出物品 A 和物品 C 時比             較類似的,喜歡物品 A 的人都喜歡物品 C,基於這個數據可以推斷用戶 C 很有可能也喜歡物品 C,所以系統會將物品 C 推薦給用戶 C。

            與上面講的類似,基於項目的協同過濾推薦和基於內容的推薦其實都是基於物品相似度預測推薦,只是相似度計算的方法不一樣,前者是從用戶歷史的偏好               推斷,而后者是基於物品本身的屬性特征信息。

            基於項目的協同過濾推薦機制的基本原理
             圖 5. 基於項目的協同過濾推薦機制的基本原理 

              核心算法代碼展示:

import org.apache.mahout.cf.taste.impl.model.file.*;//FileDataModel
import org.apache.mahout.cf.taste.model.*;//DAtaModel
import org.apache.mahout.cf.taste.impl.neighborhood.*;
import org.apache.mahout.cf.taste.impl.recommender.*;
import org.apache.mahout.cf.taste.impl.similarity.*;
import org.apache.mahout.cf.taste.neighborhood.*;
import org.apache.mahout.cf.taste.similarity.*;
import org.apache.mahout.cf.taste.recommender.*;

import java.io.*;
import java.util.*;

public class RecommendDeal{
    int userID;
    int length;
    
    public RecommendDeal(int userID){
        this.userID=userID;
        
    }
    //*******************基於用戶的推薦********************
    public List<RecommendedItem> userBasedRecommender() {  
        // step:1 構建模型 2 計算相似度 3 查找k緊鄰 4 構造推薦引擎 
    List<RecommendedItem> recommendations = null;  
    try {  
        length=(int)((Math.random()+3)*10);
        
        DataModel model = new FileDataModel(new File("D:\\ratings.txt"));//構造數據模型,Database-based  
        UserSimilarity similarity = new PearsonCorrelationSimilarity(model);//用PearsonCorrelation 算法計算用戶相似度  
        UserNeighborhood neighborhood = new NearestNUserNeighborhood(length, similarity, model);//計算用戶的“鄰居”,這里將與該用戶最近距離為 3 的用戶設置為該用戶的“鄰居”。  
        Recommender recommender = new CachingRecommender(new GenericUserBasedRecommender(model, neighborhood, similarity));//構造推薦引擎,采用 CachingRecommender 為 RecommendationItem 進行緩存  
        recommendations = recommender.recommend(this.userID, 20);//得到推薦的結果,20是推薦的數目  
    } catch (Exception e) {  
        // TODO: handle exception  
        e.printStackTrace();  
    }  
    return recommendations;  
}
    //**********************基於項目的推薦*******************
    public List<RecommendedItem> ItemBasedRecommender(){  
        List<RecommendedItem> recommendations = null;  
        length=(int)((Math.random()+1)*10);
        try {  
            DataModel model = new FileDataModel(new File("D:\\ratings.txt"));//構造數據模型,File-based  
            ItemSimilarity similarity = new PearsonCorrelationSimilarity(model);//計算內容相似度  
            Recommender recommender = new GenericItemBasedRecommender(model, similarity);//構造推薦引擎  
            recommendations = recommender.recommend(this.userID, length);//得到推薦接過  
        } catch (Exception e) {  
            // TODO: handle exception  
            e.printStackTrace();  
        }  
        return recommendations;  
    }  
    
}

              讀入文件說明:由於數據量比較大,100W條,通過數據庫讀數據太慢,采用從文件中直接讀取,(也許是我電腦的問題)我的文件是ratings.txt

              通過推薦算法得出結果后,從數據庫查出對應信息,顯示在前台。

 

            項目截圖:

            1>框架圖:只用了鏈接mysql的包,和mahout的包,無其他包,如圖

            

 

        2>效果圖:       
login

              

              登錄后選擇,點直接推薦是基於用戶的,點隨便看看是基於項目的

              

              點擊系統推薦,直接出結果:

              

               點擊隨便看看,展示部分電影,通過鏈接,顯示電影詳情,並實現項目推薦

              

            這里只推薦了5個,根據需要推薦的條數可以調整


4.總結

此項目做得簡單而丑陋,一方面是時間原因,另一方面是初衷,之所以做這個是了解一下推薦算法,通過前台能夠直觀展現出來,也可以為正在學習這方面知識的同學,做個參考!
此外,在數據量比較大的情況下,我發現串行跑的很吃力,接下來的工作可以在hadoop上繼續研究一下Taste!




參考:http://www.ibm.com/developerworks/cn/java/j-lo-mahout/
http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy1/index.html
http://www.ibm.com/developerworks/cn/web/1103_zhaoct_recommstudy1/index.html
http://blog.csdn.net/huhui_cs/article/details/8596388

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM