python-3.x - 如何设置时间片——动态主题模型

标签 python-3.x nlp gensim lda topic-modeling

简介

目前我正在使用 Gensim 结合 pandas 和 numpy 来运行文档 NLP 计算。我想构建一个 LDA 序列模型来跟踪我们的主题如何随时间变化,但在语料库格式方面遇到了错误。

我正在尝试弄清楚如何为动态主题模型设置时间片。我正在使用LdaSeqModel这需要一个整数时间片。

数据

这是一个 csv:

data = pd.read_csv('CGA Jan17 - Mar19 Time Slice.csv', encoding = "ISO-8859-1");
documents = data[['TextForTopics']]
documents['index'] = documents.index

	       Month	Year	Begin Date	TextForTopics	                                      time_slice
0	march	2017	3/23/2017	request: the caller is requesting an appointme...	1

然后将其转换为名为 Bow_corpus 的元组数组:

[[(12, 2), (25, 1), (30, 1)], [(33, 1), (136, 1), (159, 1), (161, 1)], [(165, 1), (247, 2)], (326, 1), (354, 1), (755, 1), (821, 1)]]

所需输出

它应该为每个时间片打印一个主题分配。如果我输入 3 个主题和两个时间片,我应该将三个主题打印两次,以显示主题如何随时间演变。

[(0,
  '0.165*"enrol" + 0.108*"medicar" + 0.051*"form"),
(1,
  '0.303*"caller" + 0.290*"inform" + 0.031*"abl"),
(2,
  '0.208*"date" + 0.140*"effect" + 0.060*"medicaid"')]
[(0,
  '0.165*"enrol" + 0.108*"cats" + 0.051*"form"),
(1,
  '0.303*"caller" + 0.290*"puppies" + 0.031*"abl"),
(2,
  '0.208*"date" + 0.140*"elephants" + 0.060*"medicaid"')]

我尝试过的

这就是函数 - 弓语料库是一个元组数组

ldaseq = LdaSeqModel(corpus=bow_corpus, time_slice=[], num_topics=15, chunksize=1)

我已经尝试了这些 time_slices 的整数输入的每个版本,它们都会产生错误。前提是 time_slice 将表示每个时间片中的索引/行/文档的数量。例如,我的数据有 180 万行,如果我想要两个时间片,我会按时间对数据进行排序,并输入一个整数截止值,如 time_slice = [489234, 1310766]。所有输入都会产生此错误:

错误

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-5-e58059a7fb6f> in <module>
----> 1 ldaseq = LdaSeqModel(corpus=bow_corpus, time_slice=[], num_topics=15, chunksize=1)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\gensim\models\ldaseqmodel.py in __init__(self, corpus, time_slice, id2word, alphas, num_topics, initialize, sstats, lda_model, obs_variance, chain_variance, passes, random_state, lda_inference_max_iter, em_min_iter, em_max_iter, chunksize)
    186 
    187             # fit DTM
--> 188             self.fit_lda_seq(corpus, lda_inference_max_iter, em_min_iter, em_max_iter, chunksize)
    189 
    190     def init_ldaseq_ss(self, topic_chain_variance, topic_obs_variance, alpha, init_suffstats):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\gensim\models\ldaseqmodel.py in fit_lda_seq(self, corpus, lda_inference_max_iter, em_min_iter, em_max_iter, chunksize)
    275             # seq model and find the evidence lower bound. This is the E - Step
    276             bound, gammas = \
--> 277                 self.lda_seq_infer(corpus, topic_suffstats, gammas, lhoods, iter_, lda_inference_max_iter, chunksize)
    278             self.gammas = gammas
    279 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\gensim\models\ldaseqmodel.py in lda_seq_infer(self, corpus, topic_suffstats, gammas, lhoods, iter_, lda_inference_max_iter, chunksize)
    351             bound, gammas = self.inferDTMseq(
    352                 corpus, topic_suffstats, gammas, lhoods, lda,
--> 353                 ldapost, iter_, bound, lda_inference_max_iter, chunksize
    354             )
    355         elif model == "DIM":

~\AppData\Local\Continuum\anaconda3\lib\site-packages\gensim\models\ldaseqmodel.py in inferDTMseq(self, corpus, topic_suffstats, gammas, lhoods, lda, ldapost, iter_, bound, lda_inference_max_iter, chunksize)
    401         time = 0  # current time-slice
    402         doc_num = 0  # doc-index in current time-slice
--> 403         lda = self.make_lda_seq_slice(lda, time)  # create lda_seq slice
    404 
    405         time_slice = np.cumsum(np.array(self.time_slice))

~\AppData\Local\Continuum\anaconda3\lib\site-packages\gensim\models\ldaseqmodel.py in make_lda_seq_slice(self, lda, time)
    459         """
    460         for k in range(self.num_topics):
--> 461             lda.topics[:, k] = self.topic_chains[k].e_log_prob[:, time]
    462 
    463         lda.alpha = np.copy(self.alphas)

IndexError: index 0 is out of bounds for axis 1 with size 0

解决方案

我尝试返回文档并查看用作示例的 common_corpus 的格式,我的 Bow_corpus 的格式是相同的。我还尝试运行文档中的代码以查看它是如何工作的,但它也产生了相同的错误。我不确定问题是否是我的代码,但我希望是。

我还尝试通过手动将我的 csv 分成包含 time_slices 的 9 个 csv 并从中创建一个迭代语料库来弄乱文件格式,但这不起作用。我考虑过将 csv 的每一行转换为 txt 文件,然后像 David Beil 那样创建一个语料库,但这听起来毫无意义乏味,因为我已经有了一个迭代语料库。

最佳答案

我假设您正在单个数据框中工作。假设您想使用年作为时间单位。

  1. 要使 time_sliceldaseqmodel 正常工作,您需要 首先对数据帧进行升序排序,即从最旧到最新。
  2. 创建一个 time_slice 变量,以便稍后将其反馈到模型中
import numpy as np
uniqueyears, time_slices = np.unique(data.Year, return_counts=True) 
#takes all unique values in data.Year as well as how often they occur and returns them as an array.

print(np.asarray((uniqueyears, time_slices)).T) 
#see what youve made, technically you dont need this

返回(使用示例数据)

[[1992   28]
 [1993   18]
 [1994   25]
 [1995   18]
 [1996   44]
 [1997   38]
 [1998   30]]

这已经有效了很多年,如果你想要更细粒度,你可以采用相同的概念,只要你有正确的文档顺序(这就是 gensim 将它们连接到时间片的方式)。因此,例如,如果您想获取每月的切片,您可以将 2017 年 3 月的日期重写为 20173,将 2014 年 4 月的日期重写为 20174。实际上,只要您可以识别属于同一切片的文档,任何颗粒都可以。

关于python-3.x - 如何设置时间片——动态主题模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56909294/

相关文章:

python - 如何检查仅位置参数?

python-2.7 - 如何使用斯坦福NER(命名实体识别器)的python接口(interface)?

python - Scikit Learn TfidfVectorizer : How to get top n terms with highest tf-idf score

python - 使用 Mallet Perplexity 进行 Gensim 主题建模

python - PyCharm : No module named scipy. 稀疏中的 Gensim ImportError

python - Eclipse + PyDev 导入错误

mongodb - pymongo 数据库已经存在,但已经有不同的情况

Python - 多个迭代的排气图

python - 通过 Python 3 中的 wsgiref.simple_server 提供 JPG 文件 - "write() argument must be a bytes instance"

tags - OpenNLP 的德国 maxent 模型中使用了哪些标签集?