如何构建一个真实的推荐系统?

栏目: 数据库 · 发布时间: 7年前

内容简介:AI 前线导读:随着互联网行业的井喷式发展,数据规模呈现爆炸式增长。大数据中蕴含了巨大的价值,但同时也来了很 “信息过载” 的问题。推荐系统作为一个广泛应用的信息过滤系统,在很多领域取得了巨大的成功。在电子商务上(Amazon,eBay,阿里巴巴),推荐系统为用户提供个性化产品,发掘用户潜在需求。那些电商的 “猜你喜欢” 其实就是推荐系统的应用。简单的说,推荐系统的目标是根据用户的偏好,为其找到并推荐可能感兴趣的项目。当今机器学习中最有价值的应用之一就是推荐系统。Amazon 将其 35% 的收入归功于其推

AI 前线导读:随着互联网行业的井喷式发展,数据规模呈现爆炸式增长。大数据中蕴含了巨大的价值,但同时也来了很 “信息过载” 的问题。推荐系统作为一个广泛应用的信息过滤系统,在很多领域取得了巨大的成功。在电子商务上(Amazon,eBay,阿里巴巴),推荐系统为用户提供个性化产品,发掘用户潜在需求。那些电商的 “猜你喜欢” 其实就是推荐系统的应用。简单的说,推荐系统的目标是根据用户的偏好,为其找到并推荐可能感兴趣的项目。

当今机器学习中最有价值的应用之一就是推荐系统。Amazon 将其 35% 的收入归功于其推荐系统。

译注:关于 35% 这一数据详见《The Amazon Recommendations Secret to Selling More Online》( http://rejoiner.com/resources/amazon-recommendations-secret-selling-online/)

评估是研究和开发任何推荐系统的重要组成部分。根据你的业务和可用数据,有很多方法可以评估推荐系统。在本文中,我们会尝试一些评估方法。

评级预测

在我上一篇文章中《Building and Testing Recommender Systems With Surprise, Step-By-Step 》( https://towardsdatascience.com/building-and-testing-recommender-systems-with-surprise-step-by-step-d4ba702ef80b ):使用 Surprise 构建和测试推荐系统,Surprise 以各种机器学习算法为中心来预测用户对商品条目的评级(即评级预测)。它要求用户提供明确的反馈,比如让用户在购买图书后对其进行 0~10 星的评级。然后我们用这些数据来建立用户兴趣的档案。问题是,不是每个人都愿意留下评级,因此数据往往是稀疏的,就像我们之前看到的 Book-Crossing 数据集一样:

如何构建一个真实的推荐系统?

译注:Book-Crossing 数据集可见 http://www2.informatik.uni-freiburg.de/~cziegler/BX/

大多数推荐系统是这样试图预测的:如果用户对相应的图书进行评级的话,他们会在里面放入什么内容。如果 “NaN” 太多,那么推荐系统就没有足够的数据来理解用户究竟喜欢什么。

但是,如果你能说服用户给你评级,那么明确的评级是很好的。因此,如果你拥有大量的数据和用户评级,那么评估指标应该为 RMSEMAE 。让我们展示一个带有 Surprise 库的 Movielens 数据集示例。

复制代码

movies = pd.read_csv('movielens_data/movies.csv')
ratings = pd.read_csv('movielens_data/ratings.csv')
df = pd.merge(movies, ratings, on='movieId', how='inner')
reader =Reader(rating_scale=(0.5, 5))
data =Dataset.load_from_df(df[['userId', 'title', 'rating']],reader)
trainSet, testSet = train_test_split(data,test_size=.25,random_state=0)
algo =SVD(random_state=0)
algo.fit(trainSet)
predictions = algo.test(testSet)

defMAE(predictions):
return accuracy.mae(predictions, verbose=False)
defRMSE(predictions):
return accuracy.rmse(predictions, verbose=False)

print("RMSE: ",RMSE(predictions))
print("MAE: ",MAE(predictions))
ratings_prediction.py

如何构建一个真实的推荐系统?

Top-N

从网上购物网站到视频门户网站,Top-N 推荐系统的身影无处不在。它们为用户提供他们可能感兴趣的 N 个项目的排名列表,以鼓励用户浏览、下单购买。

译注:Top-N 推荐系统的介绍可观看 YouTube 视频: https://www.youtube.com/watch?v=EeXBdQYs0CQ

Amazon 的推荐系统之一就是 “Top-N” 系统,它可以为个人提供顶级结果列表:

如何构建一个真实的推荐系统?

Amazon 的 “Top-N” 推荐包括 9 页,第一页有 6 项。一个好的推荐系统应该能够识别某个用户感兴趣的一组 N 个条目。因为我很少在 Amazon 上买书,因此我的 “Top-N” 就差得很远。换言之,我可能只会点击或阅读我的 “Top-N” 列表中的某本书。

下面的脚本为测试集中的每个用户生成了前 10 条推荐。

复制代码

def GetTopN(predictions,n=10,minimumRating=4.0):
topN = defaultdict(list)
foruserID, movieID, actualRating, estimatedRating, _inpredictions:
if(estimatedRating >= minimumRating):
topN[int(userID)].append((int(movieID), estimatedRating))

foruserID, ratingsintopN.items():
ratings.sort(key=lambda x: x[1],reverse=True)
topN[int(userID)] = ratings[:n]

return topN

LOOCV = LeaveOneOut(n_splits=1,random_state=1)

fortrainSet, testSetinLOOCV.split(data):
# Train model without left-out ratings
algo.fit(trainSet)
# Predicts ratingsforleft-out ratings only
leftOutPredictions = algo.test(testSet)
# Build predictionsforall ratingsnotinthe trainingset
bigTestSet = trainSet.build_anti_testset()
allPredictions = algo.test(bigTestSet)
# Compute top 10 recsforeachuser
topNPredicted = GetTopN(allPredictions,n=10)
top-N.py

下面是我们预测的 userId 2 和 userId 3 的前 10 项。

如何构建一个真实的推荐系统?

命中率

让我们看看生成的前 10 项推荐究竟有多好。为评估前 10 项,我们使用命中率这一指标,也就是说,如果用户对我们推荐的前 10 项中的一个进行了评级,那么我们就认为这是一个 “命中”。

计算单个用户命中率的过程如下:

  • 在训练数据中查找此用户历史记录中的所有项。

  • 有意删除其中一项条目(使用留一法,一种交叉验证方法)。

  • 使用所有其他项目为推荐系统提供信息,并要求提供前 10 项推荐。

  • 如果删除的条目出现在前 10 项推荐中,那么它就是命中的。如果没有,那就不算命中。

复制代码

def HitRate(topNPredicted, leftOutPredictions):
hits =0
total =0

# For each left-outrating
forleftOutinleftOutPredictions:
userID = leftOut[0]
leftOutMovieID = leftOut[1]
# Is itinthe predicted top10forthisuser?
hit = False
formovieID, predictedRatingintopNPredicted[int(userID)]:
if(int(leftOutMovieID) ==int(movieID)):
hit = True
break
if(hit) :
hits +=1

total +=1

# Compute overall precision
returnhits/total
print("\nHit Rate: ", HitRate(topNPredicted, leftOutPredictions))
HitRate.py

如何构建一个真实的推荐系统?

系统的总命中率是命中数除以测试用户数。它衡量的是我们推荐删除评级的频率,越高越好。

如果命中率非常低的话,这只是意味着我们没有足够的数据可供使用。就像 Amazon 对我来说,命中率就非常低,因为它没有足够的我购买图书的数据。

基于评级值的命中率

我们还可以通过预测的评级值来细分命中率。在理想情况下,我们希望预测用户喜欢的电影,因此我们关心的是高评级值而不是低评级值。

复制代码

defRatingHitRate(topNPredicted, leftOutPredictions):
hits = defaultdict(float)
total = defaultdict(float)
# For each left-out rating
foruserID, leftOutMovieID, actualRating, estimatedRating, _inleftOutPredictions:
# Is it in the predicted top N for this user?
hit =False
formovieID, predictedRatingintopNPredicted[int(userID)]:
if(int(leftOutMovieID) == movieID):
hit =True
break
if(hit) :
hits[actualRating] +=1
total[actualRating] +=1

# Compute overall precision
forratinginsorted(hits.keys()):
print(rating, hits[rating] / total[rating])
print("Hit Rate by Rating value: ")
RatingHitRate(topNPredicted, leftOutPredictions)
RatingHitRate.py

如何构建一个真实的推荐系统?

我们的命中率细分正是我们所期望的,评级值为 5 的命中率远高于 4 或 3。越高越好。

累积命中率

因为我们关心更高的评级,我们可以忽略低于 4 的预测评级,来计算 > = 4 的评级命中率。

复制代码

def CumulativeHitRate(topNPredicted, leftOutPredictions,ratingCutoff=0):
hits = 0
total = 0
#Foreach left-out rating
foruserID, leftOutMovieID, actualRating, estimatedRating, _inleftOutPredictions:
# Only look at abilitytorecommend things theusersactually liked...
if(actualRating >= ratingCutoff):
# Is itinthe predicted top 10forthis user?
hit =False
formovieID, predictedRatingintopNPredicted[int(userID)]:
if(int(leftOutMovieID) == movieID):
hit =True
break
if(hit) :
hits += 1
total += 1

# Compute overall precision
return hits/total
print("Cumulative Hit Rate (rating >= 4): ", CumulativeHitRate(topNPredicted, leftOutPredictions, 4.0))
CumulativeHitRate.py

如何构建一个真实的推荐系统?

越高越好。

平均对等命中排名(Average Reciprocal Hit Ranking,ARHR)

常用于 Top-N 推荐系统排名评估的指标,只考虑第一个相关结果出现的地方。我们在推荐用户排名靠前而不是靠后的产品获得了更多的好评。越高越好。

复制代码

def AverageReciprocalHitRank(topNPredicted, leftOutPredictions):
summation =0
total =0
# For each left-outrating
foruserID, leftOutMovieID, actualRating, estimatedRating, _inleftOutPredictions:
# Is itinthe predicted top Nforthisuser?
hitRank =0
rank =0
formovieID, predictedRatingintopNPredicted[int(userID)]:
rank = rank +1
if(int(leftOutMovieID) == movieID):
hitRank = rank
break
if(hitRank >0) :
summation +=1.0/ hitRank

total +=1

returnsummation / total

print("Average Reciprocal Hit Rank: ", AverageReciprocalHitRank(topNPredicted, leftOutPredictions))
view rawAverageReciprocalHitRank.py hosted with ❤ by GitHub
AverageReciprocalHitRank.py

如何构建一个真实的推荐系统?

你的第一个真实推荐系统可能质量很低,哪怕是成熟系统,用于新用户的表现也是一样。但是,这仍然比没有推荐系统要好多得多。推荐系统的目的之一,就是在推荐系统中了解用户 / 新用户的偏好,这样他们就可以开始从系统中接收准确的个性化推荐。

然而,如果你刚刚起步的话,那么你的网站就是全新的,这时候推荐系统并不能为任何人提供个性化的推荐,因为这时候并没有任何人的评价。然后,这就变成了一个系统引导问题。

译注:有关系统引导问题可参阅:《Learning Preferences of New Users in RecommenderSystems: An Information Theoretic Approach》( https://www.kdd.org/exploration_files/WebKDD08-Al-Rashid.pdf)

本文的 Jupyter Notebook 可以在 Github 上找到: https://github.com/susanli2016/Machine-Learning-with-Python/blob/master/Movielens Recommender Metrics.ipynb。

参考文献:Building Recommender Systems with Machine Learning and AI(《使用机器学习和人工智能构建推荐系统》 https://learning.oreilly.com/videos/building-recommender-systems/9781789803273

原文链接: https://towardsdatascience.com/evaluating-a-real-life-recommender-system-error-based-and-ranking-based-84708e3285b


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Structures and Algorithms with JavaScript

Data Structures and Algorithms with JavaScript

Michael McMillan / O'Reilly Media / 2014-2-22 / USD 28.51

If you’re using JavaScript on the server-side, you need to implement classic data structures that conventional object-oriented programs (such as C# and Java) provide. This practical book shows you how......一起来看看 《Data Structures and Algorithms with JavaScript》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换