用 LDA 做主题模型:当 MLlib 邂逅 GraphX

主题模型可以从一系列文章中自动推测讨论的主题。这些主题可以被用作总结和整理文章,也可以在机器学习流程的后期阶段用于特征化和降维。

在Spark 1.3中,MLlib现在支持最成功的主题模型之一,隐含狄利克雷分布(LDA)。LDA也是基于GraphX上构建的第一个MLlib算法。在这篇博文中,我们概述LDA和及其用例,并且解释GraphX是实现它最自然的方式。

主题模型

抽象地说,主题模型旨在一系列文章中找到一种结构。学习到这种“结构”之后,一个主题模型能回答以下这样的问题:X文章讨论的是什么?X文章和Y文章有多相似?如果我对Z文章感兴趣,我应该先读哪些文章?

LDA

主题模型是一个比较广的领域。Spark 1.3加入了隐含狄利克雷分布(LDA),差不多是现今最成功的主题模型。最初被开发用于文本分析和群体遗传学,LDA之后被不断拓展,应用到从时间序列分析到图片分析等问题。首先,我们从文本分析的角度描述LDA。

什么是主题?主题不是LDA的输入,所以LDA必须要从纯文本中推断主题。LDA将主题定义为词的分布。例如,当我们在一个20个新闻组的文章数据集上运行MLlib的LDA,开始的几个主题是:

看下三个主题中的高权重词语,我们可以很快了解每个主题在说什么:运动,空间探索和电脑。LDA的成功很大程度上源自它产生可解释主题的能力。

用例

除了推断出这些主题,LDA还可以推断每篇文章在主题上的分布。例如,X文章大概有60%在讨论“空间探索”,30%关于“电脑”,10%关于其他主题。

这些主题分布可以有多种用途:

  • 聚类: 主题是聚类中心,文章和多个类簇(主题)关联。聚类对整理和总结文章集合很有帮助。
    • 参看Blei教授和Lafferty教授对于Science杂志的文章生成的总结。点击一个主题,看到该主题下一系列文章。
  • 特征生成:LDA可以生成特征供其他机器学习算法使用。如前所述,LDA为每一篇文章推断一个主题分布;K个主题即是K个数值特征。这些特征可以被用在像逻辑回归或者决策树这样的算法中用于预测任务。
  • 降维:每篇文章在主题上的分布提供了一个文章的简洁总结。在这个降维了的特征空间中进行文章比较,比在原始的词汇的特征空间中更有意义。

在MLlib中使用LDA

我们给出一个使用LDA的小例子。我们在这儿描述这个过程,实际的代码在这个Github gist上。本例首先读取并预处理文章。预处理最重要的部分是选择词典。在本例中,我们将文本拆成词,之后去除(a)非字母词 (b)4个字符一下的短词 (c)最常见的20个词(停用词)。一般来说,在你自己的数据集上调整这个预处理步骤很重要。

我们运行LDA,使用10个主题和10轮迭代。根据你的数据集选择主题的数量很重要。其他参数设成默认,我们在Spark文档的Markdown文件(spark/docs/*.md)上训练LDA。

我们得到10个主题。下面是5个人工挑选出来的主题,每个主题配以最重要的5个词语。请注意每个主题有多么清晰地对应到Spark的一个组件!(打引号的主题标题是为了更清晰手动加的)

在Spark 1.3中LDA有Scala和Java的API。Python的API很快会加入。

实现:GraphX

有许多算法可以训练一个LDA模型。我们选择EM算法,因为它简单并且快速收敛。因为用EM训练LDA有一个潜在的图结构,在GraphX之上构建LDA是一个很自然的选择。

LDA主要有两类数据:词和文档。我们把这些数据存成一个偶图(如下所示),左边是词节点,右边是文档节点。每个词节点存储一些权重值,表示这个词语和哪个主题相关;类似的,每篇文章节点存储当前文章讨论主题的估计。

每当一个词出现在一篇文章中,图中就有一个边连接对应的词节点和文章节点。例如,在上图中,文章1包含词语“hockey” 和“system”

这些边也展示了这个算法的流通性。每轮迭代中,每个节点通过收集邻居数据来更新主题权重数据。下图中,文章2通过从连接的词节点收集数据来更新它的主题估计。

GraphX因此是LDA自然的选择。随着MLlib的成长,我们期望未来可以有更多图结构的学习算法!

可扩展性

LDA的并行化并不直观,已经有许多研究论文提出不同的策略来实现。关键问题是所有的方法都需要很大量的通讯。这在上图中很明显:词和文档需要在每轮迭代中用新数据更新相邻节点,而相邻节点太多了。

我们选择了EM算法的部分原因就是它通过很少轮的迭代就能收敛。更少的迭代,更少的通讯。

在Spark中加入LDA之前,我们在一个很大的Wikipedia数据集上做了测试。下面是一些数字:

  • 训练集规模:460万文档
  • 词典规模:110万词汇
  • 训练集规模:11亿词(大约239词/文章)
  • 100个主题
  • 16个 worker节点的EC2集群
  • 计时结果:10轮迭代中平均176秒/迭代

接下来是?

Spark的贡献者正在开发更多LDA算法:在线变分贝叶斯(一个快速近似算法)和吉布斯采样(一个更慢但是有时更准确的算法)。我们也在增加帮助模块,例如用于自动数据准备的Tokenizers和更多预测方法。

想开始用LDA,今天下载Spark 1.3

查看例子,了解API的细节,查看MLlib文档

致谢

LDA的开发是许多Spark贡献者的合作结果。他们是:Joseph K. Bradley、Joseph Gonzalez、David Hall、Guoqiang Li、Xiangrui Meng、Pedro Rodriguez、Avanesov Valeriy 和 Xusen Yin。

更多资源

通过这些综述学习更多关于主题模型和LDA的内容:

从这些研究论文中获得深入了解:

1 收藏 2 评论

关于作者:东狗

简介还没来得及写 :) 个人主页 · 我的文章 · 10

相关文章

可能感兴趣的话题



直接登录
最新评论
  • 你好,你文章中的git怎么链接不上,能否在github上创建下

  • 其实还有一本书对LDA写的更好更系统,还讲了其他资料没有的“变分推断”,这本书叫《LDA漫游指南》,http://yuedu.baidu.com/ebook/d0b441a8ccbff121dd36839a
    这位作者写的非常艰辛,放在百度阅读上供大家分享给大家阅读。希望楼主文章中提及,不要抹杀其他作者的辛勤工作

跳到底部
返回顶部