結合目前已存在的商品推薦設計(如淘寶、京東等),推薦系統主要包含系統推薦和個性化推薦兩個模塊。html
系統推薦: 根據大衆行爲的推薦引擎,對每一個用戶都給出一樣的推薦,這些推薦能夠是靜態的由系統管理員人工設定的,或者基於系統全部用戶的反饋統計計算出的當下比較流行的物品。算法
個性化推薦:對不一樣的用戶,根據他們的口味和喜愛給出更加精確的推薦,這時,系統須要瞭解需推薦內容和用戶的特質,或者基於社會化網絡,經過找到與當前用戶相同喜愛的用戶,實現推薦。mongodb
下面具體介紹系統推薦和個性化推薦的設計方案。數據庫
2.一、系統推薦目的apache
針對全部用戶推薦,當前比較流行的商品(必選) 或 促銷實惠商品(可選) 或 新上市商品(可選),以促進商品的銷售量。
PS:根據咱們的應用狀況考慮是否 選擇推薦 促銷實惠商品 和 新上市商品。(TODO1)markdown
2.二、實現方式網絡
實現方式包含:系統自動化推薦 和 人工設置推薦。框架
(1)系統自動化推薦考慮因素有:商品發佈時間、商品分類、庫存餘量、歷史被購買數量、歷史被加入購物車數量、歷史被瀏覽數量、降價幅度等。根據咱們當前可用數據,再進一步肯定(TODO2)機器學習
(2)人工設置:提供運營頁面供運營人員設置,設置包含排行位置、開始時間和結束時間、推薦介紹等等。分佈式
因爲系統推薦實現相對簡單,所以不做過多的文字說明,下面詳細介紹個性化推薦的設計。
3.一、個性化推薦目的
對不一樣的用戶,根據他們的口味和喜愛給出更加精確的推薦,系統須要瞭解需推薦內容和用戶的特質,或者基於社會化網絡,經過找到與當前用戶相同喜愛的用戶,實現推薦,以促進商品的銷售量。
3.二、三種推薦模式的介紹
據推薦引擎的數據源有三種模式:基於人口統計學的推薦、基於內容的推薦、基於協同過濾的推薦。
(1)基於人口統計學的推薦:針對用戶的「性別、年齡範圍、收入狀況、學歷、專業、職業」進行推薦。
(2)基於內容的推薦:以下圖,這裏沒有考慮人對物品的態度,僅僅是由於電影A月電影C類似,所以將電影C推薦給用戶A。這是與後面講到的協同過濾推薦最大的不一樣。
(3)基於協同過濾的推薦:以下圖,這裏咱們並不知道物品A和物品D是否類似,僅僅考慮人對物品的喜愛進行推薦。
模式採用:這三種模式能夠單獨使用,也可結合使用。結合咱們實際狀況,採用基於協同過濾的推薦更加合適,看後期狀況是否結合另外兩種模式實現推薦。但基於協同過濾的推薦這種模式,會引起「冷啓動」問題。關於,冷啓動問題,後續會討論解決方案。
3.三、用戶喜愛設計
(1)判斷用戶喜愛因素:歷史購買、歷史購物車、歷史搜索、歷史瀏覽等,待肯定咱們可用數據再進一步細化。
(2)用戶對某個商品的喜愛程度,經過不一樣行爲對應不一樣分值權重,如:歷史購買(10)、歷史購物車(8)、歷史搜索(5)、歷史瀏覽(6),肯定用戶喜愛因素後再進一步對各個因素評分權重進行 合理的設計。
(3)用戶對商品的喜愛程度最終體現:結合某個商品的不一樣行爲 統計出 最終對該商品的喜愛程度,即對商品的喜愛程度,最終以一個數字體現。
3.四、Mahout介紹
目前選擇採用協同過濾框架Mahout進行實現。
Mahout 是一個很強大的數據挖掘工具,是一個分佈式機器學習算法的集合,包括:被稱爲Taste的分佈式協同過濾的實現、分類、聚類等。Mahout最大的優勢就是基於hadoop實現,把不少之前運行於單機上的算法,轉化爲了MapReduce模式,這樣大大提高了算法可處理的數據量和處理性能。
Mahout 是一個布式機器學習算法的集合,可是這裏咱們只使用到它的推薦/協同過濾算法。
3.五、Mahout實現協同過濾實例
協同過濾在mahout裏是由一個叫taste的引擎提供的, 它提供兩種模式,一種是以jar包形式嵌入到程序裏在進程內運行,另一種是MapReduce Job形式在hadoop上運行。這兩種方式使用的算法是同樣的,配置也相似。
這裏咱們採用第一種引入jar包的單機模式。
3.5.一、依賴
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-core</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-math</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>1.2.1</version>
</dependency>
3.5.二、實現代碼
public static void main(String[] args) {
try {
// 從文件加載數據
DataModel model = new FileDataModel(new File("D:\\mahout\\data.csv"));
// 指定用戶類似度計算方法,這裏採用皮爾森相關度
UserSimilarity similarity = new PearsonCorrelationSimilarity(model);
// 指定用戶鄰居數量,這裏爲2
UserNeighborhood neighborhood = new NearestNUserNeighborhood(2,
similarity, model);
// 構建基於用戶的推薦系統
Recommender recommender = new GenericUserBasedRecommender(model,
neighborhood, similarity);
// 獲得指定用戶的推薦結果,這裏是獲得用戶1的兩個推薦
List<RecommendedItem> recommendations = recommender.recommend(1, 2);
// 打印推薦結果
for (RecommendedItem recommendation : recommendations) {
System.out.println(recommendation);
}
} catch (Exception e) {
System.out.println(e);
}
}
3.5.三、data.csv內容(用戶id、商品id,評分)
1,101,5 1,102,3 1,103,2.5 2,101,2 2,102,2.5 2,103,5 2,104,2 3,101,2.5 3,104,4 3,105,4.5 3,107,5 4,101,5 4,103,3 4,104,4.5 4,106,4 5,101,4 5,102,3 5,103,2 5,104,4 5,105,3.5 5,106,4
3.5.四、運行結果
3.六、Mahout協同過濾算法選用
3.6.一、Mahout協同過濾自帶算法介紹
Mahout算法框架自帶的推薦器有下面這些:
GenericUserBasedRecommender:基於用戶的推薦器,用戶數量少時速度快;
GenericItemBasedRecommender:基於商品推薦器,商品數量少時速度快,尤爲當外部提供了商品類似度數據後效率更好;
SlopeOneRecommender:基於slope-one算法的推薦器,在線推薦或更新較快,須要事先大量預處理運算,物品數量少時較好;
SVDRecommender:奇異值分解,推薦效果較好,但以前須要大量預處理運算;
KnnRecommender:基於k近鄰算法(KNN),適合於物品數量較小時;
TreeClusteringRecommender:基於聚類的推薦器,在線推薦較快,以前須要大量預處理運算,用戶數量較少時效果好;
Mahout最經常使用的三個推薦器是上述的前三個,本文主要討論前兩種的使用。
3.6.二、考慮使用算法
(1)GenericUserBasedRecommender(推薦)
一個很簡單的user-based模式的推薦器實現類,根據傳入的DataModel和UserNeighborhood進行推薦。其推薦流程分紅三步:
第一步,使用UserNeighborhood獲取跟指定用戶Ui最類似的K個用戶{U1…Uk};
第二步,{U1…Uk}喜歡的item集合中排除掉Ui喜歡的item, 獲得一個item集合 {Item0…Itemm}
第三步,對{Item0…Itemm}每一個itemj計算 Ui可能喜歡的程度值perf(Ui , Itemj) ,並把item按這個數值從高到低排序,把前N個item推薦給Ui。其中perf(Ui , Itemj)的計算公式以下:
其中 是用戶Ul對Itemj的喜愛值。
(2)GenericItemBasedRecommender
一個簡單的item-based的推薦器,根據傳入的DateModel和ItemSimilarity去推薦。基於Item的類似度計算比基於User的類似度計算有個好處是,item數量較少,計算量也就少了,另外item之間的類似度比較固定,因此類似度能夠事先算好,這樣能夠大幅提升推薦的速度。
其推薦流程能夠分紅三步:
第一步,獲取用戶Ui喜愛的item集合{It1…Itm}
第二步,使用MostSimilarItemsCandidateItemsStrategy(有多種策略, 功能相似UserNeighborhood) 獲取跟用戶喜愛集合裏每一個item最類似的其餘Item構成集合 {Item1…Itemk};
第三步,對{Item1…Itemk}裏的每一個itemj計算 Ui可能喜歡的程度值perf(Ui , Itemj) ,並把item按這個數值從高到低排序,把前N個Item推薦給Ui。其中perf(Ui , Itemj)的計算公式以下:
其中 是用戶Ul對Iteml的喜愛值。
(3)SlopeOneRecommender
基於Slopeone算法的推薦器,Slopeone算法適用於用戶對item的打分是具體數值的狀況。Slopeone算法不一樣於前面提到的基於類似度的算法,他計算簡單快速,對新用戶推薦效果不錯,數據更新和擴展性都很不錯,預測能達到和基於類似度的算法差很少的效果,很適合在實際項目中使用。
綜合考慮,咱們使用GenericUserBasedRecommender(基於用戶的推薦器)比較合適。3.五、Mahout實現協同過濾實例 就是採用這種算法實現的。
3.七、Mahout數據源獲取方式
DataModel 是用戶喜愛信息的抽象接口,它的具體實現支持從任意類型的數據源抽取用戶喜愛信息。Taste 默認提供 JDBCDataModel 和 FileDataModel,分別支持從數據庫和文件中讀取用戶的喜愛信息。
目前,Mahout爲DataModel提供瞭如下幾種實現:
org.apache.mahout.cf.taste.impl.model.GenericDataModel
org.apache.mahout.cf.taste.impl.model.GenericBooleanPrefDataModel
org.apache.mahout.cf.taste.impl.model.PlusAnonymousUserDataModel
org.apache.mahout.cf.taste.impl.model.file.FileDataModel
org.apache.mahout.cf.taste.impl.model.hbase.HBaseDataModel
org.apache.mahout.cf.taste.impl.model.cassandra.CassandraDataModel
org.apache.mahout.cf.taste.impl.model.mongodb.MongoDBDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92JDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.GenericJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.SQL92BooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.MySQLBooleanPrefJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.PostgreBooleanPrefSQLJDBCDataModel
org.apache.mahout.cf.taste.impl.model.jdbc.ReloadFromJDBCDataModel
從類名上就能夠大概猜出來每一個DataModel的用途,可是居然沒有HDFS的DataModel,有人實現了一個,請參考MAHOUT-1579(https://issues.apache.org/jira/browse/MAHOUT-1579)。
3.八、協同過濾實現採用技術
採用以下技術:Mahout(推薦算法) + Spark(並行計算) + Hadoop + Elasticsearch
Mahout 是一個很強大的數據挖掘工具,是一個分佈式機器學習算法的集合,包括:被稱爲Taste的分佈式協同過濾的實現、分類、聚類等。Mahout最大的優勢就是基於hadoop實現,把不少之前運行於單機上的算法,轉化爲了MapReduce模式,這樣大大提高了算法可處理的數據量和處理性能。
Spark是UC Berkeley AMP lab所開源的類Hadoop MapReduce的通用的並行計算框架,Spark基於map reduce算法實現的分佈式計算,擁有Hadoop MapReduce所具備的優勢;但不一樣於MapReduce的是Job中間輸出結果能夠保存在內存中,從而再也不須要讀寫HDFS,所以Spark能更好地適用於數據挖掘與機器學習等須要迭代的map reduce的算法。
但Spark沒有提供文件管理系統,因此,它必須和其餘的分佈式文件系統進行集成才能運做。這裏咱們能夠選擇Hadoop的HDFS,也能夠選擇其餘的基於雲的數據系統平臺。但Spark默認來講仍是被用在Hadoop上面的,畢竟,你們都認爲它們的結合是最好的。
PS:Mahout(推薦算法) + Spark(並行計算) + Hadoop + Elasticsearch搭配的實現方式並無嘗試,網上有一些解決方案,可是並不詳細,並且英文居多,所以須要進一步學習研究。
可參考文獻:https://mahout.apache.org/users/algorithms/intro-cooccurrence-spark.html
3.九、冷啓動問題
所謂冷啓動,是指對於不少推薦引擎的開始階段,當一個新用戶進入推薦系統或者系統添加一個新的物品後,因爲尚未大量的用戶數據,系統沒法計算出推薦模型,從而致使系統的推薦功能失效的問題。
可考慮的解決方案有:
(1)利用用戶註冊信息進行初步推薦,主要包括人口統計學信息、用戶描述的我的興趣內容,預先設定好用戶的偏好信息。
(2)在用戶第一次訪問系統時,給用戶提供一些物品,讓用戶反饋對這些物品的評分,而後根據用戶的反饋造成初始的個性化推薦。
(3)邀請行業的專家對新的用戶或者新的物品
進行分類、評註。
(4)隨機推薦的方法。對於冷啓動問題,實際應用中最簡單最直觀的方法是採用隨機推薦的 方式。這種方法是比較冒險。
(5)平均值法。全部項目的均值,做爲用戶對未評價過項目的預測值,將原始評分矩陣進行 填充,而後在填充後的評分矩陣上尋找目標用戶的最近鄰居,應用協同過濾的方法產生推薦。可是均值的方法只能說是一種被動應付的方式,新用戶對項目的喜愛值正好等於其餘用戶對此項目的平均值的機率是很是小的。
根據咱們實際狀況,建議使用第(1)種解決方案比較合適。