写点什么

微博背后的那些算法

2015 年 5 月 21 日

【编者按】为了更好地向读者输出更优质的内容,InfoQ 将精选来自国内外的优秀文章,经过整理审校后,发布到网站。本篇文章作者为张延祥,原文链接为《微博背后的那些算法》

引言

微博是一个很多人都在用的社交应用。天天刷微博的人每天都会进行着这样几个操作:原创、转发、回复、阅读、关注、@等。其中,前四个是针对短博文,最后的关注和 @则针对的是用户之间的关系,关注某个人就意味着你成为他的粉丝,而他成为你的好友;@某个人意味着你想要他看到你的微博信息。

微博被人们认为是“自媒体”,即普通大众分享与本身相关的“新闻”的途径。最近,有些人使用自己在自媒体上的影响力而盈利的报道屡见不鲜。那微博上个人影响力是怎样计算的呢?微博上还有哪些算法作为看不见的手在管理着我们?我们的每一个行为怎样影响着算法呢?

直观上看,微博其实是人类社会的一个简单的缩影,微博网络的一些特点,也许可以启发我们得到真实的社会网络上的规律。得益于社交网络的爆发式发展,“社会计算”尤其是社交网络分析成为数据挖掘的新宠儿。下面我们就针对微博网络分析的一些算法进行简单的介绍,其中的有些算法对于其他的社交应用可能也适用。

标签传播

微博用户量浩大,不同的人有不同的兴趣。挖掘每个用户的兴趣有助于更加精准的广告投放、内容推荐。为了得到每个用户的兴趣,可以为用户打上标签,每个标签代表用户的一个兴趣,用户可以拥有一个或多个标签。为了得到最终的用户标签,先做第一个假设:

每个用户的好友 (或粉丝) 中与该用户具有相同兴趣的人占多数。

这就引出了本文介绍的第一个算法,即标签传播算法。在这个算法中,每个用户的标签取其好友或粉丝中标签最多的一个或多个。当然,可以将好友和粉丝的标签都考虑进来,整合的时候可以考虑赋予好友的标签和粉丝的标签不同的权重。标签传播算法的过程如下:

  1. 对一部分用户给出初始标签;
  2. 对每一个用户,统计其好友和粉丝的标签数目,赋予该用户出现次数最多的一个或者多个标签。
  3. 循环进行第 2 步,直到用户的标签不再发生大的变化为止。

用户相似度计算

标签传播算法实现起来比较简单,其缺点在于当所做的假设不符合事实时,比如为了社交上的礼貌,我们一般会把自己的亲友添加关注,这些人不一定和我们拥有同样的标签;该算法的结果就会变得很差。解决的办法就是通过计算用户之间的相似度来衡量好友或粉丝的标签对用户标签的贡献率。因而得到第二个假设:

与用户越相似的好友或粉丝,其标签越可能是用户的标签。

那么,如何衡量用户之间的相似度呢?这就需要考虑到用户发表的微博信息了,包括转发的和原创的。这里是要考虑用户之间的相似度而不是用户微博之间的相似度,因而在实际计算时,将某个用户的所有微博信息聚集到一起进行计算。一个可选的方法是使用词袋法将微博信息表示成词语向量,然后直接使用余弦方法等计算其相似度。但这个方法太过简单,不容易达到好的结果,这里介绍一种基于 LDA(隐含狄利克雷分布)的相似度计算方法。

LDA 仍然使用词袋法表示文本,但是在中间添加了一个主题层,形成了“文档 - 主题 - 词语”三层概率模型,即每篇文档看成是主题的一种概率分布,主题又被看成是单词的概率分布。在 LDA 模型下,文档可以被看成按照如下方式生成:

  1. 对于每篇文档:
  2. 从主题分布中抽取一个主题;
  3. 从该主题的词语分布中抽取一个词语;
  4. 重复第 2 步和第 3 步,直到该文档的所有词语都生成。

LDA 模型参数的估计算法不在本文的讨论范围之内。这里只需要知道,通过 LDA 可以得到每个用户的微博信息的主题分布。然后使用余弦方法、KL 距离等计算相似度的方法来得到用户间主题分布的相似度,以之作为用户之间的相似度。而后使用该相似度对标签传播进行加权。

时间因素和网络因素

上述的算法还有什么缺点呢?

随着时间的变化,用户的兴趣是会变化的,计算用户相似度的时候每次都把所有微博信息都聚合在一起不太合理。对此,可以通过选取距离当前时间较近的 N 条微博。比如,对每个用户,选取距离当前时间最近的 50 条微博聚在一起放到 LDA 中训练。此处的 N 既不能太大也不能太小。太大则不容易反映用户兴趣的时间变化,太小则由于用户发表微博的随机性容易引起兴趣的漂移。为了使效果最好,可以不拘泥于一个固定的 N,比如可以考虑对每个用户按照其发表微博的时间序列做 N 值的自适应。

至此,在算法中还没有考虑微博关系中由回复、转发、@等所构成的网络信息。以转发为例,如果在用户的微博中频繁的转发某个好友的微博,那么用户和该好友的相似度相比其他好友来说应该会更高。这里可以看做是假设三:

用户转发某好友的微博的频率越高,用户与该好友的兴趣相似度越大。

相似的,可以得到假设四:

用户微博中 @某用户的频率越高,用户与该好友的兴趣相似度越大。

由此就得到了计算相似度的另外的因素。有很多方法可以添加一个新的因素到原有的相似度计算方法中,比如可以考虑将转发频率量化为值,作为权重添加到相似度的衡量中去。

社区发现

微博社区是指在微博中关系紧密的人组成的团体,社区内部的人之间联系紧密,社区之间的联系则比较稀疏。这里所指的关系紧密有两层含义,第一是社区内部的人之间的兴趣相似度大;第二是指社区内部的人之间的关系要近,比如要求社区内部的两个用户不能超过二度关联,二度关联即好友的好友。

兴趣相似度在上文已有叙述,关系相似度则需要利用用户之间的关注关系来进行计算。以用户的关注关系为单向链,可以将所有的微博用户之间的关系表示为一个巨大的有向图。用户之间的关系相似度可以简单的考虑,比如使用用户间的最短路径的倒数。但是这种方法衡量的不精确,我们知道,在现实世界中,存在着六度理论,在微博网络及其他社交网络中,往往关系会更加紧密。因而这种简单的关系相似度只能有至多六个离散值,显然不够精确。

为了达到更好的效果,这里不仅以最短路径作为显式量度,还要考虑一些隐式的量度。这里先给出两个假设,分别为假设五和假设六:

两个用户的共同好友越多,这两个好友的关系相似度越高。

两个用户的共同粉丝越多,这两个好友的关系相似度越高。

这里可以借鉴 Jaccard 相似度的计算方式,将这两种假设的量化函数表示为交集的大小与并集的大小之商。以假设五为例,其量化指标又被称为共指向性相似度,量化时使用两个用户共同好友的数目除以两个用户所有好友的数目。假设六的量化指标被称为共被指向性相似度,计算方式与共指向性相似度类似。从意义上讲,这两种相似度不仅仅是关系上的度量,在一定程度上也衡量了用户之间的兴趣相似程度,直观上看,两个用户共同关注的好友越多,他们的兴趣相似程度也越大。这两种相似度还有一个专业的名字,是基于结构情景的相似度计算。

得到了最短路径相似度、共指向性相似度、共被指向性相似度后,可以采用一种加权函数将它们融合起来,得到最后的相似度。之后,可以采用一些聚类算法如 K-Means、DBSCAN 等进行聚类操作,得到最后的社区簇。也可以采用相似度加权的标签传播算法,把具有相同标签的人作为一个社区。

影响力计算

在社区发现中,使用微博中的关系网络可以提高相似度计算的精确度。但关系网络能做的事情还有很多,影响力计算便是其中比较重要的应用。

说到影响力的计算,这里借鉴了网页排名中的算法。网页排名中广为人知的算法当属 PageRank 了,该算法由 google 创始人拉里·佩奇和谢尔盖·布林发明,随着 google 在商业上的成功而声名鹊起。该算法根据网页之间的链接来确定网页的排名,其核心在于一个假设,质量高的网页所指向的网页的质量必定也高。

根据 PageRank 的思想,可以得到微博上影响力的假设,称之为假设七:

影响力高的用户关注的用户的影响力必定也高。

将用户看成是 PageRank 中的网页,将关注关系看做是网页中的链接关系。从而,可以根据 PageRank 的算法流程得到在微博关注网络上的影响力计算算法:

  1. 赋予所有用户相同的影响力权重;
  2. 将每个用户的影响力权重按照其关注的人数等量分配;
  3. 对每个用户来说,其影响力等于其粉丝分配给他的权重之和;
  4. 第 2 步和第 3 步迭代,直到权重不再发生大的变化为止。

在网页排名中,基于网络关系的算法还有 HITS、HillTop 算法等,这些算法也可以借鉴到影响力计算中来。

上面的算法有什么缺点呢?

如果只是基于关系网络的话,那么很容易就造成,粉丝数目多的人影响力必然会很高。这样就导致有些用户去购买一些僵尸粉就可以达到很高的影响力了。这样的算法显然是不能应对实际情况的,因为还有太多的信息没有用到。

用户的影响力除了他的微博关系之外,还与他的个人属性有很大的关系,比如用户的活跃度、微文的质量等。用户的活跃度可以使用其发表微博的频度来衡量,微文的质量可以采用其被转发的数目、被回复的数目来得到。通过对这些值进行衡量,再加上上面算法的结果,就可以得到更加精确的影响力结果。

当然,也可以这样考虑,用户之间的回复关系、转发关系、@关系均可以构成网络,它们也有相应的假设,分别为假设八、假设九、假设十:

影响力越高的用户回复的微博的影响力越高,从而使该微博主人的影响力变高。

影响力越高的用户转发的微博的影响力越高,从而使该微博原创作者的影响力变高。

影响力越高的用户倾向于在其微博中 @影响力高的用户。

这样就又得到了转发网络、回复网络、@网络三种网络,借鉴 PageRank 算法,可以得到另外的三种影响力结果。将它们与关系网络的影响力结果进行融合,就可以最终的影响力结果了。这里的融合可以简单的考虑成结果的加权和,复杂的融合方法不在本文的范围之内。

话题因素和领域因素

得到了影响力的计算方法之后,可以做些什么呢?

可以对当前的热点话题进行影响力分析,得到谁在微博上成为当前热点话题的意见领袖。具体做法是这样,找到和当前热点话题相关的微文,从而找到参与当前热点话题的用户。如何找到和当前热点话题相关的微文呢?有话题标签的微文自不必说,对于没有话题标签的微文来说,可以使用上文中介绍的 LDA 算法,它可以在用户的所有微文中找到用户的主题分布,也可以对一条微文找到主题分布,一般来说,由于微文的字数限制在 140 以内,比较短,因而一条微文包含的主题数目不会太多,取该微文的主题分布中概率最高的主题当做其主题即可。

找到话题对应的微文与用户之后,运行影响力计算算法,就可以得到该话题中影响力较大的用户了。这也是舆情监测、社会热点监控的一个方面。

对于标签传播算法得到的结果,对同一标签下的用户运行影响力计算算法,可以得到该标签下的影响力排名,即领域内影响力排名。比如,李开复在全部领域内的影响力或许不是最高的,但在 IT 领域,其影响力绝对是数一数二的。

垃圾用户识别

在影响力计算中,提到要避免僵尸用户对影响力计算的干扰。在算法中,如果可以识别这样的用户,在计算影响力时将其排出在外,不仅可以提高效果,还可以降低计算量。

与影响力计算相似,垃圾用户的识别要同时考虑用户属性与链接关系两方面的因素。

对于垃圾用户来说,有一些统计上的特征与正常用户不同。比如如下几点:

  • 垃圾用户一般发微文具有一定的时间规律性,可以使用熵值对此进行衡量,熵是衡量随机性的一种量度,随机性越大,熵值越小。具体做法为将一定的粒度进行时间切片统计,得到每个时间片内的博文概率,然后依照概率进行熵值的计算。熵值越大代表用户发微文的时间越有规律,越有可能是垃圾用户。
  • 垃圾用户有些倾向于在微文中恶意的 @其他人,因而有些垃圾用户的微文中 @使用的比例比一般用户高。
  • 有些垃圾用户的微文中为了进行广告的推广,添加大量的 URL。可以通过微文中的 URL 比例进行衡量。也有些用户为了骗取 URL 的点击,微文中的内容与 URL 对应界面的内容不一致,这时需要判断微文与 URL 内容的一致程度,简单的做法可以使用词袋法将微文与 URL 对应界面表示成词语向量,查看微文中的词语在 URL 对应网页中出现的频度。
  • 对于那些为做广告推销的用户,还可以对其微文进行文本分类,判断其微文是否是广告,如果某用户的相当一部分微文是广告,则该用户可能是垃圾用户。
  • 垃圾用户一般随意的关注用户,故其粉丝数目与好友数目的比例与正常用户会有差别。而且正常用户一般是通过好友关系添加好友的,这样会形成关注三角形,如 A 看到其好友 B 关注了 C,那么若 A 也去关注 C,就形成了 A 关注 B、C,B 关注 C 的三角形。一般来说,由于垃圾用户关注的随意性,其关注三角形的比例与正常用户不同。

当然,垃圾用户与正常用户的不同之处不止这些,本文不再一一枚举。垃圾用户的识别本质上是一个二分类问题,获得了这些属性之后,就可以将这些信息输入到一个机器学习的分类模型中,比如逻辑斯蒂回归(LR)、决策树、朴素贝叶斯等,就可以对其进行分类了。

当然,还没有用到链接信息。一般来说,垃圾用户会去关注正常用户,而正常用户不会关注垃圾用户。这即是假设十一:

正常用户不倾向于关注垃圾用户。

这样就可以再次使用 PageRank 算法来对用户是否是垃圾用户的概率进行计算。这里需要注意的是,算法初始化时采用上面的分类器结果,将垃圾用户的概率设为 1,正常用户的概率设为 0。在 PageRank 计算过程中,不能通过简单的求和公式计算,比如如果一个用户关注了多个垃圾用户的时候,求和后概率可能大于 1;因而需要使用一些归一化方法或指数族函数进行概率的更新。

结语

本文对微博中常见的问题的对应算法进行了简单的介绍,在实际应用中的算法比介绍的要复杂的多。当然,本文覆盖的主题并不全,比如好友推荐、热点跟踪等就没有涉及到。但古人云“窥一斑而见全豹”,希望本文的介绍能帮助大家更好的理解微博这样的社交网络应用。

在文中,可以看到黑体标出的假设,这些假设看起来都与我们的直观感觉一致。而根据这些可以引申出很多有效的算法。所以有时候,只要你肯发现,算法就在身边。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流。

2015 年 5 月 21 日 22:588541

评论

发布
暂无评论
发现更多内容

看前谷歌工程师是如何副业赚钱的?

非著名程序员

程序员 个人成长 副业赚钱 提升认知

Windows AD日志分析告警平台—WatchAD安装教程

Young先生

监控 windows 日志 AD 告警

普通工程师简史

郭华

Cobra 命令自动补全指北

郭旭东

go cobra

低/零代码会让程序员失业吗?

代码制造者

程序员 低代码 零代码 信息化 编程开发

致远互联A6+Cloud C位出道 赋能中小企业乘风破浪

爱极客侠

微软看上的Rust 语言,安全性真的很可靠吗

华为云开发者社区

数据库 开源 rust 安全 代码

Django中的session的使用

Young先生

django session Cookie

SpringBoot系列(三):SpringBoot特性_SpringApplication类(自定义Banner)

xcbeyond

Java 微服务 springboot Banner

流量明星翻车的“直播卖房”,为什么众盟做成了?

脑极体

网站域名备案怎么做?有哪些快速备案的方法?

姜奋斗

网站 备案 网站搭建 域名解析 网站平台

神经网络的学习为何要设定损失函数?

王坤祥

神经网络 学习 损失函数

关于微服务架构的一些思考

俊俊哥

微服务

一文搞懂Flink rocksdb中的数据恢复

shengjk1

大数据 flink源码

解析中美数字货币竞争战略 | 构建属于“人类命运共同体”的货币体系

CECBC区块链专委会

数字货币 人民币

《深度工作》学习笔记(完)

石云升

读书笔记 时间管理 专注 深度工作

DSN 主流项目调研 2——Sia和SAFE Network

AIbot

区块链 分布式存储 分布式文件存储 Sia SAFENetwork

手抖了

shengjk1

随笔杂谈

核心稳定、易扩展——开放关闭原则(The Open-Closed Principle)

晃来晃去的萨麦尔

编程习惯 架构分析 软件设计原则

SpringBoot 系列(一):SpringBoot项目搭建

xcbeyond

Java 微服务 springboot

《深度工作》学习笔记(6)

石云升

读书笔记 专注 深度工作

Django查看操作数据库的执行命令

Young先生

数据库 django 操作

易观CTO郭炜:如何构建企业级大数据Ad-hoc查询引擎

易观大数据

我国开启“逆袭战”,区块链的盛夏来了?

CECBC区块链专委会

云计算 区块链技术

DSN 主流项目调研 3——Orbit数据库的故事

AIbot

区块链 分布式存储 IPFS 分布式文件 Orbit

流媒体云时代的声与色,融云铺就的桥与路

脑极体

SpringBoot系列(二):如何灵活使用SpringBoot

xcbeyond

Java 微服务 springboot

JAVA位运算

彭阿三

Java 位运算

LeetCode题解:88. 合并两个有序数组,for循环合并数组+sort排序,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

奋斗在一线大城市的年轻人的生活工作实录(工厂蓝领篇)

Learun

程序员 软件开发 故事 企业信息化 短片小说

别让非理性思维毁了你的人生

看山

随笔杂谈 非理性 认知偏差 自控术

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

微博背后的那些算法-InfoQ