自1997年Resnick等人[1]首次提出用“推荐系统”(Recommender System, RS)一词代替“协同过滤”来描述推荐技术以来, 推荐系统实现了面向系统的探索阶段, 开始成为一个重要的研究领域[2]. 推荐系统按总体的功能划分, 可分为用户建模模块、推荐对象建模模块、推荐算法模块3个重要模块[3]. 目前许多研究专注于其中某个或某几个模块的优化设计上, 如文献[4,5]侧重于用户建模优化, 文献[6]侧重于对传统协同过滤推荐的算法优化等. 一个好的推荐系统在侧重功能实现的同时还需要关注其整体性能的优化, 如推荐算法计算时间过长时如何保证系统运行流畅, 如何提高系统的可伸缩性等. 此外, 各推荐方法自身还存在着缺陷, 比如典型的协调过滤推荐和新出现的基于网络结构的推荐都存在冷启动及稀疏性问题; 基于内容的推荐, 用户将仅限于获得跟以前类似的推荐结果, 很难为用户发现新的感兴趣的信息[3]. 推荐系统在采用这些推荐方法解决问题时, 如何扬长避短进行完善?
另外, 用户的偏好是一种理性和感性的共同选择[7], 用户除了具有固定兴趣偏好, 由于时间、事件、场合等原因, 也会在短时间内发生兴趣焦点转移, 如某一用户以前对财经类文章并不感兴趣, 但最近因为所在的公司要重组准备上市, 也开始关注这方面的新闻, 这就是兴趣焦点的转移. 如何迎合用户长期偏好的同时也能适应用户短时间内的兴趣变化?
本文设计了一种实时推荐与离线推荐相结合的推荐系统来解决上述问题, 提出了待推荐池的概念, 用于存储准备推荐给用户的数据, 用户获取数据直接从待推荐池内提取, 从而保证系统运行始终流畅; 系统通过分析用户实时数据进行实时推荐, 分析用户历史数据进行离线推荐, 二者结合可更好地贴近用户长期偏好及短期兴趣焦点; 此外, 系统采用控制模块, 通过设置该模块控制调节不同的推荐结果, 从而提高系统的可伸缩能力. 此外, 本文将该推荐系统应用于微信文章的推荐上, 实时推荐采用基于内容数据的推荐方式, 离线推荐采用基于用户行为数据的推荐方式, 文中介绍了具体实施方法, 并对推荐效果进行了分析和总结.
1 主要的推荐方法目前已有的推荐方法有很多, 根据不同的分类标准可以得到不同的分类结果. 文献[2]依据推荐方法使用的数据源不同, 将推荐方法分为: 基于内容数据的推荐、基于用户行为数据的推荐、基于社交网络数据的推荐等7种推荐方法. 其中基于内容数据的推荐与基于用户行为数据的推荐是最为常见的两种推荐方式.
基于内容数据的推荐(content-based recommendation)的基本思想是对一个给定的用户, 推荐与他之前喜欢的项目在内容上有相似性的其他项目. 而项目间相似度计算方法包括: 向量空间模型、改进的向量空间模型、显式决策模型、线性分类和机器学习等. 基于用户行为数据的推荐(user behavior-based recommendation)的基本思想是利用兴趣相投, 拥有共同经验的群体喜好来给使用者推荐可能感兴趣的项目[2]. 其最为广泛的计算方法是协同过滤, 包括基于用户的协同过滤、基于项目的协调过滤以及基于模型的协同过滤[3].
单一的推荐方法存在各自的优缺点, 如文献[2]指出基于内容数据的推荐不需要一个很大的用户社区或打分历史, 对单个用户就可以产生推荐列表, 但其推荐给用户的项目与该用户已经消费过的项目很相似, 这使得不易发现用户不熟悉但是潜在感兴趣的项目种类, 给用户造成的惊喜度不高; 基于用户行为数据的推荐不需要预先获得用户或项目的特征, 仅依赖于用户的历史行为给用户兴趣建模, 从而为用户进行推荐. 但其过于依赖于用户的历史行为, 这使得推荐方法无法满足用户短时间内的兴趣变化等.
对于上述基于内容数据的推荐和基于用户行为数据的推荐各自呈现的不足之处, 一些研究者采用混合推荐策略来达到扬长避短的目的. 混合推荐包括推荐结果的混合以及推荐算法的混合[3]. 前者各推荐方法独立运行, 只对推荐结果进行选择, 如文献[8]通过设定标准从各自推荐产生的结果中进行判断选择; 后者则是推荐方法间的嵌套使用, 如文献[9]在基于协同推荐的框架内混合基于网络结构的推荐等, 一般根据应用场景不同采取不同方式.
2 推荐系统设计 2.1 推荐系统设计思路针对前面提出的问题, 我们在推荐系统设计时着重考虑: ① 关注用户长期偏好以及短期兴趣焦点变化, ② 将推荐系统作为一个整体考虑系统运行的流畅性及可伸缩能力. 为此, 我们的设计思路为:
① 既然用户的实时反馈信息, 如阅读, 点赞, 评论等, 能反映用户短时间内的兴趣焦点, 而对这些反馈信息进行长期累积, 就能形成贴近用户长期偏好的历史数据. 我们可以基于实时反馈信息进行实时推荐, 基于历史数据进行离线推荐, 将二者结合, 就能在考虑用户长期固有偏好的同时也能关注用户短时间内的兴趣焦点变化.
② 系统运行不畅, 往往是由于推荐计算时间过长, 不能及时提供推荐结果导致. 本文提出待推荐池这一概念, 用于存储准备推荐给用户的数据集. 推荐时, 系统首先从待推荐池提取一定数量的数据推荐给用户, 再通过实时推荐与离线推荐产生推荐数据补充到待推荐池内, 这样即使推荐计算运行时间长, 用户依然能够连续多次从待推荐池中提取数据, 保证了系统运行始终流畅. 待推荐池中的数据, 除了在系统运行初期是按类别等比例随机获取的数据外, 后面补充到待推荐池中的数据都是实时推荐与离线推荐的结果. 因此, 长时间运行后, 池内数据会不断贴近用户的偏好, 这样通过分析池内数据, 也可对本系统推荐效果进行评价.
③ 为了提高系统健壮性与可伸缩能力, 在推荐系统中增加控制模块. 一方面, 按照实时推荐模块和离线推荐模块产生的推荐数量, 控制模块能够合理调节两者份额, 补充到待推荐池内, 提高系统的健壮性. 如当离线推荐数据少而实时推荐数据多时, 会适当增大实时推荐比例, 反之亦然. 另一方面, 当系统增加其它推荐算法时, 很容易通过对该模块进行设置, 来选择其它推荐算法的推荐结果, 提高了系统的可伸缩能力.
2.2 推荐系统运行流程本系统整体运行流程如图1所示, 具体步骤包括:
① 初始状态下, 将所要推荐的数据, 如书籍、文本、图片、电影、音乐等数据, 随机等比例地填充到待推荐池内, 保证池内数据全面多样;
② 每次推荐, 系统从待推荐池内获取定额数据推荐给用户, 如每次从池内提取10篇文章推荐给用户;
③ 记录模块记录用户对本次推荐的反馈, 如用户对其中某些数据的阅读, 收藏, 点赞, 评论等行为信息;
④ 用户获取下次推荐数据时, 实时推荐开始运行. 提取记录模块内的所有记录信息, 实时推荐模块根据这些信息计算并产生推荐数据;
⑤ 统计模块获取记录模块信息(提取后记录模块清空), 与前面获取的历史纪录合并, 离线推荐模块根据这些统计信息计算并产生推荐数据;
⑥ 控制模块监控待推荐池, 对实时推荐数据与离线推荐数据进行去重处理, 包括与用户的历史数据比较去重, 与待推荐池比较去重, 实时与离线推荐数据比较去重; 然后, 根据待推荐池内缺额数, 通过加权或计算TopN的方式, 组合两类推荐数据, 补充到待推荐池内.
2.3 待推荐池的运作机制待推荐池以队列形式存储, 池内最大容积固定, 每次推荐时提取池内排名在前的定额数据给用户. 控制模块根据池内缺额数, 结合实时推荐数据与离线推荐数据补充到待推荐池.
初始状态下, 推荐程序由于无用户历史数据和即时反馈数据, 无法进行实时推荐与离线推荐, 系统自动将各类数据等比例随机选取填充到待推荐池内, 一方面保证池内数据全面多样, 使用户在池内能够获得所有类型数据; 另一方面, 系统后续可从用户对各类数据的反馈中获取用户的兴趣焦点与偏好, 从而进行实时推荐与离线推荐.
推荐初期, 用户历史数据没达到一定规模, 实时推荐正常而离线推荐无法有效进行. 这时, 提取实时推荐数据中至多需补充数额量的数据, 将这些数据的80%插入到待推荐池队首, 其余20%数据插入到队尾, 保证下次推荐给用户的数据既能围绕用户当前的兴趣焦点, 又能让用户有机会接触到池内其它种类的数据, 此外也保证了待推荐池内的数据量.
随着用户历史数据不断积累, 离线推荐开始正常运行. 补充待推荐池时, 组合两类推荐数据至需补充数额量, 将其中实时推荐部分插入到队首, 使下次推荐的数据中包含大量实时推荐数据与原池内少量数据, 保证推荐给用户的数据大部分围绕用户的兴趣焦点上, 还有小部分是池内存储的用户之前可能感兴趣的数据; 将离线推荐数据部分插入到队尾, 逐渐改变待推荐池内数据类型, 使其逐渐贴合用户的历史偏好.
为保证系统流畅性, 用户每次获取数据时, 直接从待推荐池内提取, 然后控制模块选择调节两种推荐方法的结果数据进行数据补充. 当多次推荐用户无反馈, 即实时推荐模块不能正常产生推荐数据, 而同时用户的历史数据稀疏, 离线推荐模块也没有推荐数据时, 会出现待推荐池内数据不断减少的现象, 这时就需要设置预警阀值, 以避免待推荐池内数据量为空. 当池内数据小于预警阀值时, 系统需要及时补充数据, 所补充的数据可依据统计模块中已有的用户偏好信息产生, 若没有, 可按照初始数据填充方式, 将各类数据等比例随机选取, 产生一定量的数据进行补充.
3 推荐实验及结果分析 3.1 实验方案将上述推荐系统应用到微信文章推荐上. 微信文章是一种数量大、种类多的文章类型. 文章数据主要来源于微信精选网站(
(1)数据存储形式
采用MySQL数据库与Redis数据库存储文章数据. MySQL是一个开源的关系型数据库管理系统, 文章数据爬取后存在该数据库中; 而Redis是一个基于内存的, 存储形式为Key-Value的非关系型数据库(NoSql)[10], 推荐系统中的待推荐池及其他数据池均使用Redis数据库存储.
为实现微信文章推荐, 每个用户拥有六个数据池(如下表1所示), 各数据池的命名格式为“用户账号_数据池特性_存储类型”.
(2)推荐方式选择
本推荐过程中, 实时推荐采用基于内容数据的推荐方式, 根据用户近期阅读的文章, 将含有这些文章标签的文章推荐给用户, 从而聚焦在用户兴趣焦点上. 离线推荐采用基于用户行为数据的推荐方式, 将相似用户阅读过而本用户没有阅读过的文章推荐给用户, 拓展推荐数据的兴趣广度.
3.2 文章标签规范化处理文献[2]指出基于内容数据的推荐方式需要进行预处理获得其项目特性. 在来源网站上, 微信文章被设置多个标签来代表其特性, 标签数多为3个, 但存在无标签、少标签、多标签、标签不规范等问题, 为此, 需要对获取的文章进行预处理, 规范文章标签. 使用Python结巴分词结合TF-IDF统计方法实现.
文章标签设置标准如图2所示. 选取方法如下:
① 使用Python结巴分词, 提取3个标题关键词, 7个除标题关键词外的内容关键词, 两类关键词提取词数不足时, 以能取到的词数为准;
② 将所有文章的所有关键词进行统计计数形成一个关键词统计排名;
③ 针对每篇文章, 从标题关键词中提取TF-IDF最大的一个标题关键词, 同理从内容关键词中提取一词. 然后针对剩余的最多8个关键词, 对照关键词统计排名获得排名最高的一个高频词, 以这三个关键词作为文章标签.
分词过程中, 引用用户字典, 确保如“微信”“朋友圈”等网络词语能够被识别出来; 引用停用词词库, 避免分词结果出现常用而无意义的词语; 引用同义词词库(如菜鸟和新手同义), 使词语标准化; 引用包含词词库(如颜色包含白色、灰色等), 使标签更具代表性.
确定标签提取规则后, 我们对527篇具备标签的微信文章进行测试, 以提取的最多10个关键词是否包含标签词作为分词合格标准, 以最终提取的3个关键词是否包含标签词作为提取合格标准进行测试, 测试结果如图3所示. 分词合格率为91%, 提取合格率为87%, 基本满足需求.
然后对所有文章进行标签处理. 以3个优先(优先保留合格标签, 优先添加标题关键词, 优先保留标签与关键词的重叠词)为标准结合关键词统计排名进行设置, 如图4所示.
3.3 推荐方法 3.3.1 实时推荐
文章标签规范化处理后, 每篇文章固定存在3个标签代表文章特性. 实时推荐模块采用基于内容数据的推荐方式进行推荐, 具体流程如图5所示.
图5中文章流行度涉及到标签流行度[11]的概念, 标签流行度是指用户查看的所有文章中某标签出现的频率高低, 计算方法如式(1)所示
$popularit{y_{(u,{t_i})}} = \frac{{Fre{q_{(u,{t_i})}}}}{{\displaystyle\sum\nolimits_{{t_j} \in T(u)} {Fre{q_{(u,{t_j})}}} }}$ | (1) |
其中,
文章流行度是指用户对文章的偏好程度, 可以用文章标签流行度累加和表示, 如式(2)如下:
$Pr {e_{popu}}\left( {u,r} \right) = \sum\nolimits_{t \in T\left( r \right)} {popularit{y_{\left( {u,t} \right)}}}$ | (2) |
其中,
用户统计模块统计用户阅读的所有文章的id、类型以及标签, 离线推荐模块根据这些历史数据采用基于用户行为数据的推荐方式进行推荐, 具体推荐流程如图6所示.
(1)群组划分
用户统计模块中类型统计池对用户阅读的所有文章的类型进行统计, 即记录了用户阅读美文哲理、幽默笑话、趣味测试、经验总结、美食美景及保健养生6类文章的文章数. 将该数据记为一个代表用户阅读类型偏好的六维向量, 计算两用户间余弦相似度, 余弦值越接近1表示越相似, 越接近0表示越不相似. 计算方法如式(3)所示, 其中
${\rm{cos}}\theta = \frac{{\displaystyle\sum\nolimits_{i = 1}^{\rm{n}} {({x_i}*{y_i})} }}{{\sqrt {\displaystyle\sum\nolimits_{i = 1}^n {{{({x_i})}^2}} } *\sqrt {\displaystyle\sum\nolimits_{i = 1}^n {{{({y_i})}^2}} } }}$ | (3) |
在用户群体中随机抽取一名用户, 计算该用户与剩余所有用户的余弦相似度, 取阀值为0.8, 将余弦相似度大于等于0.8的用户以及该用户划分为一个群组从用户群体中剥离. 在余下的用户群体中再随机抽取一名用户, 如上述方法计算, 直至将用户群体完全划分.
(2)寻找相似用户
用户标签是指用户经常看的文章标签集合, 以该数据代表用户阅读主题偏好. 统计模块中标签统计池对用户阅读的所有文章的标签进行了统计, 利用这些数据可以计算用户标签, 具体方法为: 去除标签统计池内用户只阅读过一次的标签, 然后将剩余标签根据标签流行度(式(1))排序, 排名前80%的标签集合作为用户标签. 通过计算用户间标签重叠率, 重叠率越接近1越相似, 计算方法如式(4)所示, 其中
$overla{p_{(i,j)}} = \frac{{num(label{s_i} \cap label{s_j})}}{{num(label{s_i})}}$ | (4) |
群组划分后, 对于每个群组, 遍历群组成员, 计算该成员与其他成员的标签重叠率, 取阀值0.5, 重叠率大约等于0.5的成员即为该成员的最终相似用户.
(3)被分享池
将这些相似用户的已阅读池内的数据, 经过去重处理, 记录到本用户的被分享池内. 被分享池内的文章数据即为离线推荐数据.
3.3.3 整体推荐策略本推荐系统中实时推荐在每次用户获取数据时运行一次, 运行次数取决于用户的获取次数, 而离线推荐每天定时执行一次, 所产生的推荐数据存储在用户的被分享池内.
控制模块一方面对传递过来的实时/离线推荐数据进行去重处理, 包括与用户的历史数据比较去重, 与待推荐池内数据比较去重, 实时与离线推荐数据比较去重. 另一方面, 监控待推荐池内数据量变化, 以加权及具体场景具体分析的方式组合两类推荐数据补充待推荐池, 具体组合方式如表2所示. 当需要增添其他推荐方式时, 通过对该模块进行设置, 结合这些推荐算法的推荐结果, 从而提高了系统的可伸缩能力, 如图7所示.
3.4 结果分析本文设计的推荐系统, 其目的主要在于让推荐的数据能够贴合用户的偏好, 可以通过对待推荐池内数据进行分析, 考查本系统推荐效果.
以10 788篇微信文章进行推荐测试, 设置用户待推荐池容积为100, 每次推荐, 提取池内10篇文章数据给用户. 系统模拟100名用户, 每名用户进行了100次推荐操作, 为贴近实际情况, 保证模拟效果, 所模拟的用户一方面需要具有一定的兴趣偏好, 另一方面还能按照一定概率阅读不在该偏好内的其他文章. 因此, 对模拟用户做如下设置: ① 每名用户随机具有1~3个感兴趣的文章类型. ② 每次推荐, 用户会随机阅读1~3篇偏好类型的文章. ③ 每次推荐, 用户有20%的概率阅读1篇不在偏好类型之内的其他类型的文章. 推荐过程中, 前50次只进行实时推荐, 第50次以后加入离线推荐, 每进行25次推荐, 统计所有用户当前待推荐池内, 含有2个及以上用户标签的文章所占比例, 计算最大值、最小值、平均值、两平均值总和以及该总和的增长比例. 实验结果如表3所示.
含有2个及以上用户标签的文章可以认为是用户感兴趣的文章. 初始状态下, 待推荐池内含2个及以上用户标签的文章所占比例为0. 根据表3所示, 经过25次推荐, 占比约占22.97%, 之后每25次推荐, 达到44.39%, 50.75%, 53.48%, 分别增长了93.25%, 14.33%, 5.38%. 经过100次推荐后, 含用户标签的文章总计约占91.76%, 其中能够代表用户感兴趣的文章(含有2个及以上用户标签的文章)约占53.48%, 只含有1个用户标签的文章约占38.28%, 如表4所示. 从池内文章占比变化可以看出, 待推荐池内文章能够逐渐贴近用户偏好.
4 总结
本文设计了一种结合实时推荐与离线推荐的推荐系统, 能够保证系统运行流畅、具备可伸缩能力以及能够适应用户长期偏好及短期兴趣焦点变化. 基于该系统, 实现了对于微信文章的推荐实验, 采用易理解、可操作、效果可见的推荐方式, 在实验中, 推荐方式具备如下特点: ① 用户历史数据稀疏不影响推荐系统运行; ② 只采集了用户阅读行为, 无评分机制; ③ 系统具备可伸缩能力, 能够根据各推荐模块产生的推荐数据量, 调节两类推荐数据比例, 并且可以增添其他推荐方式; ④ 保证了推荐系统始终运行流畅. 此外, 对于推荐系统评价方面, 本系统通过对待推荐池内数据分析来对本系统推荐效果进行评价, 实验表明待推荐池内数据能够逐步贴近用户兴趣偏好.
[1] |
Resnick P, Varian HR. Recommender systems. Communications of the ACM, 1997, 40(3): 56-58. DOI:10.1145/245108.245121 |
[2] |
朱扬勇, 孙婧. 推荐系统研究进展. 计算机科学与探索, 2015, 9(5): 513-525. DOI:10.3778/j.issn.1673-9418.1412023 |
[3] |
王国霞, 刘贺平. 个性化推荐系统综述. 计算机工程与应用, 2012, 48(7): 66-76. DOI:10.3778/j.issn.1002-8331.2012.07.018 |
[4] |
李嫒嫒. 存在社会影响的群体推荐用户建模研究[硕士学位论文]. 天津: 天津大学, 2014.
|
[5] |
赵鹏, 蔡庆生, 王清毅. 一种用于文章推荐系统中的用户模型表示方法. 计算机技术与发展, 2007, 17(1): 4-5, 48. DOI:10.3969/j.issn.1673-629X.2007.01.002 |
[6] |
雷曼, 龚琴, 王纪超, 等. 基于标签权重的协同过滤推荐算法. 计算机应用, 2019, 39(3): 634-638. DOI:10.11772/j.issn.1001-9081.2018071521 |
[7] |
尹祎, 冯丹, 施展. 一种基于效用的个性化文章推荐方法. 计算机学报, 2017, 40(12): 2797-2811. DOI:10.11897/SP.J.1016.2017.02797 |
[8] |
Pazzani MJ. A framework for collaborative, content-based and demographic filtering. Artificial Intelligence Review, 1999, 13(5–6): 393-408. DOI:10.1023/a:1006544522159 |
[9] |
Zhang YC, Blattner M, Yu YK. Heat conduction process on community networks as a recommendation model. Physical Review Letters, 2007, 99(15): 154301. DOI:10.1103/PhysRevLett.99.154301 |
[10] |
李挺. 基于iOS平台科技新闻推荐系统的设计与实现[硕士学位论文]. 大连: 大连理工大学, 2015.
|
[11] |
张鹏飞, 王宜贵, 张志军. 融合标签和多元信息的个性化推荐算法研究. 计算机工程与应用, 2019, 55(5): 159-165. DOI:10.3778/j.issn.1002-8331.1711-0330 |