我是如何为技术博客设计一个推荐系统(上):统计与评分加权

2017 年 8 月 29 日 phodal Phodal

过去的两周里,我一直忙于为 『玩点什么』 设计一个推荐系统。在这个过程中,参考几本书籍,查找了一系列的资料。想着这些资料上,大部分都是大同小异的,实现了几个简单的推荐功能,改进了标签推荐算法,便想着写篇文章记录一下。

『玩点什么』,是一个基于 Django、Python 的 CMS 系统(Mezzanine)。是的,和我的博客使用的是同一个 CMS 系统。由于使用的是 Python 语言,因此对于机器学习具有天生的优势。

推荐系统

推荐系统是一种信息过滤系统,用于预测用户对物品的“评分”或“偏好”。

对于推荐系统系统来说,目前采用的主要方式是:

  • 基于内容推荐:内容之间的相似度,如文章的标签、电影的属性、书籍的分类。

  • 协同过滤(待实现):用户之间的相似度,如喜欢看科幻片的 A、B 用户、并且都看过 a 电影,A 喜欢看的 c 电影,B 也可能喜欢 c 电影。

要实现这两种方式有一个前提是,用户数据。特别是协同过滤,需要有大量的用户行为数据。对于一些大的社交应用、有大量的用户,如微信来说,还会有:

  • 基于社区推荐,如,你的好友喜欢什么,就会为你推荐王者荣耀。

  • 基于人口统计学,即我们网上看到的各种区域性人的偏好,各种地域黑~。

上面主要是依赖于大量的用户数量,当我们没有大量的用户数据时。我们可以先采用其它的方式:

  • 基于统计学推荐,诸如文章的阅读量、分享量,又或者文章的评分数。

  • 基于标签推荐,对于专业领域的文章来说,作者提交的标签往往比机器生成更加可靠。

除此,按我的理解,对于专业领域来说,还会有一种方式是:

  • 基于知识图谱推荐,如我之前做的技能树和 Growth,便是其中的一种方式。

这种成知识体系的文章,往往对于用户来说,更具备价值。

收集用户数据(一):统计

那么,现在先让我们从收集用户数据谈起。

因为不论是哪一种推荐方式,其都依赖于应用服务提供者所拥有的数据数据数据。没有数据,你所谈的算法都是在耍流氓,你所学的机器学习、深度学习算法也是在而流氓,只谈算法不谈收集数据都是在耍流氓。他们的学习成本都很低,几星期几个月,差不多能学好七八十。可是要是没有 ImageNet 的图片数据、CNN 的上亿条新闻数据,这一些算法都没有价值。

而如我在《全栈应用开发:精益实践》所写,数据分析应该在我们上线了第一个 DEMO 之后,或第一个正式版就必须上线的功能,以实现产品的精益化。

精益环路


它只是数据分析的第一步,引入一些数据分析的工具——只需要引入 Google Analytics、又或者 Piwik 这样的工具,就可以轻松地帮我们做数据统计。这些功夫,基本上只需要半天就做完了。这时,当我们谈及收集用户数据的时候:

  • 对于技术人员来说,无非就是用户的地域、浏览器、操作系统等等,这些相关的信息会影响到用户的体验、技术决策等等。

  • 对于业务人员来说,他们可以了解某个产品的浏览量、受欢迎程度、爱欢迎的区域等等。

只是这些数据,并不能帮我们做出一个优秀的推荐系统。这时,我们是基于统计学,只能统计出哪些产品受用户欢迎:


事件追踪

但是,这已经可以实现我们的第一个推荐系统。

(PS:另外一部分用户数据收集,见下篇)

基于统计学:访问量及评论数推荐

我过去一直觉得,依据统计博客、文章的访问量来推荐是不可靠的。

  • 一篇文章可能因为观点受争议,如 『PHP 不再是最好的语言』,而着有极高的访问量。可这个时候,用户往往是通过标题和摘要来理解作者的观点,往往就会轻易地下定论。又有一些用户,比如我则喜欢看热闹,去下面回复一个『JavaScript 是最流行的语言』。

  • 一篇文章可能因为大 V 的流量效应,而导致 他/她/也 的每一篇文章都有极高的访问量

  • 。。。

并且使用流量统计也容易被攻击,只需要一些诸如『流量精灵』这样的软件,就可以提高文章的访问——虚假的繁荣。

一般来说,大部分的社区都会将流量大的内容、话题等,放在首页显眼的位置。从这个推荐的位置,我们就可以知道这个社区的『水平』。衡量一个社区的『水平』,无非就是最受欢迎文章的类型,如简书的鸡汤,知乎的故事。但是,这些并不代表着这些社区的真实水平,却反应了这些社区的主要受众。


简书示例

好在简书是编辑推荐制,但章的质量还是『有一定』保证的,但是文章的性质改不了鸡汤。

考虑到我过去曾经刷过访问量,以及流量统计对于数据库性能的影响,我决定改进一下统计代码,即将统计代码放在 JavaScript 中,通过 Ajax 请求实现。而我在这个过程中,犯了一个严重的错误就是,忘了在前端屏蔽中的爬虫。我虽然在 Nginx 里,直接过滤了一部分的爬虫,但是诸如 Google、百度、Bing 都是允许的,而 Google bot 则会在页面上执行 JavaScript,因此每篇博客都被刷了好多阅读量。


Google 爬虫数据

于是,只好在前端做一些相关的处理。

  
    
    
    
  1. var botPattern = "(googlebot\/|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google|bingbot...";

  2. var botRe = new RegExp(botPattern, 'i');

  3. var userAgent = navigator.userAgent;

  4. if (!botRe.test(userAgent)) {

  5. }

而除了,上面说到的鸡汤问题。它也有一些额外的好处,如:

  • 长尾效应。这种高流量的文章、商品,往往能带来长尾效应,就像亚马逊上的畅销书,畅销书本身是不赚钱的。但是网站可以通过相关的文章、产品,来获得更多的阅读及利润。而这取决于,我们为用户推荐的相关产品,是不是真正是用户需要的

考虑到上面的鸡汤流量问题,它可以吸引大量的人气,但是会导致劣币驱除良币的产生——大量产生优秀内容的作者,写不出受大众欢迎的文章。举个例子,技术写作来说,面向新手的文章,往往会有比较高的阅读量;而面向中高端用户的文章,则阅读量低。可要是首页都是新手文章,流量和受众就会越来越多,但是高端用户就会离开这个社区。

因此,我们还可以采用用户评分,来增加一个新的榜单,如 Medium 和 『玩点什么』的第二种推荐方式。

玩点什么首页推荐

它可以在保证流量的同时,也不降低网站的质量。

基于统计学:评分及 IMDB 加权算法推荐

软件开发,本身是以演进的形式进行的。不论,我们是开发基于内容的推荐系统,还是协同过滤的系统,它都依赖于我们拥有一个评分系统。与此同时,如果我们没有足够的用户,我们也进行不了内容推荐和协同过滤,因此设计一个稍微完善一点的评价排名,便显得很有必要。

下图是『玩点什么』的评分,用户不需要登录就可以评分:



玩点什么评分示例


尽管没有登录是一个风险问题,然而对于一个内容网站来说,刷评价的意义并不大。

在真实应用的过程中,遇到了一个问题:

  • A 文章只有 5 个评分,且都是 5 分;

  • B 文章则有 100 个评分,平均值则是 4.8 分

这个时候,我们很难判定 A 就比 B 好,于是在知乎上看到了一个相关的评分算法,即(更多信息可以阅读:IMDB 给出的电影评分的计算方法是怎样的?),又可以称为 IMDB TOP 250 评分算法。

它是由贝叶斯统计的算法得出的加权分(Weighted Rank-WR),其公式如下:

  
    
    
    
  1. (WR) = (v ÷ (v+m)) × R + (m ÷ (v+m)) × C

  • WR, 加权得分(weighted rating)。

  • R, 该电影的用户投票的平均得分(Rating)。

  • v, 该电影的投票人数(votes)。

  • m, 排名前 250 名的电影的最低投票数(现在为 3000)。

  • C, 所有电影的平均得分(现在为6.9)。

于是,我的算法代码就变成了这样:

  
    
    
    
  1. def imdb_rank(average_rating, votes_number):

  2.    minimum_votes = settings.MINIMUM_VOTES

  3.    correctly_votes_rate = settings.CORRECTLY_VOTES_RATE

  4.    return (votes_number / (votes_number + minimum_votes)) * average_rating + (minimum_votes / (

  5.    votes_number + minimum_votes)) * correctly_votes_rate

然而,在计算排序的时候,我不是拿所有的文章排序,而是:

  1. 从所有文章中过滤出能达到最小评分数的文章

  2. 按评分值,对这些文章进行排序,取前 10

  3. 对前 10 中的这些文章,进行 imdb_rank 计算,取前 3

这样做的主要原因是,出于服务器性能考虑。

待改进

可是我给一个文章五分,并不代表我真的喜欢这篇文章。正如,我在某宝上不敢给差评一样,万一被骚扰了呢。但是我喜欢一个东西,我会给一个评论。因此,我会开心地留个言,又或者是在留言给个差评:卖家真好,卖了个手机壳,送了个手机

因此,目前行业内有一些做法是,评分 + 评论分析,从评论中分析出用户的真实想法。


网站地址:https://www.wandianshenme.com/


文章太长,在下篇中,我将介绍:

  • 基于标签

  • 基于内容推荐

  • 协同过滤

登录查看更多
0

相关内容

推荐系统,是指根据用户的习惯、偏好或兴趣,从不断到来的大规模信息中识别满足用户兴趣的信息的过程。推荐推荐任务中的信息往往称为物品(Item)。根据具体应用背景的不同,这些物品可以是新闻、电影、音乐、广告、商品等各种对象。推荐系统利用电子商务网站向客户提供商品信息和建议,帮助用户决定应该购买什么产品,模拟销售人员帮助客户完成购买过程。个性化推荐是根据用户的兴趣特点和购买行为,向用户推荐用户感兴趣的信息和商品。随着电子商务规模的不断扩大,商品个数和种类快速增长,顾客需要花费大量的时间才能找到自己想买的商品。这种浏览大量无关的信息和产品过程无疑会使淹没在信息过载问题中的消费者不断流失。为了解决这些问题,个性化推荐系统应运而生。个性化推荐系统是建立在海量数据挖掘基础上的一种高级商务智能平台,以帮助电子商务网站为其顾客购物提供完全个性化的决策支持和信息服务。

知识荟萃

精品入门和进阶教程、论文和代码整理等

更多

查看相关VIP内容、论文、资讯等
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
90+阅读 · 2020年6月28日
【新书】Pro 机器学习算法Python实现,379页pdf
专知会员服务
199+阅读 · 2020年2月11日
【推荐系统/计算广告/机器学习/CTR预估资料汇总】
专知会员服务
87+阅读 · 2019年10月21日
深度 | 推荐系统如何冷启动?
AI100
17+阅读 · 2019年4月7日
推荐系统
炼数成金订阅号
28+阅读 · 2019年1月17日
DataCanvas周晓凌:如何为用户提供最佳体验的实时推荐系统
DataCanvas大数据云平台
5+阅读 · 2018年11月12日
基于大数据搭建社交好友推荐系统
云栖社区
8+阅读 · 2018年2月2日
如何成为一名推荐系统工程师
机器学习研究会
9+阅读 · 2017年11月20日
如何系统地学习数据挖掘?
数据库开发
10+阅读 · 2017年10月22日
Arxiv
5+阅读 · 2018年5月1日
Arxiv
6+阅读 · 2018年3月28日
Arxiv
6+阅读 · 2018年2月6日
Arxiv
27+阅读 · 2017年12月6日
Arxiv
4+阅读 · 2016年12月29日
VIP会员
相关资讯
深度 | 推荐系统如何冷启动?
AI100
17+阅读 · 2019年4月7日
推荐系统
炼数成金订阅号
28+阅读 · 2019年1月17日
DataCanvas周晓凌:如何为用户提供最佳体验的实时推荐系统
DataCanvas大数据云平台
5+阅读 · 2018年11月12日
基于大数据搭建社交好友推荐系统
云栖社区
8+阅读 · 2018年2月2日
如何成为一名推荐系统工程师
机器学习研究会
9+阅读 · 2017年11月20日
如何系统地学习数据挖掘?
数据库开发
10+阅读 · 2017年10月22日
相关论文
Arxiv
5+阅读 · 2018年5月1日
Arxiv
6+阅读 · 2018年3月28日
Arxiv
6+阅读 · 2018年2月6日
Arxiv
27+阅读 · 2017年12月6日
Arxiv
4+阅读 · 2016年12月29日
Top
微信扫码咨询专知VIP会员