44

文本挖掘从小白到精通(三)---主题模型和文本数据转换

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MjM5ODkzMzMwMQ%3D%3D&%3Bmid=2650414733&%3Bidx=5&%3Bsn=a5ea6b21a1a0e59bc5fbe20ebc2aae9c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

7z2URfZ.jpg!web

写在前面:笔者最近在梳理自己的文本挖掘知识结构,借助gensim、sklearn、keras等库的文档做了些扩充,会陆陆续续介绍文本向量化、tfidf、主题模型、word2vec,既会涉及理论,也会有详细的代码和案例进行讲解,希望在梳理自身知识体系的同时也能对想学习文本挖掘的朋友有一点帮助,这是笔者写该系列的初衷。

紧接着前面的两篇文章,笔者今天要聊的主题是:主题模型和文本数据转换(Topics and Text Data Transformation),这是在上篇文章涉及的词袋模型( Bag-of-Words)的基础上做的进一步文本特征提取。

可能有读者要问,为什么要做文本数据转换呢?

一个较为形象化的解释是:

机器不懂人类的自然语言,我们要将自然语言转换为机器易于理解的“语言”。转换成机器容易理解的语言就是说“机话”,变成一连串有阿拉伯数字构成的字符串,且这些字符串尽量保留原来人类语言的语义。举个例子,我们让机器理解一句话 --- “我们今天要去吃披萨”,进行转换后,可能出现部分的语义信息损失,比如机器会理解为“我们要去吃饭”,这在某些场合是可以接受的,但不能让机器理解为“我们要去打游戏”,这就离原始的语义信息偏离太远了。

简而言之,掌握了主题模型和文本数据转换以后,我们可以进行后面比较复杂且实用的文本挖掘应用了,比如文本相似度检索、文本聚类、文本分类等,这些都会在笔者后续的文章中提到。

正式开始前,设置日志,培养码代码的好习惯,打印程序运行中的细节,以便后面找到报错。

import logging

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

工作路径查询:

import tempfile

import os.path



TEMP_FOLDER = tempfile.gettempdir()

print('文件夹"{}" 将被用来存储语料和临时性的字典'.format(TEMP_FOLDER))

文件夹"C:\Users\hp\AppData\Local\Temp" 将被用来存储语料和临时性的字典

1. 数据转换接口(Transformation interface)

在上一篇文章 《文本挖掘从小白到精通(二)---语料库和词向量空间》 中,我们以向量流的形式创建了一个文档语料库。这次,笔者将继续使用该语料库:

from gensim import corpora, models, similarities

if os.path.isfile(os.path.join(TEMP_FOLDER, 'deerwester.dict')):

dictionary = corpora.Dictionary.load(os.path.join(TEMP_FOLDER, 'deerwester.dict'))

corpus = corpora.MmCorpus(os.path.join(TEMP_FOLDER, 'deerwester.mm'))

print("使用前面教程中产生的语料文件。")

else:

print("请运行前面的教程,以生成语料文件。")

2019-05-09 10:15:55,630 : INFO : 'pattern' package not found; tag filters are not available for English
2019-05-09 10:15:55,637 : INFO : loading Dictionary object from C:\Users\hp\AppData\Local\Temp\deerwester.dict
2019-05-09 10:15:55,642 : INFO : loaded C:\Users\hp\AppData\Local\Temp\deerwester.dict
2019-05-09 10:15:55,646 : INFO : loaded corpus index from C:\Users\hp\AppData\Local\Temp\deerwester.mm.index
2019-05-09 10:15:55,647 : INFO : initializing cython corpus reader from C:\Users\hp\AppData\Local\Temp\deerwester.mm

2019-05-09 10:15:55,649 : INFO : accepted corpus with 12 documents, 12 features, 35 non-zero entries

使用前面教程中产生的语料文件。

前面教程的语料库由这些文档构成:

  • 商业新知:知识图谱为内核,构建商业创新服务完整生态。

  • 如何更好利用知识图谱技术做反欺诈? 360金融首席数据科学家沈赟开讲。

  • 知识管理 | 基于知识图谱的国际知识管理领域可视化分析。

  • 一文详解达观数据知识图谱技术与应用。

  • 知识图谱技术落地金融行业的关键四步。

  • 一文读懂知识图谱的商业应用进程及技术背景。

  • 海云数据CPO王斌:打造大数据可视分析与AI应用的高科技企业。

  • 智能产业|《人工智能标准化白皮书2018》带来创新创业新技术标准。

  • 国家语委重大科研项目“中华经典诗词知识图谱构建技术研究”开题。

  • 最全知识图谱介绍:关键技术、开放数据集、应用案例汇总

  • 中译语通Jove Mind知识图谱平台 引领企业智能化发展。

  • 知识图谱:知识图谱赋能企业数字化转型,为企业升级转型注入新能量。

查看保存字典( Dictionary )中的前3个词汇:

print(dictionary[0])

print(dictionary[1])

print(dictionary[2])

创新 商业 知识图谱 

准备工作做好了,下面要进入正题了,笔者将重点展示 如何将文档从一个向量表示(Vector Representation )是转换为另一个向量表示 。 在此过程中,会涉及到两个目标:

  • 挖掘语料库中潜藏的结构,发现词汇之间的关联性。 前一篇文章中提到的词袋模型/表示,并不能很好的挖掘语料中的 词序特征 (语句中词汇的先后顺序)和 语义 特征 (上下文、词性搭配等),进行文本数据转换后则可以一种更加反映语义相关性的方式来表征文档,以提高后续文本聚类、文本分类等高阶文本挖掘应用的效果。

  • 使文档表示更紧凑。 这既提高了 效率 (新的文档表示会消耗更少的计算资源,转换过程会更快),也提升了 效果 (边际数据的趋势被忽略,也就是语料中的超低频和超高频词汇对语料的影响被削弱,从而达到数据降噪的目的,更能抓住文本中的重要特征)。

下面进入实际的代码操作:

1.1 创建转换(Creating a Transformation)

TF-IDF模型用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度,它是一个标准的Python对象,可通过对语料库训练进行初始化。

step 1 -- 初始化模型:

tfidf = models.TfidfModel(corpus)
2019-05-09 10:16:04,390 : INFO : collecting document frequencies
2019-05-09 10:16:04,393 : INFO : PROGRESS: processing document #0
2019-05-09 10:16:04,395 : INFO : calculating IDF weights for 12 documents and 11 features (35 matrix non-zeros)

通过打印出的日志可以看到,该TF-IDF转换模型在这12个经词袋表示的文档中抽取出了11个特征。

值得注意的是,不同的转换可能需要不同的初始化参数 --- 在TF-IDF的情境下,“训练”仅包括通过一次性提供语料库并计算其所有特征的文档频率,模型不需要额外设置参数。训练其他文本转换模型,比如潜在语义分析模型(Latent Semantic Analysis,LSI)或隐含狄利克雷分布模型(Latent Dirichlet Allocation),可能复杂很多,会涉及更多的参数设置,同时也需要更多的时间进行训练。

注意:

(文本数据)转换总是在两个特定的向量空间(Two Specific Vector Spaces)之间进行。必须使用相同的向量空间(即同一组特征id)进行模型训练和后续的向量转换。如果不能使用相同的输入特征空间(Input Feature Space),例如使用不同的字符串进行预处理,或者使用不同的特征ID,抑或本应使用TF-IDF向量却采用词袋表示来输入向量,这些“误操作”将产生转换期间的特征不匹配,进而导致错误的运行结果或产生异常。

step 2 -- 使用模型对词袋表示向量进行转换:

doc_bow = [(0, 3), (1, 5)]

print(tfidf[doc_bow])

[(0, 0.5144957554275265), (1, 0.8574929257125441)]

或者,直接对整个(训练)语料库进行特征转换:

corpus_tfidf = tfidf[corpus]

for doc in corpus_tfidf:

print(doc)

[(0, 0.4467512594633994), (1, 0.8935025189267988), (2, 0.045459441696222264)]
[(2, 0.07982263066186342), (3, 0.38329103210095783), (4, 0.48098603643475885), (5, 0.7844544378738532)]
[(2, 0.025128868703899597), (6, 0.24695318119778994), (7, 0.6849754251993109), (8, 0.6849754251993109)]
[(2, 0.07982263066186342), (3, 0.38329103210095783), (4, 0.48098603643475885), (9, 0.7844544378738532)]
[(2, 0.0910460341905888), (3, 0.43718339178067905), (5, 0.8947520894690928)]
[(1, 0.6668011702142979), (2, 0.06785075201967737), (3, 0.32580465658435587), (9, 0.6668011702142979)]
[(4, 0.6962169034343767), (6, 0.5677404313752555), (10, 0.4392639593161345)]
[(0, 1.0)]
[(2, 0.20388162893651843), (3, 0.9789955471717897)]
[(2, 0.16371704169295062), (4, 0.9865073391816752)]
[(2, 0.13039433685974838), (10, 0.9914622115415728)]

[(2, 0.06394369208554566), (10, 0.4862002131078655), (11, 0.8715047659171663)]

可以看到,每个转换后的语句中,单个词汇的表示由整数型数值的词汇计数转变成了浮点型的词汇权重。该权重表示字词对于该语句的重要性程度,数值越大,则重要性程度越高,反之越小,对于其原理,可以进行如此直觉性的理解:

字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在 语料库 中出现的频率成反比下降。

比如,示例语料库中的第一句话 --- ' 商业新知:知识图谱为内核,构建商业创新服务完整生态。 ',它原先可由词袋模型表征为

[(0, 1), (1, 2), (2, 1)]

经过 TF-IDF转换模型转换后则变为:

[(0, 0.4467512594633994), (1, 0.8935025189267988), (2, 0.045459441696222264)]

请注意,这里0,1,2在字典中分别对应‘创新'、'商业'、'知识图谱' 这3个词汇,根据这3个词的权重大小可知,对于这句话,最重要(最能代表这句话含义)的词汇是“商业”,其次是“创新”,最次是“知识图谱”。这很符合直觉:这12句话中都包含“知识图谱”,因此该词对各个文档/语句的代表性很弱。

此外,因为是示例数据,我们用这12个文档训练出TF-IDF模型后,又用这训练出来的模型对这12个文档的词袋表示进行转换。但在实际应用中,该模型可以对训练语料之外的语料/语句进行转换。当然,用于转换的语料/语句中的若干词汇不在模型的词汇表中,那么该语料/语句的部分信息会缺失。所以说,实际任务中,训练语料能大则大,绝对是“大力出奇迹”!

注意:

调用 model[corpus] 在已有的语料库文档流上创建一个包装器(Wrapper) --- 实际的文本数据转换在文档迭代期间即时完成(Done on-the-Fly)。我们无法在调用 corpus_transformed = model [corpus] 时转换整个语料库 --- 因为这意味着结果将会存储在本地内存中,这与gensim的内存独立(Memory-Independence)的目标相悖。如果你将多次迭代待转换的corpus_transformed,且转换代价较高,请先将生成的语料库序列化(Serialize)到本地,以便后续使用。

转换后的结果也可以序列化,它将一层层嵌套。

step 3 --- 基于前面的特征,进行LSI模型构建

lsi = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=3) # 初始化 LSI 转换

corpus_lsi = lsi[corpus_tfidf] #在原始语料词袋表示的基础上创建一个双包装器(Double Wrapper):bow-> tfidf-> lsi

2019-05-09 10:16:29,942 : INFO : using serial LSI version on this node
2019-05-09 10:16:29,947 : INFO : updating model with new documents
2019-05-09 10:16:29,950 : INFO : preparing a new chunk of documents
2019-05-09 10:16:29,951 : INFO : using 100 extra samples and 2 power iterations
2019-05-09 10:16:29,951 : INFO : 1st phase: constructing (12, 103) action matrix
2019-05-09 10:16:29,989 : INFO : orthonormalizing (12, 103) action matrix
2019-05-09 10:16:30,045 : INFO : 2nd phase: running dense svd on (12, 12) matrix
2019-05-09 10:16:30,061 : INFO : computing the final decomposition
2019-05-09 10:16:30,061 : INFO : keeping 3 factors (discarding 45.442% of energy spectrum)
2019-05-09 10:16:30,171 : INFO : processed documents up to #12
2019-05-09 10:16:30,175 : INFO : topic #0(1.715): -0.590*"数据" + -0.540*"技术" + -0.406*"金融" + -0.316*"一文" + -0.169*"商业" + -0.163*"企业" + -0.160*"知识图谱" + -0.109*"分析" + -0.041*"创新" + -0.036*"转型"
2019-05-09 10:16:30,176 : INFO : topic #1(1.382): 0.565*"企业" + 0.449*"数据" + -0.385*"商业" + -0.351*"技术" + 0.217*"分析" + -0.216*"创新" + -0.215*"一文" + 0.208*"转型" + -0.146*"金融" + 0.038*"管理"
2019-05-09 10:16:30,178 : INFO : topic #2(1.302): 0.580*"商业" + 0.468*"创新" + -0.444*"金融" + 0.330*"企业" + 0.264*"一文" + -0.198*"技术" + 0.150*"转型" + 0.075*"分析" + 0.026*"数据" + 0.018*"知识图谱"

在这里,我们通过潜在语义索引(Latent Semantic Indexing)( http://en.wikipedia.org/wiki/Latent_semantic_indexing)  将前面转换得到的TF-IDF语料库转换到潜在的3-D空间(3-D因为笔者在这里设置了num_topics = 3)。现在你可能想知道:这3个潜在的维度代表什么?让我们用 models.LsiModel.show_topics() 一探究竟:

lsi.show_topics()
[(0,
'-0.590*"数据" + -0.540*"技术" + -0.406*"金融" + -0.316*"一文" + -0.169*"商业" + -0.163*"企业" + -0.160*"知识图谱" + -0.109*"分析" + -0.041*"创新" + -0.036*"转型"'),
(1,
'0.565*"企业" + 0.449*"数据" + -0.385*"商业" + -0.351*"技术" + 0.217*"分析" + -0.216*"创新" + -0.215*"一文" + 0.208*"转型" + -0.146*"金融" + 0.038*"管理"'),
(2,
'0.580*"商业" + 0.468*"创新" + -0.444*"金融" + 0.330*"企业" + 0.264*"一文" + -0.198*"技术" + 0.150*"转型" + 0.075*"分析" + 0.026*"数据" + 0.018*"知识图谱"')]

1.2 对LSI主题模型的结果进行解释

再看看语料库中的文档,并给每个文档加上序号,便于索引。根据上述主题及主题词构成,即可发现文档的主题归属:

  • 1 商业新知:知识图谱为内核,构建商业创新服务完整生态。

  • 2 如何更好利用知识图谱技术做反欺诈? 360金融首席数据科学家沈赟开讲。

  • 3 知识管理 | 基于知识图谱的国际知识管理领域可视化分析。

  • 4 一文详解达观数据知识图谱技术与应用。

  • 5 知识图谱技术落地金融行业的关键四步。

  • 6 一文读懂知识图谱的商业应用进程及技术背景。

  • 7 海云数据CPO王斌:打造大数据可视分析与AI应用的高科技企业。

  • 8 智能产业|《人工智能标准化白皮书2018》带来创新创业新技术标准。

  • 9 国家语委重大科研项目“中华经典诗词知识图谱构建技术研究”开题。

  • 10 最全知识图谱介绍:关键技术、开放数据集、应用案例汇总

  • 11 中译语通Jove Mind知识图谱平台 引领企业智能化发展。

  • 12 知识图谱:知识图谱赋能企业数字化转型,为企业升级转型注入新能量。

因为我们的语料库较小,方便起见,仅查看每个主题的前3个最具代表性的主题词。

根据LSI的原理可知,“数据”、“技术”和“金融”都是相关词(并且对第一个主题的方向贡献最大),可大体推测该主题跟数据技术在金融领域的应用有关,那么,文档2、5跟该主题的相关性最大;根据第二个主题的TOP3主题词(“企业”、“数据”、“商业”)可知,该主题主要谈论企业将数据应用于商业实践,那么,文档1、6、7、10、12跟该主题的相关性最大;以此类推,第三个主题讨论的主要是(借助数据技术)在商业领域的创新,尤其是金融方面的,那么,文档1、8跟该主题相关性最大。

由于LSI、LDA等主题模型在本质上属于软聚类(Soft Clustering),也就是说,每个主题上的概率就是文章对于这个主题的隶属度,同一个文档可能夹杂着多个主题,只是对应的各个主题的概率不同罢了。 上述文档对应的主题应该是混合的,每个主题的概率大小不尽相同,在实际应用中,我们一般找出其中概率最大的一个主题。

for doc in corpus_lsi: # bow->tfidf转换 和 tfidf->lsi转换实际上是在这里即时完成的

print(doc)

[(0, -0.17690867499072602), (1, -0.44016836447597885), (2, 0.7284335174782008)]
[(0, -0.821902042820486), (1, -0.03184788440523527), (2, -0.4098203903108002)]
[(0, -0.045384645077792767), (1, 0.10578780781807381), (2, 0.042559710380774426)]
[(0, -0.7515191768805072), (1, -0.08599404650088843), (2, 0.1452967034805242)]
[(0, -0.6136428537043512), (1, -0.28286688523868675), (2, -0.4818653950021932)]
[(0, -0.5104995586789475), (1, -0.5136313252286587), (2, 0.49976771121730945)]
[(0, -0.5441363960445108), (1, 0.6841975713452622), (2, 0.20580754225199666)]
[(0, -0.040719186823048786), (1, -0.21597858129605113), (2, 0.46786434413537753)]
[(0, -0.5608211518743773), (1, -0.3417930476335039), (2, -0.18966593031566448)]
[(0, -0.6084914634082519), (1, 0.44488378344921975), (2, 0.028910120373434968)]
[(0, -0.18200362025117117), (1, 0.5612899057224641), (2, 0.32933606191854775)]

[(0, -0.12032756763512721), (1, 0.4568857150530911), (2, 0.2925478388144471)]

TF-IDF和LDA等模型也可以用先前的方法进行本地化存储:

lsi.save(os.path.join(TEMP_FOLDER, 'model.lsi'))

lsi = models.LsiModel.load(os.path.join(TEMP_FOLDER, 'model.lsi'))

2019-05-09 10:16:46,340 : INFO : saving Projection object under C:\Users\hp\AppData\Local\Temp\model.lsi.projection, separately None
2019-05-09 10:16:46,345 : INFO : saved C:\Users\hp\AppData\Local\Temp\model.lsi.projection
2019-05-09 10:16:46,347 : INFO : saving LsiModel object under C:\Users\hp\AppData\Local\Temp\model.lsi, separately None
2019-05-09 10:16:46,348 : INFO : not storing attribute projection
2019-05-09 10:16:46,349 : INFO : not storing attribute dispatcher
2019-05-09 10:16:46,351 : INFO : saved C:\Users\hp\AppData\Local\Temp\model.lsi
2019-05-09 10:16:46,353 : INFO : loading LsiModel object from C:\Users\hp\AppData\Local\Temp\model.lsi
2019-05-09 10:16:46,356 : INFO : loading id2word recursively from C:\Users\hp\AppData\Local\Temp\model.lsi.id2word.* with mmap=None
2019-05-09 10:16:46,357 : INFO : setting ignored attribute projection to None
2019-05-09 10:16:46,360 : INFO : setting ignored attribute dispatcher to None
2019-05-09 10:16:46,361 : INFO : loaded C:\Users\hp\AppData\Local\Temp\model.lsi
2019-05-09 10:16:46,364 : INFO : loading LsiModel object from C:\Users\hp\AppData\Local\Temp\model.lsi.projection
2019-05-09 10:16:46,366 : INFO : loaded C:\Users\hp\AppData\Local\Temp\model.lsi.projection

看到这里,你可能会问:这些文档之间的相似度怎样?
如何利用LSI产生的文本特征,对给定文档的输入文档(不在模型的训练语料库中),根据文档间的语义相似性对检索结果进行相似度降序排列,并从中找到和输入文档最为相似的文档?
不要着急,笔者将会下面的文章中介绍基于LSI模型 文档相似性查询 (Similarity Queries Based LSI)。 此外 ,除了用于文档检索任务外,基于LSI模型(LSA和LDA也是一样)提取的文本特征可用于文本分类和文本聚类任务

最后,笔者在梳理下目前比较流行的 文本转换模型 ,它们都可以用gensim的接口实现。

2. Gensim中可用的几种文本数据转换模型(Available Transformations Model in Gensim)

gensim这个库中,有几种常见的词向量空间算法(Vector Space Model Algorithms),下面且听笔者娓娓道来:

2.1 词频-逆向文件频率(Term Frequency * Inverse Document Frequency)

TF-IDF模型需要一个基于词袋表示(Bag-of-Words  Representation )的 训练语料库来进行初始化。在数据转换期间,它采用向量作为输入并返回另一个具有相同维度的向量,只有在训练语料库中出现较少的特征(出现越少对文档的代表性就越强)才能增加该数值。因此,TF-IDF模型将整型向量转换为实值向量(比如[(1,2),(0,10),(4,2),(5,1)]转换为[(1,0.002),(0,0.121),(4,0.0401),(5,0.5241)]),且保持维度的数量不变。值得注意的是,该模型返回的结果还可以将得到的向量归一化为(欧几里得)单位长度,使(词汇权重)值介于0到1之间。

model = models.TfidfModel(corpus, normalize=True)

2.2 潜在语义索引(LSI)

LSI将文档从词袋表示( Bag-of-Words  Representation ,优先选择词袋表示,经大量实验,这样得到的效果较好)或者TF-IDF加权空间转换为较低维度的潜在向量空间。对于上面的示例语料库,我们只使用了3个潜在维度(Latent Dimensions),但在实际语料库处理中,建议将200-500的目标维度作为“黄金标准”[详情见参考资料1]。

model = models.LsiModel(corpus_tfidf, id2word=dictionary, num_topics=6)
2019-05-09 10:16:51,102 : INFO : using serial LSI version on this node
2019-05-09 10:16:51,103 : INFO : updating model with new documents
2019-05-09 10:16:51,105 : INFO : preparing a new chunk of documents
2019-05-09 10:16:51,107 : INFO : using 100 extra samples and 2 power iterations
2019-05-09 10:16:51,108 : INFO : 1st phase: constructing (12, 106) action matrix
2019-05-09 10:16:51,108 : INFO : orthonormalizing (12, 106) action matrix
2019-05-09 10:16:51,110 : INFO : 2nd phase: running dense svd on (12, 12) matrix
2019-05-09 10:16:51,111 : INFO : computing the final decomposition
2019-05-09 10:16:51,112 : INFO : keeping 6 factors (discarding 15.684% of energy spectrum)
2019-05-09 10:16:51,113 : INFO : processed documents up to #12
2019-05-09 10:16:51,115 : INFO : topic #0(1.715): 0.590*"数据" + 0.540*"技术" + 0.406*"金融" + 0.316*"一文" + 0.169*"商业" + 0.163*"企业" + 0.160*"知识图谱" + 0.109*"分析" + 0.041*"创新" + 0.036*"转型"
2019-05-09 10:16:51,116 : INFO : topic #1(1.382): -0.565*"企业" + -0.449*"数据" + 0.385*"商业" + 0.351*"技术" + -0.217*"分析" + 0.216*"创新" + 0.215*"一文" + -0.208*"转型" + 0.146*"金融" + -0.038*"知识"
2019-05-09 10:16:51,118 : INFO : topic #2(1.302): 0.580*"商业" + 0.468*"创新" + -0.444*"金融" + 0.330*"企业" + 0.264*"一文" + -0.198*"技术" + 0.150*"转型" + 0.075*"分析" + 0.026*"数据" + 0.018*"知识图谱"
2019-05-09 10:16:51,121 : INFO : topic #3(1.173): 0.561*"数据" + -0.553*"企业" + -0.386*"转型" + -0.326*"金融" + -0.272*"技术" + 0.179*"一文" + 0.095*"分析" + -0.073*"知识图谱" + -0.040*"创新" + 0.034*"知识"
2019-05-09 10:16:51,123 : INFO : topic #4(1.090): 0.685*"创新" + -0.499*"一文" + 0.421*"金融" + -0.221*"技术" + 0.163*"数据" + -0.097*"转型" + -0.095*"企业" + 0.069*"分析" + 0.045*"知识" + 0.045*"管理"

将模型训练得出的主题展示出来:

model.print_topics()
2019-05-09 10:16:53,259 : INFO : topic #0(1.715): 0.590*"数据" + 0.540*"技术" + 0.406*"金融" + 0.316*"一文" + 0.169*"商业" + 0.163*"企业" + 0.160*"知识图谱" + 0.109*"分析" + 0.041*"创新" + 0.036*"转型"
2019-05-09 10:16:53,261 : INFO : topic #1(1.382): -0.565*"企业" + -0.449*"数据" + 0.385*"商业" + 0.351*"技术" + -0.217*"分析" + 0.216*"创新" + 0.215*"一文" + -0.208*"转型" + 0.146*"金融" + -0.038*"知识"
2019-05-09 10:16:53,263 : INFO : topic #2(1.302): 0.580*"商业" + 0.468*"创新" + -0.444*"金融" + 0.330*"企业" + 0.264*"一文" + -0.198*"技术" + 0.150*"转型" + 0.075*"分析" + 0.026*"数据" + 0.018*"知识图谱"
2019-05-09 10:16:53,264 : INFO : topic #3(1.173): 0.561*"数据" + -0.553*"企业" + -0.386*"转型" + -0.326*"金融" + -0.272*"技术" + 0.179*"一文" + 0.095*"分析" + -0.073*"知识图谱" + -0.040*"创新" + 0.034*"知识"
2019-05-09 10:16:53,266 : INFO : topic #4(1.090): 0.685*"创新" + -0.499*"一文" + 0.421*"金融" + -0.221*"技术" + 0.163*"数据" + -0.097*"转型" + -0.095*"企业" + 0.069*"分析" + 0.045*"知识" + 0.045*"管理"
2019-05-09 10:16:53,267 : INFO : topic #5(1.003): -0.670*"知识" + -0.670*"管理" + -0.265*"分析" + 0.141*"数据" + -0.074*"技术" + 0.063*"创新" + 0.037*"转型" + -0.030*"商业" + 0.023*"企业" + -0.012*"知识图谱"
[(0,
'0.590*"数据" + 0.540*"技术" + 0.406*"金融" + 0.316*"一文" + 0.169*"商业" + 0.163*"企业" + 0.160*"知识图谱" + 0.109*"分析" + 0.041*"创新" + 0.036*"转型"'),
(1,
'-0.565*"企业" + -0.449*"数据" + 0.385*"商业" + 0.351*"技术" + -0.217*"分析" + 0.216*"创新" + 0.215*"一文" + -0.208*"转型" + 0.146*"金融" + -0.038*"知识"'),
(2,
'0.580*"商业" + 0.468*"创新" + -0.444*"金融" + 0.330*"企业" + 0.264*"一文" + -0.198*"技术" + 0.150*"转型" + 0.075*"分析" + 0.026*"数据" + 0.018*"知识图谱"'),
(3,
'0.561*"数据" + -0.553*"企业" + -0.386*"转型" + -0.326*"金融" + -0.272*"技术" + 0.179*"一文" + 0.095*"分析" + -0.073*"知识图谱" + -0.040*"创新" + 0.034*"知识"'),
(4,
'0.685*"创新" + -0.499*"一文" + 0.421*"金融" + -0.221*"技术" + 0.163*"数据" + -0.097*"转型" + -0.095*"企业" + 0.069*"分析" + 0.045*"知识" + 0.045*"管理"'),
(5,
'-0.670*"知识" + -0.670*"管理" + -0.265*"分析" + 0.141*"数据" + -0.074*"技术" + 0.063*"创新" + 0.037*"转型" + -0.030*"商业" + 0.023*"企业" + -0.012*"知识图谱"')]

LSI模型训练的独特之处在于: 我们可以在任何时间对模型进行 再次训练 ,只需提供更多用于 训练 的语料。它通过一种称为 在线训练/学习 增量训练/学习 (Online Training/Online Learning或者Incremental Training/Incremental Learning 的过程来完成,该过程对底层模型(Underlying Model)进行增量更新。由于这个特性,输入的文档流(Document Stream)甚至可能是无穷无尽的 --- 只要在LSI模型需要语料时再喂进新文档,对训练模型 保持 持续性的新文档输入。

增量学习的使用方法说明:

model.add_documents(another_tfidf_corpus) # 现在LSI模型已经在tfidf_corpus + 另一个tfidf_corpus上进行训练了

lsi_vec = model[tfidf_vec] # 将一个新文档转换到LSI空间,但不影响模型

model.add_documents(more_documents) # tfidf_corpus + another_tfidf_corpus + 更多的文档 lsi_vec = model[tfidf_vec]

详情请参阅 gensim.models.lsimodel 的接口文档,了解如何使LSI逐渐“忘记”源源不断的文档流中的陈旧信息。调节该接口中的一些参数可能会影响运行的速度、内存的使用率以及LSI算法的数值精度。

gensim在很多模型上使用了一种新颖的在线增量流分布式训练算法(Online Incremental Streamed Distributed Training Algorithm,相当拗口的说辞!),如果想了解该算法的细节,请参看结尾[参考资料5]中的论文。

2.3 随机映射(Random Projections)

RP算法旨在减少向量空间的维度。这是一种非常有效的(对内存和CPU友好)方法,通过加入一点随机性来近似表示文档之间的TF-IDF距离。比较推荐的目标维度最好是几百/几千,具体数值取决于语料库的大小。

model = models.RpModel(corpus_tfidf, num_topics=3)
2019-05-09 10:16:56,243 : INFO : no word id mapping provided; initializing from corpus, assuming identity
2019-05-09 10:16:56,248 : INFO : constructing (3, 12) random matrix
model.num_topics #主题数有多少?
model.num_terms  #主题模型中参与训练的词汇数有多少?

12

2.4 隐狄利克雷分配模型(Latent Dirichlet Allocation, LDA)

LDA是另一种从词袋表示转变为低维度主题空间的文本数据转换模型。LDA是LSA(也称为多项PCA)的概率扩展(Probabilistic Extension),因此LDA的主题可以解释为词汇的概率分布。与LSA一样,这些分布也是从训练语料库中自动推断出来的,不需要人为介入。文档又被解释为这些主题的(软)混合,这跟LSI和LSA一样。

model = models.LdaModel(corpus, id2word=dictionary, num_topics=3)
2019-05-09 10:17:01,014 : INFO : using symmetric alpha at 0.3333333333333333
2019-05-09 10:17:01,017 : INFO : using symmetric eta at 0.3333333333333333
2019-05-09 10:17:01,018 : INFO : using serial LDA version on this node
2019-05-09 10:17:01,020 : INFO : running online (single-pass) LDA training, 3 topics, 1 passes over the supplied corpus of 12 documents, updating model once every 12 documents, evaluating perplexity every 12 documents, iterating 50x with a convergence threshold of 0.001000
2019-05-09 10:17:01,021 : WARNING : too few updates, training might not converge; consider increasing the number of passes or iterations to improve accuracy
2019-05-09 10:17:01,112 : INFO : -3.650 per-word bound, 12.6 perplexity estimate based on a held-out corpus of 12 documents with 42 words
2019-05-09 10:17:01,113 : INFO : PROGRESS: pass 0, at document #12/12
2019-05-09 10:17:01,124 : INFO : topic #0 (0.333): 0.189*"技术" + 0.187*"知识图谱" + 0.167*"一文" + 0.104*"数据" + 0.098*"商业" + 0.075*"创新" + 0.039*"金融" + 0.033*"企业" + 0.027*"分析" + 0.027*"知识"
2019-05-09 10:17:01,125 : INFO : topic #1 (0.333): 0.281*"知识图谱" + 0.101*"企业" + 0.094*"技术" + 0.072*"转型" + 0.072*"管理" + 0.072*"知识" + 0.071*"商业" + 0.070*"数据" + 0.066*"金融" + 0.048*"创新"
2019-05-09 10:17:01,127 : INFO : topic #2 (0.333): 0.271*"数据" + 0.154*"企业" + 0.148*"分析" + 0.064*"知识图谱" + 0.054*"创新" + 0.052*"技术" + 0.047*"商业" + 0.044*"一文" + 0.043*"金融" + 0.041*"知识"
2019-05-09 10:17:01,128 : INFO : topic diff=1.179380, rho=1.000000

展示主题模型中的各个主体及其主题词分布情况:

model.show_topics()
[(0,
  '0.189*"技术" + 0.187*"知识图谱" + 0.167*"一文" + 0.104*"数据" + 0.098*"商业" + 0.075*"创新" + 0.039*"金融" + 0.033*"企业" + 0.027*"分析" + 0.027*"知识"'),
 (1,
  '0.281*"知识图谱" + 0.101*"企业" + 0.094*"技术" + 0.072*"转型" + 0.072*"管理" + 0.072*"知识" + 0.071*"商业" + 0.070*"数据" + 0.066*"金融" + 0.048*"创新"'),
 (2,
  '0.271*"数据" + 0.154*"企业" + 0.148*"分析" + 0.064*"知识图谱" + 0.054*"创新" + 0.052*"技术" + 0.047*"商业" + 0.044*"一文" + 0.043*"金融" + 0.041*"知识"')]

gensim这个库采用一种叫做在线学习(Online Learning)的策略实现,运行速度较快,它还可以以分布式模式(Distributed Mode)在计算机集群上运行,详情请参看参考文献[2]。

2.5 层次狄利克雷过程(Hierarchical Dirichlet Process, HDP)

HDP是一种非参数贝叶斯方法(跟其他的主题模型不同,它不需要事先确定主题的数量),它对于想偷懒的同学来说,简直是福音!以下是它的接口调用方法:

model = models.HdpModel(corpus, id2word=dictionary)
2019-05-09 10:17:05,932 : INFO : (0, '0.229*转型 + 0.181*管理 + 0.172*一文 + 0.107*知识 + 0.088*商业 + 0.085*知识图谱 + 0.052*技术 + 0.028*企业 + 0.026*分析 + 0.023*创新')
2019-05-09 10:17:05,936 : INFO : (1, '0.294*创新 + 0.158*转型 + 0.139*知识图谱 + 0.088*知识 + 0.075*金融 + 0.074*管理 + 0.060*商业 + 0.055*数据 + 0.037*一文 + 0.012*技术')
2019-05-09 10:17:05,938 : INFO : (2, '0.381*金融 + 0.140*知识 + 0.129*创新 + 0.103*技术 + 0.093*企业 + 0.050*数据 + 0.034*商业 + 0.031*分析 + 0.024*转型 + 0.006*一文')
2019-05-09 10:17:05,939 : INFO : (3, '0.239*知识 + 0.234*分析 + 0.180*金融 + 0.086*数据 + 0.084*创新 + 0.069*一文 + 0.041*知识图谱 + 0.038*转型 + 0.025*管理 + 0.002*商业')
2019-05-09 10:17:05,941 : INFO : (4, '0.250*转型 + 0.199*管理 + 0.167*技术 + 0.145*企业 + 0.069*商业 + 0.054*一文 + 0.042*知识图谱 + 0.021*创新 + 0.020*金融 + 0.018*数据')
2019-05-09 10:17:05,943 : INFO : (5, '0.205*技术 + 0.166*企业 + 0.124*商业 + 0.118*转型 + 0.107*数据 + 0.069*金融 + 0.068*创新 + 0.046*管理 + 0.034*一文 + 0.027*分析')
2019-05-09 10:17:05,944 : INFO : (6, '0.250*企业 + 0.163*金融 + 0.113*创新 + 0.099*知识 + 0.090*数据 + 0.057*转型 + 0.055*一文 + 0.044*商业 + 0.043*分析 + 0.043*管理')
2019-05-09 10:17:05,948 : INFO : (7, '0.311*一文 + 0.247*创新 + 0.129*金融 + 0.078*知识 + 0.073*商业 + 0.058*数据 + 0.038*技术 + 0.022*分析 + 0.015*管理 + 0.013*转型')
2019-05-09 10:17:05,949 : INFO : (8, '0.156*知识图谱 + 0.144*创新 + 0.142*转型 + 0.102*金融 + 0.089*商业 + 0.071*数据 + 0.059*知识 + 0.057*管理 + 0.056*企业 + 0.050*分析')
2019-05-09 10:17:05,951 : INFO : (9, '0.215*创新 + 0.191*技术 + 0.178*分析 + 0.094*知识 + 0.070*管理 + 0.063*企业 + 0.051*商业 + 0.038*金融 + 0.034*知识图谱 + 0.029*数据')
2019-05-09 10:17:05,952 : INFO : (10, '0.346*一文 + 0.164*商业 + 0.150*管理 + 0.110*分析 + 0.090*知识图谱 + 0.042*企业 + 0.033*数据 + 0.022*创新 + 0.022*技术 + 0.011*金融')
2019-05-09 10:17:05,953 : INFO : (11, '0.216*金融 + 0.165*商业 + 0.140*分析 + 0.082*知识图谱 + 0.079*转型 + 0.074*知识 + 0.068*数据 + 0.059*企业 + 0.042*创新 + 0.035*一文')
2019-05-09 10:17:05,955 : INFO : (12, '0.397*转型 + 0.120*创新 + 0.110*技术 + 0.101*分析 + 0.069*金融 + 0.057*商业 + 0.050*知识 + 0.028*知识图谱 + 0.025*一文 + 0.023*企业')
2019-05-09 10:17:05,956 : INFO : (13, '0.299*分析 + 0.274*一文 + 0.121*数据 + 0.087*创新 + 0.061*金融 + 0.059*企业 + 0.043*知识图谱 + 0.014*知识 + 0.014*管理 + 0.012*商业')
2019-05-09 10:17:05,958 : INFO : (14, '0.185*商业 + 0.144*创新 + 0.108*转型 + 0.100*管理 + 0.098*一文 + 0.092*分析 + 0.072*数据 + 0.060*金融 + 0.053*企业 + 0.036*技术')
2019-05-09 10:17:05,958 : INFO : (15, '0.235*转型 + 0.163*商业 + 0.140*企业 + 0.102*技术 + 0.074*数据 + 0.072*分析 + 0.067*管理 + 0.046*知识 + 0.039*一文 + 0.027*知识图谱')
2019-05-09 10:17:05,959 : INFO : (16, '0.165*商业 + 0.164*管理 + 0.159*分析 + 0.126*数据 + 0.109*创新 + 0.079*企业 + 0.066*知识图谱 + 0.041*技术 + 0.038*知识 + 0.029*一文')
2019-05-09 10:17:05,961 : INFO : (17, '0.204*管理 + 0.193*知识图谱 + 0.166*一文 + 0.163*转型 + 0.088*创新 + 0.048*知识 + 0.045*金融 + 0.038*商业 + 0.020*企业 + 0.016*数据')
2019-05-09 10:17:05,962 : INFO : (18, '0.225*企业 + 0.136*金融 + 0.136*技术 + 0.099*知识 + 0.098*商业 + 0.095*一文 + 0.078*创新 + 0.076*管理 + 0.034*知识图谱 + 0.019*分析')

2019-05-09 10:17:05,963 : INFO : (19, '0.232*企业 + 0.205*一文 + 0.121*技术 + 0.089*金融 + 0.076*数据 + 0.076*创新 + 0.075*转型 + 0.069*商业 + 0.017*管理 + 0.016*分析')

model.num_topics  # 该模型自动生成 主题数有多少?

20

展示 HDP 主题模型中的各个主题及其主题词分布情况:

model.show_topics()  #
[(0,
'0.229*转型 + 0.181*管理 + 0.172*一文 + 0.107*知识 + 0.088*商业 + 0.085*知识图谱 + 0.052*技术 + 0.028*企业 + 0.026*分析 + 0.023*创新 + 0.008*数据 + 0.000*金融'),
(1,
'0.294*创新 + 0.158*转型 + 0.139*知识图谱 + 0.088*知识 + 0.075*金融 + 0.074*管理 + 0.060*商业 + 0.055*数据 + 0.037*一文 + 0.012*技术 + 0.004*企业 + 0.004*分析'),
(2,
'0.381*金融 + 0.140*知识 + 0.129*创新 + 0.103*技术 + 0.093*企业 + 0.050*数据 + 0.034*商业 + 0.031*分析 + 0.024*转型 + 0.006*一文 + 0.005*知识图谱 + 0.004*管理'),
(3,
'0.239*知识 + 0.234*分析 + 0.180*金融 + 0.086*数据 + 0.084*创新 + 0.069*一文 + 0.041*知识图谱 + 0.038*转型 + 0.025*管理 + 0.002*商业 + 0.001*技术 + 0.001*企业'),
(4,
'0.250*转型 + 0.199*管理 + 0.167*技术 + 0.145*企业 + 0.069*商业 + 0.054*一文 + 0.042*知识图谱 + 0.021*创新 + 0.020*金融 + 0.018*数据 + 0.013*分析 + 0.003*知识'),
(5,
'0.205*技术 + 0.166*企业 + 0.124*商业 + 0.118*转型 + 0.107*数据 + 0.069*金融 + 0.068*创新 + 0.046*管理 + 0.034*一文 + 0.027*分析 + 0.019*知识图谱 + 0.017*知识'),
(6,
'0.250*企业 + 0.163*金融 + 0.113*创新 + 0.099*知识 + 0.090*数据 + 0.057*转型 + 0.055*一文 + 0.044*商业 + 0.043*分析 + 0.043*管理 + 0.039*知识图谱 + 0.004*技术'),
(7,
'0.311*一文 + 0.247*创新 + 0.129*金融 + 0.078*知识 + 0.073*商业 + 0.058*数据 + 0.038*技术 + 0.022*分析 + 0.015*管理 + 0.013*转型 + 0.010*知识图谱 + 0.006*企业'),
(8,
'0.156*知识图谱 + 0.144*创新 + 0.142*转型 + 0.102*金融 + 0.089*商业 + 0.071*数据 + 0.059*知识 + 0.057*管理 + 0.056*企业 + 0.050*分析 + 0.038*技术 + 0.037*一文'),
(9,
'0.215*创新 + 0.191*技术 + 0.178*分析 + 0.094*知识 + 0.070*管理 + 0.063*企业 + 0.051*商业 + 0.038*金融 + 0.034*知识图谱 + 0.029*数据 + 0.019*一文 + 0.017*转型'),
(10,
'0.346*一文 + 0.164*商业 + 0.150*管理 + 0.110*分析 + 0.090*知识图谱 + 0.042*企业 + 0.033*数据 + 0.022*创新 + 0.022*技术 + 0.011*金融 + 0.007*知识 + 0.002*转型'),
(11,
'0.216*金融 + 0.165*商业 + 0.140*分析 + 0.082*知识图谱 + 0.079*转型 + 0.074*知识 + 0.068*数据 + 0.059*企业 + 0.042*创新 + 0.035*一文 + 0.032*管理 + 0.009*技术'),
(12,
'0.397*转型 + 0.120*创新 + 0.110*技术 + 0.101*分析 + 0.069*金融 + 0.057*商业 + 0.050*知识 + 0.028*知识图谱 + 0.025*一文 + 0.023*企业 + 0.019*数据 + 0.001*管理'),
(13,
'0.299*分析 + 0.274*一文 + 0.121*数据 + 0.087*创新 + 0.061*金融 + 0.059*企业 + 0.043*知识图谱 + 0.014*知识 + 0.014*管理 + 0.012*商业 + 0.009*转型 + 0.009*技术'),
(14,
'0.185*商业 + 0.144*创新 + 0.108*转型 + 0.100*管理 + 0.098*一文 + 0.092*分析 + 0.072*数据 + 0.060*金融 + 0.053*企业 + 0.036*技术 + 0.032*知识 + 0.020*知识图谱'),
(15,
'0.235*转型 + 0.163*商业 + 0.140*企业 + 0.102*技术 + 0.074*数据 + 0.072*分析 + 0.067*管理 + 0.046*知识 + 0.039*一文 + 0.027*知识图谱 + 0.025*创新 + 0.010*金融'),
(16,
'0.165*商业 + 0.164*管理 + 0.159*分析 + 0.126*数据 + 0.109*创新 + 0.079*企业 + 0.066*知识图谱 + 0.041*技术 + 0.038*知识 + 0.029*一文 + 0.014*金融 + 0.011*转型'),
(17,
'0.204*管理 + 0.193*知识图谱 + 0.166*一文 + 0.163*转型 + 0.088*创新 + 0.048*知识 + 0.045*金融 + 0.038*商业 + 0.020*企业 + 0.016*数据 + 0.015*分析 + 0.004*技术'),
(18,
'0.225*企业 + 0.136*金融 + 0.136*技术 + 0.099*知识 + 0.098*商业 + 0.095*一文 + 0.078*创新 + 0.076*管理 + 0.034*知识图谱 + 0.019*分析 + 0.004*数据 + 0.001*转型'),
(19,

'0.232*企业 + 0.205*一文 + 0.121*技术 + 0.089*金融 + 0.076*数据 + 0.076*创新 + 0.075*转型 + 0.069*商业 + 0.017*管理 + 0.016*分析 + 0.012*知识图谱 + 0.012*知识')]

从上面的示例中可以看到,添加新的向量空间转换(Vetor Space Modle Transformations)(比如不同的加权策略)相当简单; 有关更多信息和示例,请参阅gensim的API参考或参阅各类库的源代码。

值得重申的是,这些都是独特的增量实现,不需要一次性将整个训练语料库载入到本地内存中。另外,如果你有多个CPU和较大的内存,你可以采用分布式计算,最大限度的提高计算效率。好了,打了这么多的基础以后,我们可以进入到第一个实际应用的环节 - 相似文本检索,给定一个待查语句和一系列的相关文档,从这些文档中找到和待查语句相似度最高的一个来。

在下一篇文章中,笔者会接着本次的主题,聊聊基于LSI模型抽取的文本特征进行文档相似性检索,也就是给定一个新文档,在已有的语料库中找到和它语义或主题最为相似的文档。

参考资料:
[1] Bradford. 2008. An empirical study of required dimensionality for large-scale latent semantic indexing applications.
[2] Hoffman, Blei, Bach. 2010. Online learning for Latent Dirichlet Allocation.
[3] Wang, Paisley, Blei. 2011. Online variational inference for the hierarchical Dirichlet process.
[4] Halko, Martinsson, Tropp. 2009. Finding structure with randomness.
[5] Řehůřek. 2011. Subspace tracking for Latent Semantic Analysis.

推荐阅读

这个NLP工具,玩得根本停不下来

征稿启示| 200元稿费+5000DBC(价值20个小时GPU算力)

文本自动摘要任务的“不完全”心得总结番外篇——submodular函数优化

Node2Vec 论文+代码笔记

模型压缩实践收尾篇——模型蒸馏以及其他一些技巧实践小结

中文命名实体识别工具(NER)哪家强?

学自然语言处理,其实更应该学好英语

斯坦福大学NLP组Python深度学习自然语言处理工具Stanza试用

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。

mYbYbmy.jpg!web

阅读至此了,分享、点赞、在看三选一吧:pray:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK