【火炉炼AI】机器学习042-NLP文本的主题建模

【火炉炼AI】机器学习042-NLP文本的主题建模

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, NLTK 3.3)

文本的主题建模时用NLP来识别文本文档中隐藏的某种模式的过程,可以发现该文档的隐藏主题,以便对文档进行分析。主题建模的实现过程是,识别出某文本文档中最有意义,最能表征主题的词来实现主题分类,即寻找文本文档中的关键词,通过关键词就可以识别出某文档的隐藏主题。


1. 准备数据集

本次所用的数据集存放在一个txt文档中,故而需要从txt文档中加载该文本内容,然后再对这些文本进行预处理。由于预处理的步骤比较多,故而此处建立一个class来完成数据的加载和预处理过程,也使得代码看起来更简洁,更通用。

# 准备数据集,建一个class来加载数据集,对数据进行预处理
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.stem.snowball import SnowballStemmer
from gensim import models, corpora

class DataSet:
    
    def __init__(self,txt_file_path):
        self.__txt_file=txt_file_path
    
    def __load_txt(self): # 从txt文档中加载文本内容,逐行读入
        with open(self.__txt_file,'r') as file:
            content=file.readlines() # 一次性将所有的行都读入
        return [line[:-1] for line in content] # 去掉每一行末尾的\n
    
    def __tokenize(self,lines_list): # 预处理之一:对每一行文本进行分词
        tokenizer=RegexpTokenizer('\w+') 
        # 此处用正则表达式分词器而不用word_tokenize的原因是:排除带有标点的单词
        return [tokenizer.tokenize(line.lower()) for line in lines_list]
    
    def __remove_stops(self,lines_list): # 预处理之二:对每一行取出停用词
        # 我们要删除一些停用词,避免这些词的噪声干扰,故而需要一个停用词表
        stop_words_list=stopwords.words('english')  # 获取英文停用词表
        return [[token for token in line if token not in stop_words_list]
                for line in lines_list] 
        # 这儿有点难以理解,lines_list含有的元素也是list,这一个list就是一行文本,
        # 而一行文本内部有N个分词组成,故而lines_list可以看出二维数组,需要用两层generator
    
    def __word_stemm(self,lines_list): # 预处理之三:对每个分词进行词干提取
        stemmer=SnowballStemmer('english')
        return [[stemmer.stem(word) for word in line] for line in lines_list]
    
    def prepare(self):
        '''供外部调用的函数,用于准备数据集'''
        # 先从txt文件中加载文本内容,再进行分词,再去除停用词,再进行词干提取
        stemmed_words=self.__word_stemm(self.__remove_stops(self.__tokenize(self.__load_txt())))
        # 后面的建模需要用到基于dict的词矩阵,故而先用corpora构建dict在建立词矩阵
        dict_words=corpora.Dictionary(stemmed_words)
        matrix_words=[dict_words.doc2bow(text) for text in stemmed_words]
        return dict_words, matrix_words 
    
    # 以下函数主要用于测试上面的几个函数是否运行正常
    def get_content(self):
        return self.__load_txt()
    
    def get_tokenize(self):
        return self.__tokenize(self.__load_txt())
    
    def get_remove_stops(self):
        return self.__remove_stops(self.__tokenize(self.__load_txt()))
    
    def get_word_stemm(self):
        return self.__word_stemm(self.__remove_stops(self.__tokenize(self.__load_txt())))

这个类是否运行正常,是否能够得到我们预期的结果了?可以用下面的代码来测试

# 检验上述DataSet类是否运行正常
dataset=DataSet("E:\PyProjects\DataSet\FireAI\data_topic_modeling.txt")

# 以下测试load_txt()函数是否正常
content=dataset.get_content()
print(len(content))
print(content[:3])

# 以下测试__tokenize()函数是否正常
tokenized=dataset.get_tokenize()
print(tokenized)

# 一下测试__remove_stops()函数是否正常
removed=dataset.get_remove_stops()
print(removed)

# 以下测试__word_stemm()函数是否正常
stemmed=dataset.get_word_stemm()
print(stemmed)

# 以下测试prepare函数是否正常
_,prepared=dataset.prepare()
print(prepared)

输出的运行结果比较长,可以看我的github源代码。


2. 构建模型,训练数据集

我们用LDA模型(Latent Dirichlet Allocation, LDA)做主题建模,如下:

# 获取数据集
dataset=DataSet("E:\PyProjects\DataSet\FireAI\data_topic_modeling.txt")
dict_words, matrix_words =dataset.prepare()

# 使用LDAModel建模
lda_model=models.ldamodel.LdaModel(matrix_words,num_topics=2,
                           id2word=dict_words,passes=25) 
# 此处假设原始文档有两个主题

上面的代码会建立LDAModel并对模型进行训练,需要注意,LDAModel位于gensim模块中,这个模块需要自己用pip install gensim来安装,安装之后才能使用。

LDAModel会计算每个单词的重要性,然后建立重要性计算方程,依靠此方程来给出预测主题。

如下代码可以打印出该重要性方程:

# 查看模型中最重要的N个单词
print('Most important words to topics: ')
for item in lda_model.print_topics(num_topics=2,num_words=5):
    # 此处只打印最重要的5个单词
    print('Topic: {}, words: {}'.format(item[0],item[1]))

-------------------------------------输---------出--------------------------------

Most important words to topics:
Topic: 0, words: 0.075"need" + 0.053"order" + 0.032"system" + 0.032"encrypt" + 0.032"work"
Topic: 1, words: 0.037
"younger" + 0.037"develop" + 0.037"promot" + 0.037"talent" + 0.037"train"

--------------------------------------------完-------------------------------------

########################小**********结###############################

1,一般机器学习项目需要我们自己处理的内容都是数据集方面,可以将数据集处理过程写成一个专门的class,比如上面我把文本预处理过程写在class里面,每一个函数代表一种预处理方式,这样条理清楚,具有一定通用性。

2,此处我们使用gensim模块中的LDAModel来做主题建模,gensim模块是一个非常有用的NLP处理工具,在文本内容分析中应用较多。

#################################################################


注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容