整体概述
介绍完所有的单个推荐系统算法后,我们迎来将他们整合到一起的日子。首先这个整合代码整体并不难就是将每一个推荐算法训练完加入评估器的算法池中,再对其进行评估。
接下来我们来看看这个文件中我们需要导入的第三方包:
from MovieLens import MovieLens # 自己写的数据处理类
from surprise import SVD, SVDpp # surprise库的SVD,SVD++算法
from Evaluator import Evaluator # 自己实现的推荐效果评估器
from ContentBasedAlgorithm import ContentBasedAlgorithm # 基于内容计算相似度的模块
from surprise import KNNBasic # surprise自带的KNNBasic算法
import numpy as np
import random
from time import time
from surprise import NormalPredictor # surprise库自带的随机推荐算法
from HybridAlgorithm import HybridAlgorithm # 自己实现的融合算法
from surprise.model_selection import GridSearchCV # 寻找最佳参数算法,参考sklearn中的同名函数
import random
import numpy as np
这些要用到的第三方库大部分是surprise库中的自带算法,还有一些自己写的一些评估类,融合算法类等等。
步骤解析
1、导入训练数据
导入数据利用到了LoadMovieLensData()函数,其代码如下:
def LoadMovieLensData():
ml = MovieLens()
print('Loading movie ratings..')
data = ml.loadMovieLensDataset()
#Compute movie popularity ranks to measure novelty
rankings = ml.getPopularityRanks()
return (ml,data,rankings)
(ml, evaluationData, rankings) = LoadMovieLensData()
这个函数的代码主要利用到了MoviesLens类,这个类为了让原始数据符合surprise的数据格式,对数据做了一定的处理和调整。详情可以点击MoviesLens。最后将该函数得返回值赋值给对应变量。
2、设置相同的随机数
np.random.seed(0)
random.seed(0)
在多个算法构建的python文件中都发现了相同的两个随机语句,一开始我是很费解为什么要有这两句话,因为在当前文件中并没有使用到随机数。但是直到我看到了评估数据划分文件EvaluationData中有这样的一行代码:
self.trainset, self.testset = train_test_split(data, test_size=0.25, random_state=1)
由代码可见,在划分评估数据时,我们使用了random_state这个参数。对这个参数有如下解释:
这里的random_state就是为了保证程序每次运行都分割一样的训练集和测试集。否则,同样的算法模型在不同的训练集和测试集上的效果不一样。
所以这就很好的解释了这两行代码的必要性,使得代码的复现率更高。
3、构建评估器
我们将整理好的用户对电影评分数据和电影热门排序数据放入Evaluator类中,初始化一个评估器,以评估推荐算法的性能。代码如下:
evaluator = Evaluator(evaluationData, rankings)
4、构建基于内容相似度推荐模型
接下来,就进行整个推荐系统中最核心的部分了,构建各个推荐算法。首先第一个就是基于用户电影内容相似度推荐的算法了。这部分算法主要是基于用户观看电影的类型和年份计算相似度从而从中选取相似度高的进行推荐。详细代码解析可以点击ContentBasedAlgorithm
在训练完模型后,要将这个模型放入评估函数的待评估池中等待所有模型构建完毕后进行评估。代码如下:
ContentKNN = ContentBasedAlgorithm()
evaluator.AddAlgorithm(ContentKNN, "ContentBased")
5、构建KNNBasic算法分别基于用户和电影进行推荐
首先,构建基于用户相似度数据的KNNBasic算法,然后将它加入待评估算法池。然后构建基于电影相似度数据的KNNBasic算法,然后将它加入待评估算法池。这两个算法的区别体现在一个是对用户相似度的计算一个是对电影相似度的计算。二者代码的区别,因为时调用surprise库中有的KNNBasic,所以只是一个参数的区别。具体代码如下:
# 基于用户
sim_options_user = {'name': 'cosine', 'user_based': True}
userKNN = KNNBasic(sim_options=sim_options_user)
evaluator.AddAlgorithm(userKNN, "UserBased")
# 基于电影
sim_options_item = {'name': 'cosine', 'user_based': False}
itemKNN = KNNBasic(sim_options=sim_options_item)
evaluator.AddAlgorithm(itemKNN, "ItemBased")
6、构建SVD和SVD++算法
这一步相对其他的比较简单,因为使用的都是默认参数下的SVD和SVD++,因为这两个算法都是surprise自带的库,所以只是将他们调用,再将其放入评估器中。代码如下:
# SVD
SVD = SVD()
evaluator.AddAlgorithm(SVD, "SVD")
# SVD++
SVDPlusPlus = SVDpp()
evaluator.AddAlgorithm(SVDPlusPlus, "SVD++")
7、构建随机分布推荐和基于内容推荐算法的融合模型
构建模型的最后一步,使用到了surprise库中最基础的基于数据分布进行推荐的算法NormalPredictor和之前构建完成的基于内容推荐算法ContentKNN。还使用到了自己写的模型融合算法HybridAlgorithm,将两个算法进行等比例融合。详情可以点击HybridAlgorithm.
Random = NormalPredictor()
Hybrid = HybridAlgorithm([Random, ContentKNN], [0.5, 0.5])
evaluator.AddAlgorithm(Hybrid, 'Hybrid')
8、评估器评估并作出推荐
接下来就是最关键的部分,根据每个构建完的算法对测试用户0进行推荐电影,其中用到的代码如下:
evaluator.Evaluate(True)
evaluator.SampleTopNRecs(ml)
最核心的部分是SampleTopNRecs函数,因为运用到的库比较多所以可以结合其他python文件一起看,下面是我对该函数的详细注释:
def SampleTopNRecs(self, ml, testSubject=0, k=10): # 传入数据参数、测试用户Id、默认推荐电影数量10
for algo in self.algorithms: # 分别用算法池中的算法推荐
print("\nUsing ", algo.GetName()) # 显示正在使用的算法
trainSet = self.dataset.GetFullTrainSet() # 获取训练数据的特征矩阵
algo.GetAlgorithm().fit(trainSet) # 对训练数据进行训练
print("Computing Recommendations") # 开始计算推荐电影
testSet = self.dataset.GetAntiTestSetForUser(testSubject) # 使用训练集之外的用户评分测试,缺少的评分使用了平均填充。
predictions = algo.GetAlgorithm().test(testSet) # 对构建完成的测试集数据进行预测
recommendations = [] # 推荐的电影信息
print("\nFor user ", testSubject, " we recommend:")
# 将电影信息添加到列表中,并以推荐指标升序排列
for userID, movieID, actualRating, estimatedRating, _ in predictions:
intMovieID = int(movieID)
recommendations.append((intMovieID, estimatedRating))
recommendations.sort(key=lambda x: x[1], reverse=True)
number = 0
# 打印前十五个被推荐的电影名字、评分
for ratings in recommendations[:15]:
number += 1
print(number, " - ", ml.getMovieName(ratings[0]), round(ratings[1], 1))
总结
这个项目涉及到的python文件和第三方库算法较多,单个查看某个算法较难理解,必须结合多个算法文件一起查看效果更佳.项目大致流程:数据预处理导入—>多个模型构建—>评估器评估并预测—>输出推荐电影信息.