【第22期】观点:IT 行业加班,到底有没有价值?

Gensim官方教程翻译(七)——分布式潜在语义分析案例(Distributed Latent Semantic Analysis)

翻译 2015年07月06日 21:52:30

仅供个人学习之用,如有纰漏,敬请指正。原文地址


阅读《分布式计算》教程来了解gensim中的分布式计算。

设置一个集群

我们将会通过一个案例展示如何运行分布式潜在语义分析。让我们假设我们有5个计算机,所有的电脑都在一个网段(网络广播可达)。为了开始,首先安装gensim并在每台电脑上设置Pyro():

$ sudo easy_install gensim[distributed]
$ export PYRO_SERIALIZERS_ACCEPTED=pickle
$ export PYRO_SERIALIZER=pickle

接下来,在某一个计算机上运行Pyro的名称服务(无论是哪一台):

$ python -m Pyro4.naming -n 0.0.0.0 &

假设我们的集群中的电脑都是有带有内存负载的双核电脑,我们可以在其中4台上运行2个工作者脚本,共创建8个逻辑工作节点:

$ python -m gensim.models.lsi_worker &

这将会运行gensim的lsi_worker.py脚本(在4台电脑上运行2次)。这让gensim知道它可以在这四台电脑上每台并行运行两个工作,以便计算可以更快,当然也会消耗双倍的内存。
再下一步,选择一台计算机将其作为一个作业调度程序,负责工作者同步,并在其上运行LSA调度器。
在我们的例子中,我们将会使用第5台电脑来作为调度器,并在那里运行:

$ python -m gensim.models.lsi_dispatcher &

一般来说,调度器可以运行在与其中一个工作者节点上,或者也可以是另一个不同的电脑(在相同的广播域)。调度器大多数时间不会占用太多CPU,但是请选择一个有足够内存的计算机。
就是这样!集群已经被建立起来了,并且可以用来接受工作了。后来需要移除工作者节点时,只要结束其lsi_worker进程即可(不会影响正在运行的计算,节点的添加和删除都是动态的)。如果结束了lsi_dispatcher,在你重启它之前将不能运行计算(虽然已经存在的工作者进程能重新启用)。

运行LSA

让我们测试一下我们的设置,运行一个分布式LSA计算。在五台计算机中的任意一台打开一个Python shell(再说一遍,可以是任意一台在同一广播域的计算机,我们的选择都是偶然的)并尝试运行:

>>> from gensim import corpora, models, utils
>>> import logging
>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

>>> corpus = corpora.MmCorpus('/tmp/deerwester.mm') # 载入一个在教程中用到的9个文档的语料库
>>> id2word = corpora.Dictionary.load('/tmp/deerwester.dict')

>>> lsi = models.LsiModel(corpus, id2word=id2word, num_topics=200, chunksize=1, distributed=True) # 运行分布式LSA

这里使用到了《语料库与向量空间》教程中创建的语料库及属性记号映射。如果你查找Python会话的日志,你应该会找到类似这样的一行:

2010-08-09 23:44:25,746 : INFO : using distributed version with 8 workers

这意味着一切都在顺利进行。你也可以检查来自工作者和调度器进程的日志文件——这对于防止问题特别有用。检查一下LSA的结果,打印前两个潜在主题:

topic #0(3.341): 0.644*"system" + 0.404*"user" + 0.301*"eps" + 0.265*"time" + 0.265*"response"
topic #1(2.542): 0.623*"graph" + 0.490*"trees" + 0.451*"minors" + 0.274*"survey" + -0.167*"system"

成功了!但是这种规模的语料库对于我们强大的集群来说没有什么挑战性……实际上,我们故意降低了单个文档一次工作的大小(chunksize参数),否则所有的文档将会被一个工作者一次处理完。

所以,让我们在百万文档上试验一下LSA:

>>> # 不断重复corpus将语料填充至1M
>>> corpus1m = utils.RepeatCorpus(corpus, 1000000)
>>> # 运行分布式LSA
>>> lsi1m = models.LsiModel(corpus1m, id2word=id2word, num_topics=200, chunksize=10000, distributed=True)

>>> lsi1m.print_topics(num_topics=2, num_words=5)
topic #0(1113.628): 0.644*"system" + 0.404*"user" + 0.301*"eps" + 0.265*"time" + 0.265*"response"
topic #1(847.233): 0.623*"graph" + 0.490*"trees" + 0.451*"minors" + 0.274*"survey" + -0.167*"system"

其日志文件应该类似于:

2010-08-10 02:46:35,087 : INFO : using distributed version with 8 workers
2010-08-10 02:46:35,087 : INFO : updating SVD with new documents
2010-08-10 02:46:35,202 : INFO : dispatched documents up to #10000
2010-08-10 02:46:35,296 : INFO : dispatched documents up to #20000

2010-08-10 02:46:46,524 : INFO : dispatched documents up to #990000
2010-08-10 02:46:46,694 : INFO : dispatched documents up to #1000000
2010-08-10 02:46:46,694 : INFO : reached the end of input; now waiting for all remaining jobs to finish
2010-08-10 02:46:47,195 : INFO : all jobs finished, downloading final projection
2010-08-10 02:46:47,200 : INFO : decomposition complete

因为我们的“一百万语料库”词汇量太小、结构太一般,LSA的计算啊仅仅消耗了12秒。-_-!为了真实的压力测试,让我们在英文维基百科语料库上做一个LSA。

维基百科上的分布式LSA

首先,像之前的《英文维基百科的实验》一样下载并准备维基百科语料库,然后加载语料库迭代器:

>>> import logging, gensim, bz2
>>> logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

>>> # 加载id->word mapping (the dictionary)
>>> id2word = gensim.corpora.Dictionary.load_from_text('wiki_en_wordids.txt')
>>> # load corpus iterator
>>> mm = gensim.corpora.MmCorpus('wiki_en_tfidf.mm')
>>> # mm = gensim.corpora.MmCorpus(bz2.BZ2File('wiki_en_tfidf.mm.bz2')) # use this if you compressed the TFIDF output

>>> print(mm)
MmCorpus(3199665 documents, 100000 features, 495547400 non-zero entries)

现在我们已经准备好在英文维基百科上运行分布式LSA了:

>>> # 使用集群提取400个LSI主题
>>> lsi = gensim.models.lsimodel.LsiModel(corpus=mm, id2word=id2word, num_topics=400, chunksize=20000, distributed=True)

>>> # 打印前10个主题的贡献最高的单词(消极或积极)
>>> lsi.print_topics(10)
2010-11-03 16:08:27,602 : INFO : topic #0(200.990): -0.475*"delete" + -0.383*"deletion" + -0.275*"debate" + -0.223*"comments" + -0.220*"edits" + -0.213*"modify" + -0.208*"appropriate" + -0.194*"subsequent" + -0.155*"wp" + -0.117*"notability"
2010-11-03 16:08:27,626 : INFO : topic #1(143.129): -0.320*"diff" + -0.305*"link" + -0.199*"image" + -0.171*"www" + -0.162*"user" + 0.149*"delete" + -0.147*"undo" + -0.144*"contribs" + -0.122*"album" + 0.113*"deletion"
2010-11-03 16:08:27,651 : INFO : topic #2(135.665): -0.437*"diff" + -0.400*"link" + -0.202*"undo" + -0.192*"user" + -0.182*"www" + -0.176*"contribs" + 0.168*"image" + -0.109*"added" + 0.106*"album" + 0.097*"copyright"
2010-11-03 16:08:27,677 : INFO : topic #3(125.027): -0.354*"image" + 0.239*"age" + 0.218*"median" + -0.213*"copyright" + 0.204*"population" + -0.195*"fair" + 0.195*"income" + 0.167*"census" + 0.165*"km" + 0.162*"households"
2010-11-03 16:08:27,701 : INFO : topic #4(116.927): -0.307*"image" + 0.195*"players" + -0.184*"median" + -0.184*"copyright" + -0.181*"age" + -0.167*"fair" + -0.162*"income" + -0.151*"population" + -0.136*"households" + -0.134*"census"
2010-11-03 16:08:27,728 : INFO : topic #5(100.326): 0.501*"players" + 0.318*"football" + 0.284*"league" + 0.193*"footballers" + 0.142*"image" + 0.133*"season" + 0.119*"cup" + 0.113*"club" + 0.110*"baseball" + 0.103*"f"
2010-11-03 16:08:27,754 : INFO : topic #6(92.298): -0.411*"album" + -0.275*"albums" + -0.217*"band" + -0.214*"song" + -0.184*"chart" + -0.163*"songs" + -0.160*"singles" + -0.149*"vocals" + -0.139*"guitar" + -0.129*"track"
2010-11-03 16:08:27,780 : INFO : topic #7(83.811): -0.248*"wikipedia" + -0.182*"keep" + 0.180*"delete" + -0.167*"articles" + -0.152*"your" + -0.150*"my" + 0.144*"film" + -0.130*"we" + -0.123*"think" + -0.120*"user"
2010-11-03 16:08:27,807 : INFO : topic #8(78.981): 0.588*"film" + 0.460*"films" + -0.130*"album" + -0.127*"station" + 0.121*"television" + 0.115*"poster" + 0.112*"directed" + 0.110*"actors" + -0.096*"railway" + 0.086*"movie"
2010-11-03 16:08:27,834 : INFO : topic #9(78.620): 0.502*"kategori" + 0.282*"categoria" + 0.248*"kategorija" + 0.234*"kategorie" + 0.172*"категория" + 0.165*"categoría" + 0.161*"kategoria" + 0.148*"categorie" + 0.126*"kategória" + 0.121*"catégorie"

在串行模式,使用单程算法(one-pass algorithm)创建维基百科的LSI模型,在我的笔记本上消耗了5.25小时(OS X, C2D 2.53GHz, 4GB RAM with libVec)。使用了有4个工作者(Linux, dual-core Xeons of 2Ghz, 4GB RAM with ATLAS)的分布式模式,消耗时间下降至1小时41分。你可以在我的研究论文中阅读到更多的关于内部设定和实验的内容。

举报

相关文章推荐

Gensim Word2vec 使用教程

本文主要基于Radim Rehurek的Word2vec Tutorial.**准备输入**Gensim的word2vec的输入是句子的序列. 每个句子是一个单词列表代码块例如:>>> # impor...

Gensim官方教程翻译(三)——主题与转换(Topics and Transformations)

gensim官方教程翻译。本篇主要介绍了gensim提供的各种空间向量模型转换方法及其使用。

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

Gensim官方教程翻译(六)——分布式计算(Distributed Computing)

为何要分布式计算?需要构建一个百万文档级语料库的语义代表,却耗时太~~长?手上有几个可用的闲置计算机?分布式计算力争通过将给定的任务切分为几个小型任务,并将这些任务指派给几台平行的计算机完成来实现加速...

Gensim官方教程翻译(五)——英文维基百科的实验

仅供个人学习只用,如有错误,敬请指正。原文地址为了测试gensim的性能,我们在维基百科英文版上运行了一些实验。 这个页面描述了获取与处理维基百科的过程,以便任何人都能再现这个结果。本教程要求已经正...

Gensim官方教程翻译(一)——快速入门

为了方便自己学习,翻译了官方的教程,原文:http://radimrehurek.com/gensim/tutorial.html。 本教程按照一系列的实例组织,用以突出gensim的各种特征。本教程...

Gensim官方教程翻译(二)——语料库与向量空间(Corpora and Vector Spaces)

本文内容:如何利用gensim将文本信息转换为分析用的语料库,以及如何读取/存储语料库。

Gensim官方介绍翻译

为了方便自己学习,翻译一下。原文地址:http://radimrehurek.com/gensim/intro.html。 Gensim是一个免费的Python库,它可以用来从文档中自动提取语义主题,...

Gensim官方教程翻译(四)——相似度查询(Similarity Queries)

本文主要讲述了如何利用gensim将训练好并经过空间转换的空间向量模型进行索引,并应用于计算查询字符串与已索引文档的相似度。

Gensim Word2vec简介

本文主要基于Radim Rehurek的Word2vec Tutorial. 准备输入 Gensim的word2vec的输入是句子的序列. 每个句子是一个单词列表: >>> # import...

Python版的Word2Vec -- gensim 学习手札 中文词语相似性度量 V1.1

前言相关内容链接: 第一节:Google Word2vec 学习手札 昨天好不容易试用了一下Google自己提供的Word2Vector的源代码,花了好长时间训练数据,结果发现似乎Python并不能...
  • MebiuW
  • MebiuW
  • 2016-08-24 20:10
  • 6045
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)