LDA背景
LDA(隐含狄利克雷分布)是一个主题聚类模型,是当前主题聚类领域最火、最有力的模型之一,它能通过多轮迭代把特征向量集合按主题分类。目前,广泛运用在文本主题聚类中。
LDA的开源实现有很多。目前广泛使用、能够分布式并行处理大规模语料库的有微软的LightLDA,谷歌plda、plda+,sparkLDA等等。下面介绍这3种LDA:
LightLDA依赖于微软自己实现的multiverso参数服务器,服务器底层使用mpi或zeromq发送消息。LDA模型(word-topic矩阵)由参数服务器保存,它为文档训练进程提供参数查询、更新服务。
plda、plda+使用mpi消息通信,将mpi进程分为word、doc俩部分。doc进程训练文档,word进程为doc进程提供模型的查询、更新功能。
spark LDA有两种实现:1.基于gibbs sampling原理和使用GraphX实现的版本(即spark文档上所说的EMLDAOptimizer and DistributedLDAModel),2.基于变分推断原理的实现的版本(即spark文档上的OnlineLDAOptimizer and LocalLDAModel)。Spark LDA的介绍请参见这里。
LightLDA,plda、plda+,spark LDA比较
论能够处理预料库的规模大小,LihgtLDA要远远好于plda和spark LDA
经过测试,在10个服务器(8核40GB)集群规模下:
LihgtLDA能够处理上亿文档、百万词汇的语料库,能够训练上百万主题数。这样的处理能力使得LihgtLDA能够轻松训练绝大多数语料库。微软号称使用几十机器的集群便能训练Bing搜索引擎爬下数据的十分之一。
相对于LihgtLDA ,plda+能够处理规模小的多,上限是:词汇数目*主题数(模型大小) < 5亿。当语料库规模达到上限后,mpi集群会因内存不够而终止,或因为内存数据频繁切换,迭代速度十分缓慢。虽然plda+对语料库的词汇数目和训练的主题数目很敏感,但对文档的规模并不是很敏感,在词汇数目和主题数目较小的情况下,1000万级别的文档也能够轻松解决。
spark LDA的GraphX版处理规模衡量标准是图的顶点数据,即(文档数 + 词汇数目)*主题数目,上限是 文档数*主题数 < 50亿(由于词汇数目相对于文档数目往往较小,近似等于 文档数*主题数)。当超过这个规模后,spark集群进入假死状态。不停有节点出现OOM,直至任务以失败告终。
变分推断实现的spark LDA瓶颈是 词汇数目*主题数目,这个值也就是我们所说的模型大小,上限约1亿。为什么存在这个瓶颈呢?是因为变分推断的实现过程中,模型使用矩阵本地存储,各个分区计算模型的部分值,然后在driver上将矩阵reduce叠加。当模型过大,driver节点的内存就无法承受各个分区发过来的模型。
收敛速度上,LightLDA要远快于plda、plda+和spark LDA。小规模语料库(30万文档,10万词,1000主题)测试,LightLDA : plda+ : spark LDA(graphx) = 1:4:50
为什么各种LDA的能够处理语料库规模的衡量标准不一样呢?这与它们的实现方式有关,不同的LDA有不同的瓶颈,我们这里单讲plda+的源码解读,其他lda后续介绍
plda+介绍
plda+是LDA的并行C++实现,由谷歌公司开发,它分布式基础是MPI,使用高度优化的Gibbs sampling算法训练文档。
如图所示,plda+将mpi进程组分为2部分——word进程和doc进程。
word进程
word进程存储plda+的模型,使用分布是存储方式,每个进程只负责模型的一部分。LDA的模型指的是word-topic矩阵(矩阵大小=词汇数目x主题数目),矩阵每行表示语料库中一word在各个topic中出现的次数。实现上,每行word-topic由向量或数组表示。word进程负责为doc进程提供word-topic模型参数(即矩阵中的一行,word的各topic出现次数),响应doc进程发送过来的模型更新消息。它的角色就相当于一个参数服务器。
doc进程
doc进程是plda+存储文档的地方,也是训练文档的地方。也采用分布式存储方式,每个进程只持有语料库的一部分文档。另外,doc进程还分布是存储doc-topic矩阵,doc-topic矩阵(矩阵大小=文档数目x主题数目)描述语料库各文档doc中的所有词在各个topic下的数目。doc进程从word进程获取word-topic参数和global_topic参数(每个主题拥有的词的数目,由word-topic矩阵按行叠加),依据gibbs sampling算法为每个词的重新选取主题,将词的主题选取情况发送消息给word进程,通知其更新模型。
doc进程主要由3部