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

0 相關源碼

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

1 推薦系統簡介

1.1 什麼是推薦系統

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

1.2 推薦系統的作用

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

1.2.2 大幅度提高銷售量

1.3 推薦系統的技術思想

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

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

1.4 推薦系統的工業化實現

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

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

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

  • LibMF(C+ +,Lin Chih-Jen)
    Spark機器學習實戰 (十二) - 推薦系統實戰

2 推薦系統原理

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

可能是推薦系統最詳細且簡單的入門教程

官方文檔指南

協同過濾

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

  • 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分割
    Spark機器學習實戰 (十二) - 推薦系統實戰

  • 代碼分割數據集
    Spark機器學習實戰 (十二) - 推薦系統實戰

  • 分割結果
    Spark機器學習實戰 (十二) - 推薦系統實戰

3.2 預測評分

  • 預測代碼
    Spark機器學習實戰 (十二) - 推薦系統實戰
  • 預測結果
    Spark機器學習實戰 (十二) - 推薦系統實戰

3.3 MovieLens數據集推薦

  • 數據集推薦代碼
    Spark機器學習實戰 (十二) - 推薦系統實戰

    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機器學習實戰 (十二) - 推薦系統實戰

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

Spark機器學習實踐系列

X 交流學習

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

Java交流羣

博客

知乎

Github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章