1 #!/usr/bin/python
2 # coding:utf8
3 """
4 Created on 2018-03-13
5 Updated on 2018-03-13
6 Author: 片刻
7 GitHub: https://github.com/apachecn/AiLearning
8 Coding: http://blog.csdn.net/github_36299736/article/details/54966460
9 通俗理解:https://blog.csdn.net/qq_39422642/article/details/78730662
10 """
11
12 import gensim
13 from gensim import corpora, models
14 from nltk.stem.porter import PorterStemmer
15 from nltk.tokenize import RegexpTokenizer
16 from stop_words import get_stop_words
17
18 # 创建示例文档
19 doc_a = "Brocolli is good to eat. My brother likes to eat good brocolli, but not my mother."
20 doc_b = "My mother spends a lot of time driving my brother around to baseball practice."
21 doc_c = "Some health experts suggest that driving may cause increased tension and blood pressure."
22 doc_d = "I often feel pressure to perform well at school, but my mother never seems to drive my brother to do better."
23 doc_e = "Health professionals say that brocolli is good for your health."
24 # 将示例文档编译成列表
25 doc_set = [doc_a, doc_b, doc_c, doc_d, doc_e]
26
27
28 # 创建PorterStemmer类的p_stemmer
29 p_stemmer = PorterStemmer()
30 # 分词:将文档转化为其原子元素
31 tokenizer = RegexpTokenizer(r'\w+')
32 # 创建英文停用词列表
33 en_stop = get_stop_words('en')
34
35 # print(p_stemmer.stem('boys')) # 输出boy
36
37
38 # 循环中标记的文档列表
39 texts = []
40 # 遍历文档列表
41 for i in doc_set:
42
43 # 清理并标记文档字符串
44 raw = i.lower()
45 tokens = tokenizer.tokenize(raw)
46 print(tokens)
47
48 # 从令牌中删除停用词(停用词处理:移除无意义的词)
49 stopped_tokens = [i for i in tokens if not i in en_stop]
50
51 # 词干令牌(词干提取:将同义词合并)
52 stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]
53 # 添加令牌列表
54 texts.append(stemmed_tokens)
55
56 # 把我们的标记文档转换成一个id <-> 词条字典
57 dictionary = corpora.Dictionary(texts)
58 print(dictionary.token2id) # 来查看每个单词的id
59 # print(dictionary.roken2id) # 显示 brocolli 的 id 是 0
60
61 # 将标记文档转换为文档术语矩阵
62 # doc2bow() 方法将 dictionary 转化为一个词袋
63 corpus = [dictionary.doc2bow(text) for text in texts]
64
65
66 # 生成LDA模型
67 """
68 LdaModel 类的详细描述可以在 gensim 文档中查看。我们的实例中用到的参数:
69
70 参数:
71 num_topics: 必须。LDA 模型要求用户决定应该生成多少个主题。由于我们的文档集很小,所以我们只生成三个主题。
72 id2word: 必须。LdaModel 类要求我们之前的 dictionary 把 id 都映射成为字符串。
73 passes: 可选。模型遍历语料库的次数。遍历的次数越多,模型越精确。但是对于非常大的语料库,遍历太多次会花费很长的时间。
74 """
75 # ldamodel = gensim.models.ldamodel.LdaModel(
76 # corpus, num_topics=3, id2word=dictionary, passes=20)
77
78 # print(dir(ldamodel))
79 # print(ldamodel.print_topics(num_topics=3, num_words=3))
80
81 """
82 这是什么意思呢?每一个生成的主题都用逗号分隔开。每个主题当中有三个该主题当中最可能出现的单词。即使我们的文档集很小,这个模型依旧是很可靠的。还有一些需要我们考虑的问题:
83
84 - health, brocolli 和 good 在一起时有很好的含义。
85 - 第二个主题有点让人疑惑,如果我们重新查看源文档,可以看到 drive 有很多种含义:driving a car 意思是开车,driving oneself to improve 是激励自己进步。这是我们在结果中需要注意的地方。
86 - 第三个主题包含 mother 和 brother,这很合理。
87
88 调整模型的主题数和遍历次数对于得到一个好的结果是很重要的。两个主题看起来更适合我们的文档。
89 """
90
91 lda = gensim.models.ldamodel.LdaModel(
92 corpus, num_topics=3, id2word=dictionary, passes=20)
93
94 print('-'*10)
95 print(lda.print_topics(num_topics=3, num_words=5)) # 各个主题的前num_words个主题词
96 print('-'*10)
97 print(lda[corpus[2]]) # 语料2属于各个主题的概率