引言
在上一篇的博客谈到使用LDA的方法挖掘影迷关注点可谓是无功而返。后来我思考了许久,决定将原来的向量空间模型转变为词语网(WordNet),然后通过社区检测算法来把网络划分不同的社区,从而确定为不同的话题。
社区检测算法
现实世界中的许多系统都可以采用网络的形式来加以描述,可以将网络看作由节点和连接节点的边组成的集合。通常用节点来表示现实系统中的个体,用边表示个体间的某种关联。网络反映了节点之间相互关系。社区检测,又称社区发现(NetWork Community Detection),最基本的作用是将个体根据网络结构进行社区分类,即将个体划分到若干社区中。其过程类似于聚类,但聚类并没有考虑到节点与节点之间的作用。
关于网络社区检测算法的原理介绍,我放另一份博客中:网络社区检测讲解
至于快速入门的书籍,我推荐丁连红、时鹏的《网络社区发现》
在实现上,我是使用python版的igraph,我将它的安装使用说明放到我的百度文库当中
python-igraph讲义
词图切分的过程原理说明
社区检测算法用很多种,主要分为流式分析和拓扑分析。流式分析优点是快速,但结构不稳定;拓扑分析则较为慢,但稳定性较强,对初始状态相对不那么敏感。考虑到结果的质量性,我在项目中主要采用后者中的一种方法,基于模块度增益的社区检测算法(BGLL)
模块度的公式如下:
步骤一:创建倒排索引
一部电影有上万条评论,所以我先采用Spark做评论词条化,从而构建词项词典(dictionary)和倒排记录表(posting)。保存到一个reverseIndex.txt的文件中,形成的结果图如下:
具体实现的代码,我放到github上:倒排索引代码
步骤二:构建词语网络,词图切分
形成倒排索引后,我本来打算使用PMI去计算词语之间的关联程度,但计算出来的PMI值相差不大,造得切分出来的效果十分的差。后来我转变了一下,改为先是通过词语出现频率过滤低频词语,然后根据计算词语之间的支持度,代替原来的PMI。构建好词语网路之后,就利用BGLL进行切分。切分的效果如图:
可以看出话题之间词语的关联性也相对比较强的,例如大蛇丸的儿子,国语配音等话题。
这段实现的代码,我也放至到github当中:词图切分的代码
后记
由于比赛时间的仓促,我们并没有做比较严格的指标来衡量该算法思路的优劣,只是根据模块度的值来判断划分结果的好快。幸运的是,当时比赛的时候,评委对我们整体项目表示十分的满意,我们也过关斩将地拿到了第一名。怎么说,感觉我们需要前进的路还有很多要走,写下这份博客来记录我的小小心得。