小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Taste 是 Apache Mahout 提供的一個(gè)協(xié)同過(guò)濾算法的高效實(shí)現(xiàn)

 funson 2012-09-25
Taste 是 Apache Mahout 提供的一個(gè)協(xié)同過(guò)濾算法的高效實(shí)現(xiàn) (2011-04-17 11:09:33)
 

Web 2.0 的一個(gè)核心思想就是“群體智慧”,即基于大眾行為,為每個(gè)用戶(hù)提供個(gè)性化的推薦。這使得如何讓用戶(hù)能更快速更準(zhǔn)確的獲得所需要的信息,成為了 Web 應(yīng)用成敗的關(guān)鍵。Apache Mahout 是 ASF(Apache Software Foundation)的一個(gè)較新的開(kāi)源項(xiàng)目,提供機(jī)器學(xué)習(xí)領(lǐng)域的一些經(jīng)典算法的高效實(shí)現(xiàn)。本文主要講述如何基于 Apache Mahout 來(lái)構(gòu)建社會(huì)化推薦引擎,幫助 Web 應(yīng)用開(kāi)發(fā)者更高效的實(shí)現(xiàn)個(gè)性化推薦功能,從而提高最終用戶(hù)滿(mǎn)意度。

推薦引擎利用特殊的信息過(guò)濾(IF,Information Filtering)技術(shù),將不同的內(nèi)容(例如電影、音樂(lè)、書(shū)籍、新聞、圖片、網(wǎng)頁(yè)等)推薦給可能感興趣的用戶(hù)。通常情況下,推薦引擎的實(shí)現(xiàn)是通過(guò)將用戶(hù)的個(gè)人喜好與特定的參考特征進(jìn)行比較,并試圖預(yù)測(cè)用戶(hù)對(duì)一些未評(píng)分項(xiàng)目的喜好程度。參考特征的選取可能是從項(xiàng)目本身的信息中提取的,或是基于用戶(hù)所在的社會(huì)或社團(tuán)環(huán)境。

根據(jù)如何抽取參考特征,我們可以將推薦引擎分為以下四大類(lèi):

  • 基于內(nèi)容的推薦引擎:它將計(jì)算得到并推薦給用戶(hù)一些與該用戶(hù)已選擇過(guò)的項(xiàng)目相似的內(nèi)容。例如,當(dāng)你在網(wǎng)上購(gòu)書(shū)時(shí),你總是購(gòu)買(mǎi)與歷史相關(guān)的書(shū)籍,那么基于內(nèi)容的推薦引擎就會(huì)給你推薦一些熱門(mén)的歷史方面的書(shū)籍。
  • 基于協(xié)同過(guò)濾的推薦引擎:它將推薦給用戶(hù)一些與該用戶(hù)品味相似的其他用戶(hù)喜歡的內(nèi)容。例如,當(dāng)你在網(wǎng)上買(mǎi)衣服時(shí),基于協(xié)同過(guò)濾的推薦引擎會(huì)根據(jù)你的歷史購(gòu)買(mǎi)記錄或是瀏覽記錄,分析出你的穿衣品位,并找到與你品味相似的一些用戶(hù),將他們?yōu)g覽和購(gòu)買(mǎi)的衣服推薦給你。
  • 基于關(guān)聯(lián)規(guī)則的推薦引擎:它將推薦給用戶(hù)一些采用關(guān)聯(lián)規(guī)則發(fā)現(xiàn)算法計(jì)算出的內(nèi)容。關(guān)聯(lián)規(guī)則的發(fā)現(xiàn)算法有很多,如 Apriori、AprioriTid、DHP、FP-tree 等。
  • 混合推薦引擎:結(jié)合以上各種,得到一個(gè)更加全面的推薦效果。

隨著互聯(lián)網(wǎng)上數(shù)據(jù)和內(nèi)容的不斷增長(zhǎng),人們?cè)絹?lái)越重視推薦引擎在互聯(lián)網(wǎng)應(yīng)用中的作用??上攵捎诨ヂ?lián)網(wǎng)上的數(shù)據(jù)過(guò)多,用戶(hù)很難找到自己想要的信息,通過(guò)提供搜索功能來(lái)解決這個(gè)問(wèn)題是遠(yuǎn)遠(yuǎn)不夠的。推薦引擎可以通過(guò)分析用戶(hù)的行為來(lái)預(yù)測(cè)用戶(hù)的喜好,使用戶(hù)能更容易找到他們潛在需要的信息。這里以電子商務(wù)應(yīng)用中的推薦引擎為例來(lái)說(shuō)明推薦引擎在互聯(lián)網(wǎng)應(yīng)用中的重要性。

電子商務(wù)推薦系統(tǒng) (E-Commence Recommendation System) 向客戶(hù)提供商品信息和購(gòu)買(mǎi)建議,模擬銷(xiāo)售人員幫助客戶(hù)完成購(gòu)買(mǎi)過(guò)程。智能推薦系統(tǒng)的作用可以概括為:將電子商務(wù)網(wǎng)站的瀏覽者轉(zhuǎn)變?yōu)橘?gòu)買(mǎi)者,提高電子商務(wù)網(wǎng)站的交叉銷(xiāo)售能力,提高客戶(hù)對(duì)電子商務(wù)網(wǎng)站的忠誠(chéng)度。

電子商務(wù)推薦系統(tǒng)的界面表現(xiàn)形式有以下幾種:

  • 瀏覽:客戶(hù)提出對(duì)特定商品的查詢(xún)要求,推薦引擎根據(jù)查詢(xún)要求返回高質(zhì)量的推薦;
  • 相似商品:推薦引擎根據(jù)客戶(hù)購(gòu)物籃中的商品和客戶(hù)可能感興趣的商品推薦與它們類(lèi)似的商品;
  • Email:推薦系統(tǒng)通過(guò)電子郵件的方式通知客戶(hù)可能感興趣的商品信息;
  • 評(píng)論:推薦系統(tǒng)向客戶(hù)提供其他客戶(hù)對(duì)相應(yīng)產(chǎn)品的評(píng)論信息。

Apache Mahout 是 Apache Software Foundation(ASF)旗下的一個(gè)開(kāi)源項(xiàng)目,提供一些可擴(kuò)展的機(jī)器學(xué)習(xí)領(lǐng)域經(jīng)典算法的實(shí)現(xiàn),旨在幫助開(kāi)發(fā)人員更加方便快捷地創(chuàng)建智能應(yīng)用程序。經(jīng)典算法包括聚類(lèi)、分類(lèi)、協(xié)同過(guò)濾、進(jìn)化編程等等,并且,在 Mahout 的最近版本中還加入了對(duì) Apache Hadoop 的支持,使這些算法可以更高效的運(yùn)行在云計(jì)算環(huán)境中。

Taste 簡(jiǎn)介

Taste 是 Apache Mahout 提供的一個(gè)協(xié)同過(guò)濾算法的高效實(shí)現(xiàn),它是一個(gè)基于 Java 實(shí)現(xiàn)的可擴(kuò)展的,高效的推薦引擎。Taste 既實(shí)現(xiàn)了最基本的基于用戶(hù)的和基于內(nèi)容的推薦算法,同時(shí)也提供了擴(kuò)展接口,使用戶(hù)可以方便的定義和實(shí)現(xiàn)自己的推薦算法。同時(shí),Taste 不僅僅只適用于 Java 應(yīng)用程序,它可以作為內(nèi)部服務(wù)器的一個(gè)組件以 HTTP 和 Web Service 的形式向外界提供推薦的邏輯。Taste 的設(shè)計(jì)使它能滿(mǎn)足企業(yè)對(duì)推薦引擎在性能、靈活性和可擴(kuò)展性等方面的要求。

Taste 工作原理


圖 1. Taste 的主要組件圖
圖 1. Taste 的主要組件圖

Taste 由以下五個(gè)主要的組件組成:

  • DataModel:DataModel 是用戶(hù)喜好信息的抽象接口,它的具體實(shí)現(xiàn)支持從任意類(lèi)型的數(shù)據(jù)源抽取用戶(hù)喜好信息。Taste 默認(rèn)提供 JDBCDataModel 和 FileDataModel,分別支持從數(shù)據(jù)庫(kù)和文件中讀取用戶(hù)的喜好信息。
  • UserSimilarity 和 ItemSimilarity:UserSimilarity 用于定義兩個(gè)用戶(hù)間的相似度,它是基于協(xié)同過(guò)濾的推薦引擎的核心部分,可以用來(lái)計(jì)算用戶(hù)的“鄰居”,這里我們將與當(dāng)前用戶(hù)口味相似的用戶(hù)稱(chēng)為他的鄰居。 ItemSimilarity類(lèi)似的,計(jì)算內(nèi)容之間的相似度。
  • UserNeighborhood:用于基于用戶(hù)相似度的推薦方法中,推薦的內(nèi)容是基于找到與當(dāng)前用戶(hù)喜好相似的“鄰居用戶(hù)”的方式產(chǎn)生的。UserNeighborhood 定義了確定鄰居用戶(hù)的方法,具體實(shí)現(xiàn)一般是基于 UserSimilarity 計(jì)算得到的。
  • Recommender:Recommender 是推薦引擎的抽象接口,Taste 中的核心組件。程序中,為它提供一個(gè) DataModel,它可以計(jì)算出對(duì)不同用戶(hù)的推薦內(nèi)容。實(shí)際應(yīng)用中,主要使用它的實(shí)現(xiàn)類(lèi) GenericUserBasedRecommender 或者 GenericItemBasedRecommender,分別實(shí)現(xiàn)基于用戶(hù)相似度的推薦引擎或者基于內(nèi)容的推薦引擎。

Taste 的安裝與簡(jiǎn)單的 Demo 實(shí)現(xiàn)

安裝 Taste 的軟件需求:

  • 如果需要 build 源代碼或者例子,需要 Apache Ant 1.5+ 或 Apache Maven 2.0.10+。
  • Taste 應(yīng)用程序需要 Servlet 2.3+ 容器,例如 Jakarta Tomcat。
  • Taste 中的 MySQLJDBCDataModel 實(shí)現(xiàn)需要 MySQL 4.x+ 數(shù)據(jù)庫(kù)。

安裝 Taste 并運(yùn)行 Demo:

  1. 從 SVN 或是下載壓縮包得到 Apache Mahout 的發(fā)布版本:
  2. 從 Grouplens 下載數(shù)據(jù)源:"1 Million MovieLens Dataset"。
  3. 解壓數(shù)據(jù)源壓縮包,將 movie.dat 和 ratings.dat 拷貝到 Mahout 安裝目錄下的 taste-web/src/ main/resources/org/apache/mahout/cf/taste/example/grouplens 目錄下。
  4. 回到在 core 目錄下,運(yùn)行"mvn install",將 Mahout core 安裝在本地庫(kù)中。
  5. 進(jìn)入 taste-web, 拷貝 ../examples/target/grouplens.jar 到 taste-web/lib 目錄
  6. 編輯 taste-web/recommender.properties,將 recommender.class 設(shè)置為 org.apache.mahout. cf.taste.example.grouplens.GroupLensRecommender。
  7. 在 Mahout 的安裝目錄下,運(yùn)行"mvn package"。
  8. 運(yùn)行“mvn jetty:run-war”。這里需要將 Maven 的最大內(nèi)存設(shè)置為 1024M,MAVEN_OPTS=-Xmx1024M。如果需要在 Tomcat 下運(yùn)行,可以在執(zhí)行"mvn package"后,將 taste-web/target 目錄下生成的 war 包拷貝到 Tomcat 的 webapp 下,同時(shí)也需要將 Java 的最大內(nèi)存設(shè)置為 1024M,JAVA_OPTS=-Xmx1024M,然后啟動(dòng) Tomcat。
  9. 訪(fǎng)問(wèn)“http://localhost:8080/[your_app] /RecommenderServlet?userID=1”,得到系統(tǒng)為編號(hào)為 1 的用戶(hù)的推薦內(nèi)容。參看圖 2,Taste demo 運(yùn)行結(jié)果界面,每一行第一項(xiàng)是推薦引擎預(yù)測(cè)的評(píng)分,第二項(xiàng)是電影的編號(hào)。
  10. 同時(shí),Taste 還提供 Web 服務(wù)訪(fǎng)問(wèn)接口,通過(guò)以下 URL 訪(fǎng)問(wèn):

    http://localhost:8080/[your_app]/RecommenderService.jws

    WSDL 文件:http://localhost:8080/[your_app]/RecommenderService.jws?wsdl

    也可以通過(guò)簡(jiǎn)單的 HTTP 請(qǐng)求調(diào)用這個(gè) Web 服務(wù):

    http://localhost:8080/[your_app]/RecommenderService.jws?method=recommend&userID=1&howMany=10


圖 2. Taste Demo 運(yùn)行結(jié)果界面
圖 2. Taste Demo 運(yùn)行結(jié)果界面

使用 Taste 構(gòu)建推薦引擎實(shí)例 – 電影推薦引擎

根據(jù)上面的步驟,我們可以得到一個(gè)簡(jiǎn)單的推薦引擎 demo 環(huán)境,下面介紹如何使用 Taste 方便地構(gòu)建自定義的推薦引擎。

抽取 Taste 工具包

直接使用 Mahout 的項(xiàng)目環(huán)境進(jìn)行編碼,需要使用 Ant 或者 Maven 進(jìn)行編譯,整個(gè)過(guò)程比較復(fù)雜,這里我們將構(gòu)建推薦引擎所需要的工具包從 Mahout 工程中抽取出來(lái),從而方便的構(gòu)建自定義的推薦引擎。

在 Eclipse 中創(chuàng)建 Web 應(yīng)用的工程 MovieSite,將 demo 時(shí)生成的推薦引擎 Web 應(yīng)用的 war 包解壓縮,將 lib 下的 jar 文件拷貝到 MovieSite 的 lib 目錄下。這樣我們就可以方便的編寫(xiě)自己的推薦引擎。


圖 3. MovieSite 工程中引用的 jar 文件
圖 3. MovieSite 工程中引用的 jar 文件

數(shù)據(jù)建模

這里我們想要編寫(xiě)一個(gè)電影推薦引擎,第一步需要對(duì)數(shù)據(jù)進(jìn)行建模,分析應(yīng)用中涉及的主要實(shí)體以及實(shí)體間的關(guān)系,從而設(shè)計(jì)數(shù)據(jù)庫(kù)存儲(chǔ),程序中的類(lèi),以及推薦引擎的 DataModel。


圖 4 電影和用戶(hù)信息數(shù)據(jù)模型
圖 4 電影和用戶(hù)信息數(shù)據(jù)模型

數(shù)據(jù)模型中存在以下實(shí)體:

  • Movie:表示電影,包含電影的基本信息:編號(hào)、名稱(chēng)、發(fā)布時(shí)間、類(lèi)型等等。
  • User:表示用戶(hù),包含用戶(hù)的基本信息:編號(hào)、姓名、郵件等等。
  • Movie Reference:表示某個(gè)用戶(hù)對(duì)某個(gè)電影的喜好程度,包含用戶(hù)編號(hào)、電影編號(hào)、用戶(hù)的評(píng)分以及評(píng)分的時(shí)間。
  • Movie Similarity:表示兩個(gè)電影的相似度(這里的相似度是雙向的),包括兩個(gè)電影編號(hào)、電影的相似度。兩個(gè)電影的相似度可以通過(guò)電影的基本信息計(jì)算得到。

下面我們就基于這個(gè)數(shù)據(jù)模型設(shè)計(jì)數(shù)據(jù)庫(kù)的存儲(chǔ)以及推薦引擎的 DataModel。

  1. 1 .創(chuàng)建 MySQL 數(shù)據(jù)庫(kù)存儲(chǔ)電影和用戶(hù)的信息,用戶(hù)的喜好信息以及電影的相似度。



    清單 1. 創(chuàng)建數(shù)據(jù)庫(kù) SQL
     
    CREATE DATABASE movie;
    USE movie;
    CREATE TABLE movies ( // 保存電影相關(guān)的信息。
    id INTEGER NOT NULL AUTO_INCREMENT,
    name varchar(100) NOT NULL,
    published_year varchar(4) default NULL,
    type varchar(100) default NULL,
    -- ...more movie information...
    PRIMARY KEY (id)
    );

    CREATE TABLE users ( // 保存用戶(hù)信息
    id INTEGER NOT NULL AUTO_INCREMENT,
    name varchar(50) NOT NULL,
    email varchar(100) default NULL,
    -- ...more user information...
    PRIMARY KEY (id)
    );

    CREATE TABLE movie_preferences ( // 保存用戶(hù)對(duì)電影的評(píng)分,即喜好程度
    userID INTEGER NOT NULL,
    movieID INTEGER NOT NULL,
    preference INTEGER NOT NULL DEFAULT 0,
    timestamp INTEGER not null default 0,
    FOREIGN KEY (userID) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (movieID) REFERENCES movies(id) ON DELETE CASCADE
    );

    CREATE TABLE movie_similarity ( // 保存電影和電影的相似程度
    movieID1 INTEGER NOT NULL,
    movieID2 INTEGER NOT NULL,
    similarity DOUBLE NOT NULL DEFAULT 0,
    FOREIGN KEY (movieID1) REFERENCES movies(id) ON DELETE CASCADE,
    FOREIGN KEY (movieID2) REFERENCES movies(id) ON DELETE CASCADE
    );

    CREATE INDEX movie_preferences_index1 ON movie_preferences ( userID , movieID );
    CREATE INDEX movie_preferences_index2 ON movie_preferences ( userID );
    CREATE INDEX movie_preferences_index3 ON movie_preferences ( movieID );

    在實(shí)際應(yīng)用中,我們需要將應(yīng)用中的實(shí)例數(shù)據(jù)寫(xiě)入到數(shù)據(jù)庫(kù)中。作為例子,這里將從 GroupLen 下載的數(shù)據(jù)源寫(xiě)入數(shù)據(jù)庫(kù)。

  2. 設(shè)計(jì)實(shí)現(xiàn)推薦引擎的 DataModel。

    由于上面采用數(shù)據(jù)庫(kù)存儲(chǔ)用戶(hù)的喜好信息,這里需要基于數(shù)據(jù)庫(kù)的推薦引擎實(shí)現(xiàn)。這里擴(kuò)展 MySQLJDBCDataModel 實(shí)現(xiàn)電影推薦引擎的 DataModel 實(shí)例。



    清單 2. Taste DataModel 的實(shí)現(xiàn)
     
    public class MovieDataModel extends MySQLJDBCDataModel {

    //保存用戶(hù)對(duì)電影的評(píng)分的數(shù)據(jù)庫(kù)表名
    public final static String PERFERENCETABLE = "movie_preferences";
    public final static String USERID_COLUMN = "userID"; //表中用戶(hù)標(biāo)識(shí)的列名
    public final static String ITEMID_COLUMN = "movieID"; //表中電影標(biāo)識(shí)的列名
    public final static String PERFERENCE_COLUMN = "preference"; //表中評(píng)分的列名

    public MovieDataModel(String dataSourceName) throws TasteException {
    super(lookupDataSource(dataSourceName), PERFERENCETABLE, USERID_COLUMN,
    ITEMID_COLUMN, PERFERENCE_COLUMN);
    }

    public MovieDataModel() {
    //DBUtil.getDataSource() 將返回應(yīng)用的數(shù)據(jù)源
    //此應(yīng)用是J2EE應(yīng)用,所以這里會(huì)采用JDNI的方式創(chuàng)建數(shù)據(jù)庫(kù)鏈接。
    super(DBUtil.getDataSource(), PERFERENCETABLE, USERID_COLUMN,
    ITEMID_COLUMN, PERFERENCE_COLUMN);
    }
    }

推薦引擎實(shí)現(xiàn)

前面介紹了數(shù)據(jù)建模和 DataModel 的實(shí)現(xiàn),下面來(lái)詳細(xì)介紹推薦引擎的實(shí)現(xiàn)。如前面介紹的,Taste 既實(shí)現(xiàn)了最基本的基于用戶(hù)的和基于內(nèi)容的推薦算法,同時(shí)也提供了擴(kuò)展接口,使用戶(hù)可以方便的定義和實(shí)現(xiàn)自己的推薦算法。下面詳細(xì)介紹如何擴(kuò)展 Taste 的推薦引擎接口,實(shí)現(xiàn)基于用戶(hù)相似度的推薦引擎,基于內(nèi)容相似度的推薦引擎,以及 Slope One 的推薦引擎。Slope One 是一種非??焖俸?jiǎn)單的基于項(xiàng)目的推薦方法,需要使用用戶(hù)的評(píng)分信息。


清單 3. 基于用戶(hù)相似度的推薦實(shí)現(xiàn)

 
public class UserBasedRecommender implements Recommender {

private final Recommender recommender;

public UserBasedRecommender() throws IOException, TasteException {
this(new MovieDataModel());
}

public UserBasedRecommender(DataModel model) throws TasteException {

UserSimilarity userSimilarity = new PearsonCorrelationSimilarity(model);
userSimilarity.setPreferenceInferrer(new AveragingPreferenceInferrer(model));

UserNeighborhood neighborhood =
new NearestNUserNeighborhood(3, userSimilarity, model);
recommender = new CachingRecommender(
new GenericUserBasedRecommender(model, neighborhood, userSimilarity));
}

//對(duì)外提供的推薦的接口,參數(shù)為用戶(hù)標(biāo)識(shí)和推薦項(xiàng)的個(gè)數(shù)
public List<RecommendedItem> recommend(long userID, int howMany)
throws TasteException {
return recommender.recommend(userID, howMany);
}

public List<RecommendedItem> recommend(long userID, int howMany,
Rescorer<Long> rescorer) throws TasteException {
return recommender.recommend(userID, howMany, rescorer);
}

//以下方法都是實(shí)現(xiàn)Recommender的接口
public float estimatePreference(long userID, long itemID) throws TasteException {
return recommender.estimatePreference(userID, itemID);
}

public void setPreference(long userID, long itemID, float value)
throws TasteException {
recommender.setPreference(userID, itemID, value);
}

public void removePreference(long userID, long itemID) throws TasteException {
recommender.removePreference(userID, itemID);
}

public DataModel getDataModel() {
return recommender.getDataModel();
}

public void refresh(Collection<Refreshable> alreadyRefreshed) {
recommender.refresh(alreadyRefreshed);
}

public String toString() {
return "UserBasedRecommender[recommender:" + recommender + ']';
}
}

從上面的代碼示例清單 3 可以看出,實(shí)現(xiàn)一個(gè)推薦引擎需要實(shí)現(xiàn) Recommender 接口,它一般是對(duì)于某種 Taste 提供的推薦引擎的擴(kuò)展,這是對(duì) GenericUserBasedRecommender 進(jìn)行的擴(kuò)展,其中最重要的方法就是實(shí)例化推薦引擎的構(gòu)造方法,一般其中涉及以下步驟:

  • 基于 DataModel,計(jì)算用戶(hù)的相似度,這里采用 PearsonCorrelation 算法。
  • 為用戶(hù)相似度設(shè)置相似度推理方法,這里采用了 AveragingPreferenceInferrer。
  • 基于用戶(hù)相似度計(jì)算用戶(hù)的“鄰居”,這里將與該用戶(hù)最近距離為 3 的用戶(hù)設(shè)置為該用戶(hù)的“鄰居”。
  • 使用以上得到的用戶(hù)相似度對(duì)象和鄰居用戶(hù)的計(jì)算方法對(duì)象創(chuàng)建一個(gè) GenericUserBasedRecommender 的實(shí)例。一般情況下,這時(shí)都采用 CachingRecommender 為 RecommendationItem 進(jìn)行緩存,從而提高訪(fǎng)問(wèn)速度。


清單 4. 基于內(nèi)容相似度的推薦實(shí)現(xiàn)

 
public class ItemBasedRecommender implements Recommender {

private final Recommender recommender;

public ItemBasedRecommender() throws IOException, TasteException {
this(new MovieDataModel());
}

public ItemBasedRecommender(DataModel dataModel) throws TasteException {

Collection<GenericItemSimilarity.ItemItemSimilarity> correlations =
MovieSimilarityTable.getAllMovieSimilarities();
ItemSimilarity itemSimilarity = new GenericItemSimilarity(correlations);
recommender = new CachingRecommender(new EmbededItemBasedRecommender(
new GenericItemBasedRecommender(dataModel, itemSimilarity)));
}

public List<RecommendedItem> recommend(long userID, int howMany)
throws TasteException {
return recommender.recommend(userID, howMany);
}

.........

//EmbededItemBasedRecommender類(lèi)的定義
private static final class EmbededItemBasedRecommender implements Recommender {

//包含一個(gè)GenericItemBasedRecommender實(shí)例;
private final GenericItemBasedRecommender recommender;

private EmbededItemBasedRecommender(GenericItemBasedRecommender recommender) {
this.recommender = recommender;
}

public List<RecommendedItem> recommend(long userID, int howMany,
Rescorer<Long> rescorer)
throws TasteException {
FastIDSet itemIDs = recommender.getDataModel().getItemIDsFromUser(userID);
return recommender.mostSimilarItems(itemIDs.toArray(), howMany, null);
}

........

}

從上面的代碼示例清單 4 可以看出,與上一個(gè)實(shí)現(xiàn)類(lèi)似它是對(duì) GenericItemBasedRecommender 的擴(kuò)展,它的構(gòu)造方法涉及以下步驟:

  1. 為了提高推薦引擎的實(shí)時(shí)響應(yīng)速度,這里需要對(duì)電影信息的預(yù)處理,將電影的相似度提前計(jì)算好存儲(chǔ)在數(shù)據(jù)庫(kù)中的 movie_similarity 表中,然后從數(shù)據(jù)庫(kù)中讀取所有的電影的相似度,用于創(chuàng)建 ItemItemSimilarity 的集合。
  2. 基于 ItemItemSimilarity 的集合生成一個(gè)內(nèi)容相似度 ItemSimilarity。
  3. 創(chuàng)建一個(gè) EmbededItemBasedRecommender 實(shí)例,它是一個(gè)內(nèi)部類(lèi),包含一個(gè) GenericItemBasedRecommender 實(shí)例,它的 recommend 方法中,先從 DataModel 中得到該用戶(hù)評(píng)分的電影列表,然后調(diào)用 GenericItemBasedRecommender 中的 mostSimilarItems 方法計(jì)算出最相似的電影推薦給用戶(hù)。


清單 5. SlopeOne Recommeder 的實(shí)現(xiàn)

 
public final class MovieRecommender implements Recommender {

private final Recommender recommender;

public MovieRecommender() throws IOException, TasteException {
this(new MovieDataModel());
}

public MovieRecommender(DataModel dataModel) throws TasteException {
//創(chuàng)建一個(gè)SlopeOneRecommender的實(shí)例
recommender = new CachingRecommender(new SlopeOneRecommender(dataModel));
}

//對(duì)外提供的推薦的接口,參數(shù)為用戶(hù)標(biāo)識(shí)和推薦項(xiàng)的個(gè)數(shù)
public List<RecommendedItem> recommend(long userID, int howMany)
throws TasteException {
return recommender.recommend(userID, howMany);
}

........

}

Slope One 是一種非常快速簡(jiǎn)單的基于項(xiàng)目的推薦方法,它只需要使用用戶(hù)的評(píng)分信息。具體的實(shí)現(xiàn),只需要在我們的推薦引擎中包含一個(gè) SlopeOneRecommender 的實(shí)例。

推薦引擎 API 設(shè)計(jì)與實(shí)現(xiàn)

完成了推薦引擎的設(shè)計(jì)與實(shí)現(xiàn),下面我們需要設(shè)計(jì)一些 REST API,向外暴露推薦功能。為了提高推薦引擎的處理效率,這里采用 Singleton 模式實(shí)現(xiàn)一個(gè)推薦引擎的單例 MovieRecommenderSingleton。在 Servlet 啟動(dòng)的時(shí)候初始化推薦引擎的單例,以后每次調(diào)用推薦方法。


清單 6. Servlet 的實(shí)現(xiàn)

 
public class MovieRecommenderServlet extends HttpServlet {

private static final int NUM_TOP_PREFERENCES = 20;
private static final int DEFAULT_HOW_MANY = 20;

private Recommender recommender;

@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);

//從web.xml中讀取需要?jiǎng)?chuàng)建的推薦引擎類(lèi)名

String recommenderClassName = config.getInitParameter("recommender-class");
if (recommenderClassName == null) {
throw new ServletException(
"Servlet init-param "recommender-class" is not defined");
}

try {
MovieRecommenderSingleton.initializeIfNeeded(recommenderClassName);
} catch (TasteException te) {
throw new ServletException(te);
}
recommender = MovieRecommenderSingleton.getInstance().getRecommender();
}

@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException {
//Parameters.USER_ID = "userID"
String userIDString = request.getParameter(Parameters.USER_ID);
if (userIDString == null) {
throw new ServletException("userID was not specified");
}
long userID = Long.parseLong(userIDString);
String howManyString = request.getParameter(Parameters.COUNT);
//Parameters.COUNT = "count"
int howMany = howManyString == null ? DEFAULT_HOW_MANY :
Integer.parseInt(howManyString);
String format = request.getParameter(Parameters.FORMAT);
//Parameters.FORMAT = "format"
if (format == null) {
format = "json";
}

try {
//為指定用戶(hù)計(jì)算推薦的電影
List<RecommendedItem> items = recommender.recommend(userID, howMany);
//加載電影的相關(guān)信息,RecommendMovieList是保存了一組推薦電影的相關(guān)信息和
//引擎計(jì)算得到的他們的ranking
RecommendMovieList movieList = new RecommendMovieList(items);
if ("text".equals(format)) {
writePlainText(response, movieList);
} else if ("json".equals(format)) {
writeJSON(response, movieList);
} else {
throw new ServletException("Bad format parameter: " + format);
}


}
} catch (TasteException te) {
throw new ServletException(te);
} catch (IOException ioe) {
throw new ServletException(ioe);
}

}
//details please refer to the src code
}

以上完成了電影推薦引擎服務(wù)器端的編程,下面我們使用 FireFox 的插件 Poster 測(cè)試一下 HTTP 請(qǐng)求,查看推薦引擎的返回結(jié)果。對(duì)任意一個(gè)用戶(hù),推薦引擎應(yīng)該基于一定的規(guī)則計(jì)算得到一組電影以及預(yù)計(jì)的評(píng)分,為了有更好的用戶(hù)體驗(yàn),引擎在拿到推薦電影序號(hào)的列表后,從電影信息數(shù)據(jù)庫(kù)中查詢(xún)得到電影的相關(guān)信息,包括電影的名稱(chēng),發(fā)表時(shí)間以及類(lèi)型等信息。這里我們采用 JSON 作為推薦引擎的響應(yīng)格式。


圖 4. 用 Poster 測(cè)試 Servlet 的結(jié)果(查看大圖
圖 4. 用 Poster 測(cè)試 Servlet 的結(jié)果

用戶(hù)界面展示

實(shí)現(xiàn)一個(gè)推薦引擎的最后一步就是編寫(xiě)客戶(hù)端代碼,為電影推薦引擎提供一個(gè)友好的用戶(hù)界面。下面展示一下我們?yōu)殡娪巴扑]引擎寫(xiě)的一個(gè)簡(jiǎn)單的用戶(hù)界面:右邊紅色框中的是該用戶(hù)已經(jīng)打分的電影列表,左邊藍(lán)色框中是推薦引擎為用戶(hù)推薦的電影列表。

首先,展示一下基于用戶(hù)的推薦引擎的推薦結(jié)果,推薦引擎會(huì)根據(jù)用戶(hù)已打分的電影找到用戶(hù)的“鄰居”,將“鄰居”們比較喜歡的電影推薦給當(dāng)前用戶(hù)。


圖 5. 基于用戶(hù)的推薦結(jié)果(查看大圖
圖 5. 基于用戶(hù)的推薦結(jié)果

其次,圖 6 展示了基于內(nèi)容的推薦引擎的推薦結(jié)果,推薦引擎會(huì)根據(jù)用戶(hù)已打分的電影找到相似的電影,推薦給當(dāng)前用戶(hù)。


圖 6. 基于內(nèi)容的推薦結(jié)果(查看大圖
圖 6. 基于內(nèi)容的推薦結(jié)果

最后,展示 SlopeOne 推薦引擎的推薦結(jié)果,這種推薦引擎計(jì)算速度較快,效果很好,是一種非??焖俸?jiǎn)單的基于項(xiàng)目的推薦方法。


圖 7. SlopeOne 實(shí)現(xiàn)的推薦結(jié)果(查看大圖
圖 7. SlopeOne 實(shí)現(xiàn)的推薦結(jié)果

總結(jié)

目前幾乎所有大型的電子商務(wù)系統(tǒng),都不同程度地使用了各種形式的推薦引擎。推薦技術(shù)的使用,不僅大大的提高了用戶(hù)購(gòu)物的體驗(yàn),增加了用戶(hù)的粘著度,而且電子商務(wù)公司也由于推薦系統(tǒng)的應(yīng)用而大大的提高了交叉銷(xiāo)售的可能,從而大大的提高了營(yíng)業(yè)額。今天,你有自己的商品推薦系統(tǒng)么?

借鑒于電子商務(wù)的成功經(jīng)驗(yàn),我們可以把推薦技術(shù)應(yīng)用到其他的領(lǐng)域。像我們?cè)谖恼轮兴菔镜哪菢樱憧梢詣?chuàng)建一個(gè)電影的推薦引擎。如果你是一個(gè) blogger,那么你可以創(chuàng)建一個(gè)博客的推薦引擎,如果你是一個(gè)新聞提供商,你可以使用推薦技術(shù)為不同的用戶(hù)推薦它可能關(guān)心的新聞,等等。

今天,你推薦了么?

今天,你推薦了么?

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多