LDA模型运用

---恢复内容开始---

 

小项目:分析希拉里邮件主题

 

import numpy as np
import pandas as pd
import re

df = pd.read_csv("HillaryEmails.csv")
df.head(1)#发现df中有很多字段,最有用的还是 ExtractedBodyText内容,所以我们将提取该字段,并提出id,再dropna()

# 原邮件数据中有很多Nan的值,直接扔了。
df = df[['Id','ExtractedBodyText']].dropna()

 

文本预处理:

上过我其他NLP课程的同学都知道,文本预处理这个东西,对NLP是很重要的。

我们这里,针对邮件内容,写一组正则表达式:

def clean_email_text(text):

text = text.replace('\n'," ") #新行,我们是不需要的
text = re.sub(r"-", " ", text) #把 "-" 的两个单词,分开。(比如:july-edu ==> july edu)
text = re.sub(r"\d+/\d+/\d+", "", text) #日期,对主体模型没什么意义
text = re.sub(r"[0-2]?[0-9]:[0-6][0-9]", "", text) #时间,没意义
text = re.sub(r"[\w]+@[\.\w]+", "", text) #邮件地址,没意义
text = re.sub(r"/[a-zA-Z]*[:\//\]*[A-Za-z0-9\-_]+\.+[A-Za-z0-9\.\/%&=\?\-_]+/i", "", text) #网址,没意义
pure_text = ''
# 以防还有其他特殊字符(数字)等等,我们直接把他们loop一遍,过滤掉
for letter in text:
  # 只留下字母和空格
  if letter.isalpha() or letter==' ':
    pure_text += letter
# 再把那些去除特殊字符后落单的单词,直接排除。
# 我们就只剩下有意义的单词了。
text = ' '.join(word for word in pure_text.split() if len(word)>1)
return text

 好的,现在我们新建一个colum,并把我们的方法跑一遍:

docs = df['ExtractedBodyText']
docs = docs.apply(lambda s: clean_email_text(s))

好,来看看长相:

docs.head(1).values

array(['Thursday March PM Latest How Syria is aiding Qaddafi and more Sid hrc memo syria aiding libya docx hrc memo syria aiding libya docx March For Hillary'],
      dtype=object)

我们直接把所有的邮件内容拿出来。

doclist = docs.values

 

LDA模型构建:

好,我们用Gensim来做一次模型构建

首先,我们得把我们刚刚整出来的一大波文本数据

[[一条邮件字符串],[另一条邮件字符串], ...]

转化成Gensim认可的语料库形式:

[[一,条,邮件,在,这里],[第,二,条,邮件,在,这里],[今天,天气,肿么,样],...]

引入库:

from gensim import corpora, models, similarities
import gensim

import NLTK

 STOPWORDS = set(stopwords.words('english'))

 texts = [[word for word in doc.lower().split() if word not in STOPWORDS] for doc in doclist]

建立语料库

用词袋的方法,把每个单词用一个数字index指代,并把我们的原文本变成一条长长的数组:

dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)

我们可以看到,第10号分类,其中最常出现的单词是:

lda.print_topic(10, topn=5)

我们把所有的主题打印出来看看:

lda.print_topics(num_topics=20, num_words=5)

 

接下来:

通过

lda.get_document_topics(bow)

或者

lda.get_term_topics(word_id)

两个方法,我们可以把新鲜的文本/单词,分类成20个主题中的一个。

但是注意,我们这里的文本和单词,都必须得经过同样步骤的文本预处理+词袋化,也就是说,变成数字表示每个单词的形式。

---恢复内容结束---

posted @ 2018-12-17 09:41  慕云深  阅读(596)  评论(0)    收藏  举报