http://www.csdn.net/article/2015-09-30/2825828算法
你们好,我叫杨鹏,主要关注于推荐和机器学习方面。我今天分享一下世纪佳缘在推荐方面的尝试和心得。编程
先说一下咱们的推荐场景。咱们使用推荐的场景跟电影、商品推荐有很大的不一样,商品的推荐可能只考虑到转化就能够了,咱们要考虑推荐链的更长一些。app
咱们的状况:用户登陆网站,算法推荐出用户可能感兴趣的人,用户发信,收信用户看信。最大的不一样点在于,咱们的item也是人,设计算法时也要考虑item的感觉。机器学习
拿亚马逊来类比,亚马逊可能只须要考虑把一本书推荐给某我的,咱们还要考虑这本书是否是想被推荐给这我的。举一个极端的例子,若是咱们只是想提升男性用户发信,咱们只须要给全部人推荐美女,这样发信量必定会暴涨。可是这样作会引起不少问题:1)美女一天不可能读上千封信;2)美女对于一些条件很差的男性根本没兴趣;3)非美女收不到信。工具
因此不管是在产生候选,仍是在排序的时候,咱们都要同时考虑user和item。学习
以上是咱们在推荐场景上比较特殊的地方。测试
下面我主要说两个主题,先说咱们如何产生推荐。今天主要说一下基于图的算法,咱们的图算法是在Spark上实现的,使用用户历史发信数据,计算获得用户的推荐列表。(世纪佳缘对Spark的理解,能够参考这个文档:世纪佳缘吴金龙:Spark介绍——编辑注)网站
咱们的数据很稀疏,在图算法中,对于数据比较多的用户使用一跳节点,对于数据少的用户使用二跳甚至三跳节点的数据,这样能够避开CF中计算类似度的问题,对数据少的用户也能产生足够多的推荐。人工智能
当时遇到的主要问题是数据:一是数据太大,二是数据质量不高。spa
对那些出度(发信)和入度(收信)不少的点都要想办法进行抽样,不然会在计算时会耗尽内存。抽样时也尽可能提升数据质量。
对于收信不少的用户,抽样方法很简单,留下用户看了的信,去掉没看过的。对于发信的抽样,固然也能够只留下被看过的信,可是种方法有一点讲不通,由于看不看信是站在item的角度考虑的,对发信抽样,应该站在user的角度。
咱们尝试了直接扔掉发信过多的用户,随机抽样,保留最近数据几种方法。可是这样的方法都是很盲目的。对于发信而言,最主要的度量应该是:发信那一刻,用户是否是认真的。若是用户发信是很随意的,没有通过筛选,那这个数据其实没有多大意义。
解决这个问题固然也能够作个模型,可是太复杂了,咱们使用了一种简单的方法:根据用户的发信间隔判断,好比这封信与上一封信时间间隔10s以上,咱们就认为用户在用心的发信,保留这个数据,不然扔掉。方法很简单,可是最终线上的效果却很好。
我取了一个发信很随意的用户数据,统计了收信人在某个维度的分布,以下图所示。
如下则是一个认真发信的用户,判断标准就是刚才说的时间间隔。
能够明显看出来,认真发信的用户,只给符合本身要求的人发信,因此分布会更集中一些。可是不认真的用户,分布就很散了。
第二个主题,说一下排序。主要是对上边产生的候选集排序后把最终结果展现给用户。用到的算法也是CTR预测中经常使用到的LR、FM、GBDT等。
前边说过,咱们除了要考虑user发信,还要考虑item会不会看信,甚至item会不会回信。
所以一次排序一般会组合好几个模型:点击模型预测user从展现里点item的几率,发信模型预测发信几率,读信模型预测item读信几率。而后对这几种几率作个组合后获得最终的权重值。
用到的工具,数据怎么处理,都跟你们同样,没什么要说的,这里重点提一个咱们用到的评估方法。
大体就是上图这条曲线,横座标是预测几率的一个区间,纵座标是在这个区间内真实值的平均。好比图中(0.45, 0.46)的点,计算方法是:
这条曲线最完美的状况应该是只有(0, 0),(1, 1)点有值,固然算法不可能作到这样。次好的状况,画出来的线应该与 y=x 重合。
以前说过,咱们的排序是把多个算法出来的几率值做组合,因此对每一个算法的效果除了要求排序正确,还但愿预测的几率值也尽可能接近真实值。
ROC、NDCG能够很好的度量排序,可是无法度量真实值与预测值的误差,这就是为何咱们特别关注这条线。
最后说一下咱们几回算法尝试时遇到的问题。
1.测试Facebook论文中提到的用GBDT提取特征的方法。
当时为了方便,咱们直接把给LR的特征做为GBDT的特征,而后把获得的叶子节点做为特征,与原来的特征组合到一块儿再扔给LR。(能够参考这篇博客:CTR预估中GBDT与LR融合方案——编辑注)
线下效果和线上效果都有提高,咱们推广了这个方法,可是发现其中一个模型没有任何效果。
排查问题的时候发现,这个模型对全部特征做了离散化,出来的特征值所有非0即1。GBDT原本就是个树模型,能很好的处理非线性特征,使用离散化后的特征反而没什么效果。并且对于这种只有0、1值的状况,GBDT出现了不收敛的现象。
2.不一样的场景,使用不一样的算法。
LR是咱们最常使用的,因此在作点击模型时,天然也是先上了LR,可是线上效果并很差。后来上FM,效果却好的出奇。
若是登陆过咱们的网站,很容易发现缘由:展现的场景,只能看到头像、地区、年龄等几个属性,LR使用了大量用户看不到的特征,这些特征对于模型来讲是没有意义的。
That's all,我今天分享就到这里了。
问:可否再详细介绍一下推荐系统所采用的工具?
答:R的话,咱们主要用Liblinear;FM主要用SVDFeature;数据主要放Hive;Redis、Memcache和MongoDB都会用到;实时计算,会对接Kafka。
问:不实时计算能够吗?哪些方面是须要实时计算?
答:最主要的计算,仍是离线算好的。好比实时的排序,由于推荐列表动态生成,排序只能作成实时的。
问:请问主要的算法用得什么语言开发的?
答:线上Java,线下的代码就很随意了,Python/Java/Shell/Hive,什么方便用什么。
问:作算法时,你觉的最大的障碍是啥?如何解决这些障碍?能够谈谈具体实现上遇到的一些困难。
答:不少时候,一个模型效果很差,可是殊不知道从哪里着手改进。不知道加什么样的特征会有效,换模型也没有效果,试过了能想到的全部方法。
问:对数学要求高吗?
答:我本身主要作开发工做,数学有要求,可是不是那么高,能看懂论文就好。
问:杨老师,大家对用户的习惯有研究吗?如何作的?
答:用户习惯,咱们主要会统计一些数据,好比用户常常给多少岁的人发信,而后把这个统计做为特征放到模型里。
问:请问下,在使用算法的过程当中,对于对应算法的具体推演过程大家须要所有理解透么。感受有时候一个算法对数学的要求好高啊,想理清原因难度蛮大的。
答:不须要所有理解透,至少我看了不少遍EM的推导,如今推,我仍是不会。可是我知道EM推导大概怎么回事。
问:通常大家怎么样从为解决某个问题,而选择须要利用哪些维度,而后出发去构建模型的?
答:这个主要仍是我的经验,作的多了,很容易就能找到最有效的特征。
问:模型是基于已有的一些文章的仍是在实验过程当中改进的,有专门的算法部?
答:模型主要仍是基于已有的,除非很不符合咱们的须要,不然不多去改。
问:一些经常使用算法的推导,特性,用法都的知道吗?
答:经常使用算法确定是要知道的。
问:杨老师,你刚刚学习的时候,从哪一个简单示例或者文档入手的?
答:《集体智慧编程》。
问:可否介绍佳缘的推荐目前的实际效果,下一步的改进方向?
答:分算法和场景,总体上看,若是原来什么算法都没有,可能会有50%左右的提高。下一步的方向,主要是具体细分用户,或者从其它维度细分算法。以前的只关注了按场景细分,之后细分的维度会拓宽些。
问:请问您认为应届生应该怎样往机器学习方向发展呢?
答:环境是最重要的,若是真想作,找个真正作这个的公司。我一直想作游戏,到如今都没作成[Smile]。