,
(1.济南职业学院,山东 济南 250014;2.山东广播电视大学,山东 济南 250014)
随着网络的飞速发展,网络信息飞速增长,人们面临着“信息过载”和“信息迷航”的问题。借助于搜索引擎,人们可以从海量信息中查找到自己所需的信息。但是,搜索引擎只适用于在有明确需求的情况下帮人们查找信息,如果在没有明确需求的情况下,搜索引擎则难以帮助人们有效地筛选信息。此时推荐技术应运而生,它通过研究用户的兴趣偏好,自动建立起用户和信息之间的联系,从而帮助用户从海量信息中去发掘自己潜在的需求。
推荐系统是建立在海量数据挖掘基础上的,它通过分析用户的历史数据来了解用户的需求和兴趣,从而将用户感兴趣的信息、物品等主动推荐给用户,其本质是建立用户与物品之间的联系。常用的推荐算法主要有专家推荐、基于统计的推荐、基于内容的推荐和协同过滤推荐等。其中协同过滤推荐是推荐系统中应用最早和最为成功的算法。
协同过滤算法的关键是计算相似度及求解推荐评分,在计算时需要用到矩阵的一些运算。Python的第三方扩展库Numpy是一科学计算库,提供了大量的数组及矩阵运算,因此很多推荐系统中都是利用Numpy来实现协同过滤算法,但因协同过滤算法中涉及到的矩阵多是稀疏矩阵,采用普通的二维数组存放存在大量的无效存储,空间利用率较低,同时利用Numpy扩展库也无法进行算法的优化,因此本文利用Python的内置序列字典来存放稀疏矩阵,自行编制相应的代码来求解推荐评分,可有效提高算法的时间空间效率。
协同过滤算法分为基于用户的协同过滤算法和基于物品的协同过滤算法。
基于用户的协同过滤算法(简称UserCF),通过不同用户对物品的评分来评测用户之间的相似性,基于用户之间的相似性做出推荐。简单说就是给用户推荐和他兴趣相似的其他用户喜欢的物品。
基于物品的协同过滤算法(简称ItemCF),通过用户对不同物品的评分来评测物品之间的相似性,基于物品之间的相似性做出推荐。简单说就是给用户推荐和他之前喜欢的物品相似的物品。
UserCF算法和ItemCF算法最主要的区别在于:UserCF推荐的是那些和目标用户有共同兴趣爱好的其他用户所喜欢的物品,ItemCF算法则推荐那些和目标用户之前喜欢的物品类似的其他物品。因此,UserCF算法的推荐更偏向社会化,适合应用于新闻推荐、微博话题推荐等应用场景;而ItemCF算法的推荐则是更偏向于个性化,适合应用于电子商务、电影、图书等应用场景。
UserCF算法和ItemCF算法思想类似,其实现过程也基本类似,唯一不同的是一个是计算用户相似度,一个是计算物品相似度,本文以ItemCF算法为例详细说明其具体实现。
以一组用户的观影记录作为测试数据集,共包括两个数据文件,一个是rating.txt,存放的是用户对电影的评分记录,其数据如图1所示,每一行用逗号分隔的3个数据项分别表示用户ID、电影ID和评分。
图1 评分数据
另一个数据文件是movies.txt,存放的是电影信息,其数据如图2所示,每一行用逗号分隔的3个数据项分别表示电影ID、电影名称和上映时间,该数据文件主要用于推荐结果输出。
图2 电影信息数据
1.数据预处理
将数据集中的文件读入并进行一定的处理,将用户评分记录及电影信息分别存入相应的字典中。其Python代码如图3所示。
图3 数据预处理代码
2.建立同现矩阵
ItemCF算法的关键是计算物品(此处为电影)的相似度,相似度的计算方法有很多,在此直接以同时出现的次数多少作为相似度的衡量,因此需要建立物品的同现矩阵M。
建立过程如下:
step1:列出每个用户看过的电影列表,结果如图4所示。
图4 用户看过的电影列表
step2:求出每个用户的电影同现矩阵
例对用户1,其看过的电影有11、12、13,因此在矩阵对应的位置(11,12)(12,11)(11,13)(13,11)(12,13)(13,12)处写上1,其余为0。也即用户1的同现矩阵如图5所示。
图5 用户1的同现矩阵
step3:将所有用户的同现矩阵相加,得到最终的同现矩阵,如图6所示。
图6 所有用户的同现矩阵
利用Python来实现同现矩阵的建立,其代码如图7所示。
图7 求解电影同现矩阵
3.计算推荐评分
计算每个用户曾看过的电影的推荐评分。推荐评分=同现矩阵M*评分向量R。
评分向量即用户对所有物品(电影)的评分,由评分记录表可得出。
由前面计算出的同现矩阵和用户1的评分向量可得出用户1对电影104的推荐评分为:
U1:14=4.5*3+3.5*1=17
具体求解方法如图8所示。
用户ID电影ID1用户评分电影ID2电影ID1与电影ID2的关联权重得分=用户评分∗电影ID1与电影ID2的关联权重1114.51434.5∗3=13.51123.51413.5∗1=3.511331400114014001150141011601430总分=13.5+3.5=17
图8推荐评分求解过程
同样方法可求得每个用户对未曾看过的电影的推荐评分,其结果如图9所示。图中阴影部分为每个用户未曾看过的电影中推荐评分最高的,也是要推荐的结果。
然后将推荐得分从高到低排序,实际应用中通常采用Top-N推荐,即为目标用户提供一个长度为N的推荐列表,使该推荐列表能够尽量满足用户的兴趣和需求。利用Python来计算推荐评分的代码如图10所示。
图9 所有用户对未曾观看的电影的推荐得分
图10 求解推荐评分
4.输出推荐结果
求得推荐评分的前N项后就可将结果输出给用户。输出推荐结果时,有时可能需要为某个指定用户来输出推荐结果,也可能需要为所有用户都输出推荐结果,为使程序更加灵活,可编制两个不同的函数来满足其需求。为一个指定用户输出推荐结果的Python代码如图11所示。
图11 输出推荐结果
例如要为用户1推荐两部电影可直接调用主函数:main_one(“rates.txt”,“movies.txt”,“1”,2),程序运行结果如图12所示,与前面手工计算得出的结果相同。
图12 用户1的推荐结果
若想为每个用户都输出其推荐结果,其相应的主函数代码如图13所示。
图13 为每个用户推荐结果
如要为每个用户推荐1部电影,则可直接调用主函数:main_all(“rates.txt”,“movies.txt”,1),运行结果如图14所示。
图14 所有用户的推荐结果
其输出结果与前面手工求解的结果完全相同。
前面给出的测试数据集数据很少,主要应用于系统开发测试中。实际应用中推荐系统所用的数据集通常为海量数据,为验证系统在海量数据中的使用,可以MovieLens(http://grouplens.org/datasets/movielens)作为电影推荐系统中的实验数据来测试系统。MovieLens是GroupLens Research实验室的一个非商业性质、以研究为目的的实验性项目,采集了一组从20世纪90年代末到21世纪初的电影评分数据,包含大小不同的数据集,每个数据集中包括电影信息数据及电影评分记录等。如MovieLens 1M数据集中存放了1000多名用户对近2000部电影的评分记录,每个用户至少对20部电影进行过评分,一共有100000多条电影评分记录。当数据量增大时,存储同现矩阵所需要的空间也相应增加,通过前述也可以看出同现矩阵是一稀疏矩阵,因此采用字典来存储同现矩阵中的非零元素要比直接存储整个同现矩阵节省空间。又因字典是Python的内置对象,而numpy是第三方扩展库,需要安装和导入相应的模块,因此同一算法采用内置对象比用扩展库会获得更优的时间性能和空间性能。
本文利用Python实现的协同过滤算法框架清晰,代码简洁,同时因其用Python的内置序列字典代替二维数组来存放稀疏矩阵,有效提高了算法的时间空间效率。