Spark機器學習實戰 (十二) - 推薦系統實戰

0 相關源碼

將結合前述知識進行綜合實戰,以達到所學即所用。在推薦系統項目中,講解了推薦系統基本原理以及實現推薦系統的架構思路,有其餘相關研發經驗基礎的同窗能夠結合以往的經驗,實現本身的推薦系統。git

1 推薦系統簡介

1.1 什麼是推薦系統

1.2 推薦系統的做用

1.2.1 幫助顧客快速定位需求,節省時間

1.2.2 大幅度提升銷售量

1.3 推薦系統的技術思想

1.3.1 推薦系統是一種機器學習的工程應用

1.3.2 推薦系統基於知識發現原理

1.4 推薦系統的工業化實現

  • Apache Spark github

  • Apache Mahout 算法

  • SVDFeature(C++) apache

  • LibMF(C+ +,Lin Chih-Jen) bash

2 推薦系統原理

多是推薦系統最詳細且簡單的入門教程架構

官方文檔指南

協同過濾

協同過濾一般用於推薦系統。這些技術旨在填寫用戶項關聯矩陣的缺失條目。 spark.ml目前支持基於模型的協同過濾,其中用戶和產品由一小組可用於預測缺失條目的潛在因素描述。 spark.ml使用交替最小二乘(ALS)算法來學習這些潛在因素。 spark.ml中的實現具備如下參數:dom

  • numBlocks 用戶和項目將被分區爲多個塊的數量,以便並行化計算(默認爲10)。機器學習

  • rank 模型中潛在因子的數量(默認爲10)。性能

  • maxIter 要運行的最大迭代次數(默認爲10)。學習

  • regParam 指定ALS中的正則化參數(默認爲1.0)。

  • implicitPrefs 指定是使用顯式反饋ALS變體仍是使用適用於隱式反饋數據的變量(默認爲false,這意味着使用顯式反饋)。

  • alpha 適用於ALS的隱式反饋變量的參數,其控制偏好觀察中的基線置信度(默認爲1.0)。 nonnegative指定是否對最小二乘使用非負約束(默認爲false)。

注意:基於DataFrame的ALS API目前僅支持用戶和項ID的整數。 user和item id列支持其餘數字類型,但id必須在整數值範圍內。

顯性與隱性反饋

基於矩陣分解的協同過濾的標準方法將用戶項矩陣中的條目視爲用戶對項目給出的顯式偏好,例如,給予電影評級的用戶。

在許多現實世界的用例中,一般只能訪問隱式反饋(例如,觀看,點擊,購買,喜歡,分享等)。 spark.ml中用於處理此類數據的方法取自Collaborative Filtering for Implicit Feedback Datasets。本質上,這種方法不是試圖直接對評級矩陣進行建模,而是將數據視爲表示用戶操做觀察強度的數字(例如點擊次數或某人花在觀看電影上的累積持續時間)。而後,這些數字與觀察到的用戶偏好的置信水平相關,而不是與項目的明確評級相關。而後,該模型試圖找到可用於預測用戶對項目的預期偏好的潛在因素。

縮放正則化參數

咱們經過用戶在更新用戶因素時產生的評級數或在更新產品因子時收到的產品評級數來縮小正則化參數regParam以解決每一個最小二乘問題。 這種方法被命名爲「ALS-WR」,並在「Netflix獎的大規模並行協同過濾」一文中進行了討論。 它使regParam較少依賴於數據集的規模,所以咱們能夠將從採樣子集中學習的最佳參數應用於完整數據集,並指望得到相似的性能。

冷啓動策略

在使用ALS模型進行預測時,一般會遇到測試數據集中的用戶和/或項目,這些用戶和/或項目在訓練模型期間不存在。這一般發生在兩種狀況中:

  • 在生產中,對於沒有評級歷史且未對模型進行過訓練的新用戶或項目(這是「冷啓動問題」)。
  • 在交叉驗證期間,數據在訓練和評估集之間分割。當使用Spark的CrossValidator或TrainValidationSplit中的簡單隨機分割時,實際上很常見的是在評估集中遇到不在訓練集中的用戶和/或項目 默認狀況下,當模型中不存在用戶和/或項目因子時,Spark會在ALSModel.transform期間分配NaN預測。這在生產系統中頗有用,由於它表示新用戶或項目,所以系統能夠決定使用某些後備做爲預測。

可是,這在交叉驗證期間是不合須要的,由於任何NaN預測值都將致使評估指標的NaN結果(例如,使用RegressionEvaluator時)。這使得模型選擇不可能。

Spark容許用戶將coldStartStrategy參數設置爲「drop」,以便刪除包含NaN值的預測的DataFrame中的任何行。而後將根據非NaN數據計算評估度量而且該評估度量將是有效的。如下示例說明了此參數的用法。

注意:目前支持的冷啓動策略是「nan」(上面提到的默認行爲)和「drop」。未來可能會支持進一步的戰略。

在如下示例中,咱們從MovieLens數據集加載評級數據,每行包含用戶,電影,評級和時間戳。 而後,咱們訓練一個ALS模型,默認狀況下,該模型假設評級是顯式的(implicitPrefs爲false)。 咱們經過測量評級預測的均方根偏差來評估推薦模型。

import org.apache.spark.ml.evaluation.RegressionEvaluator
import org.apache.spark.ml.recommendation.ALS

case class Rating(userId: Int, movieId: Int, rating: Float, timestamp: Long)
def parseRating(str: String): Rating = {
  val fields = str.split("::")
  assert(fields.size == 4)
  Rating(fields(0).toInt, fields(1).toInt, fields(2).toFloat, fields(3).toLong)
}

val ratings = spark.read.textFile("data/mllib/als/sample_movielens_ratings.txt")
  .map(parseRating)
  .toDF()
val Array(training, test) = ratings.randomSplit(Array(0.8, 0.2))

// Build the recommendation model using ALS on the training data
val als = new ALS()
  .setMaxIter(5)
  .setRegParam(0.01)
  .setUserCol("userId")
  .setItemCol("movieId")
  .setRatingCol("rating")
val model = als.fit(training)

// Evaluate the model by computing the RMSE on the test data
// Note we set cold start strategy to 'drop' to ensure we don't get NaN evaluation metrics model.setColdStartStrategy("drop") val predictions = model.transform(test) val evaluator = new RegressionEvaluator() .setMetricName("rmse") .setLabelCol("rating") .setPredictionCol("prediction") val rmse = evaluator.evaluate(predictions) println(s"Root-mean-square error = $rmse") // Generate top 10 movie recommendations for each user val userRecs = model.recommendForAllUsers(10) // Generate top 10 user recommendations for each movie val movieRecs = model.recommendForAllItems(10) // Generate top 10 movie recommendations for a specified set of users val users = ratings.select(als.getUserCol).distinct().limit(3) val userSubsetRecs = model.recommendForUserSubset(users, 10) // Generate top 10 user recommendations for a specified set of movies val movies = ratings.select(als.getItemCol).distinct().limit(3) val movieSubSetRecs = model.recommendForItemSubset(movies, 10) 複製代碼

若是評級矩陣是從另外一個信息源派生的(即從其餘信號推斷出來),您能夠將implicitPrefs設置爲true以得到更好的結果:

val als = new ALS()
  .setMaxIter(5)
  .setRegParam(0.01)
  .setImplicitPrefs(true)
  .setUserCol("userId")
  .setItemCol("movieId")
  .setRatingCol("rating")
複製代碼

3 推薦系統實戰coding

3.1 分割數據集

  • 數據集 tab分割

  • 代碼分割數據集

  • 分割結果

3.2 預測評分

  • 預測代碼
  • 預測結果

3.3 MovieLens數據集推薦

  • 數據集推薦代碼

MovieLens數據集由GroupLens研究組在 University of Minnesota — 明尼蘇達大學(與咱們使用數據集無關)中組織的。 MovieLens是電影評分的集合,有各類大小。 數據集命名爲1M,10M和20M,是由於它們包含1,10和20萬個評分。 最大的數據集使用約14萬用戶的數據,並覆蓋27,000部電影。 除了評分以外,MovieLens數據還包含相似「Western」的流派信息和用戶應用的標籤,如「over the top」和「Arnold Schwarzenegger」。 這些流派標記和標籤在構建內容向量方面是有用的。內容向量對項目的信息進行編碼,例如顏色,形狀,流派或真正的任何其餘屬性 - 能夠是用於基於內容的推薦算法的任何形式。

MovieLens的數據在過去20年中已經由大學的學生以及互聯網上的人們進行收集了。 MovieLens有一個網站,您能夠註冊,貢獻本身的評分,並接收由GroupLens組實施的幾個推薦者算法這裏之一的推薦內容。

  • 用戶ID

  • 所推電影

Spark機器學習實踐系列

X 交流學習

Java交流羣

博客

知乎

Github

相關文章
相關標籤/搜索