戳蓝色字关注我们哟!
导读:在《推荐算法概述》一文中,我们介绍了推荐算法分为基于用户、基于物品、基于模型的协同过滤方法,矩阵分解模型是典型的基于模型的方法之一,本文将从基本概念、原理、实践几个角度进行介绍。
1
基本概念
- 显式信息 & 隐式信息 显式信息指用户对物品的直接打分,如对商户、电影、书籍的评分。 隐式信息指用户对物品没有直接打分,需要通过点击次数、浏览时间、收藏、购买次数等反应感兴趣程度。
- 评分预测 & TopN推荐 两者属于推荐系统的应用场景。评分预测将用户对商品的打分表示为一个二维矩阵,如无打分则空,因此打分矩阵非常稀疏,评分预测就是根据已有打分补全缺失打分的过程。评分预测可用显式信息也可用隐式信息。TopN是根据隐式信息生成一个感兴趣列表,然后给用户进行推荐。
2
原理简述
矩阵分解指将一个大的矩阵转化为两个小矩阵相乘:
对应在推荐场景中,大矩阵表示用户对物品的评分,将大矩阵转化为用户矩阵和物品矩阵相乘,小矩阵的维度k解释为隐含的兴趣点,原本缺失的地方通过两个矩阵相乘也得到了取值,该取值就是预测的分数。
模型训练的目标是使输入输出矩阵误差最小,并且为了避免过拟合加入了正则项。应用显示信息和隐式信息的目标函数分别如下:
得到最优p、q的方法主要有梯度下降和交替最小二乘(ALS)两种,梯度下降是按照梯度的方向对p、q进行迭代,但消耗的计算资源较大,ALS是在每次迭代过程中,固定其中一个参数改变另一个参数,可实现并行运算,适用于矩阵较大、非常稀疏的场景。
3
pyspark实现
spark中有通过ALS实现矩阵分解的机器学习库,可直接调用。如下是官网上针对显示信息的示例代码,如要针对隐式信息进行预测,则在ALS函数中增加implicitPrefs=True参数即可。
代码语言:javascript复制from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.recommendation import ALS
from pyspark.sql import Row
lines = spark.read.text("data/mllib/als/sample_movielens_ratings.txt").rdd
parts = lines.map(lambda row: row.value.split("::"))
ratingsRDD = parts.map(lambda p: Row(userId=int(p[0]), movieId=int(p[1]),
rating=float(p[2]), timestamp=int(p[3])))
ratings = spark.createDataFrame(ratingsRDD)
(training, test) = ratings.randomSplit([0.8, 0.2])
# Build the recommendation model using ALS on the training data
# Note we set cold start strategy to 'drop' to ensure we don't get NaN evaluation metrics
als = ALS(maxIter=5, regParam=0.01, userCol="userId", itemCol="movieId", ratingCol="rating",
coldStartStrategy="drop")
model = als.fit(training)
# Evaluate the model by computing the RMSE on the test data
predictions = model.transform(test)
evaluator = RegressionEvaluator(metricName="rmse", labelCol="rating",
predictionCol="prediction")
rmse = evaluator.evaluate(predictions)
print("Root-mean-square error = " str(rmse))
# Generate top 10 movie recommendations for each user
userRecs = model.recommendForAllUsers(10)
# Generate top 10 user recommendations for each movie
movieRecs = model.recommendForAllItems(10)
# Generate top 10 movie recommendations for a specified set of users
users = ratings.select(als.getUserCol()).distinct().limit(3)
userSubsetRecs = model.recommendForUserSubset(users, 10)
# Generate top 10 user recommendations for a specified set of movies
movies = ratings.select(als.getItemCol()).distinct().limit(3)
movieSubSetRecs = model.recommendForItemSubset(movies, 10)
4
优缺点
矩阵分解将大矩阵转化为两个低维矩阵的乘积,解决了矩阵稀疏的问题,且原理简单易应用。但是运算速度一般,不适合实时计算场景,常用于离线计算,且解释性较差。
往期推荐:
XGBoost(二):R语言实现
R语言爬虫与文本分析
图片相似度识别:pHash算法