7.3 主题模型应用实例

本章的前两节介绍了利用 gensim 以及 sklearn 库构建主题模型的方法,并且通过简单的例子演示了各个类及方法的调用方式,本节将使用 20 newsgroups 新闻数据集中的实际数据,利用 gensim 库相关类和方法,测试主题模型对于计算文档相似度以及文本聚类的效果。

7.3.1 加载数据

依然使用 sklearn 内建函数 fetch_20newsgroups 加载 20 newsgroups 新闻数据


In [1]:import sklearn
       from sklearn.datasets import fetch_20newsgroups
       dataset = fetch_20newsgroups(shuffle=True, random_state=1,remove=('headers', 'footers', 'quotes'))
       dataset
Out[1]:{'DESCR':None,
        'data': [u"Well i'm not sure …… It is unfortunate.\n",
                 u"\n\n\n\n\n\n\nYeah, …… III",
                 ...],
        'description':'the 20 newsgroups by date dataset',
        'filenames':array(['……'], dtype='|S97'),
        'target':array([17,  0, 17, ...,  9,  4,  9]),
        'target_names':['alt.atheism','comp.graphics',……'talk.politics.misc','talk.religion.misc']} # 新闻文本保存在键 “data” 对应的列表内,“target”对应新闻类型,“target_names”为不同新闻类型名称
In [2]:corpus=dataset["data"] # 抽取新闻文本
       len(corpus) # 查看新闻文本数
Out[2]:11314

7.3.2 文本数据预处理

(1)分词、小写

使用 NLTK 分词函数 word_tokenize 对新闻文本进行分词处理


In [3]:import nltk
       from nltk import word_tokenize
       corpus_token=[[word.lower() for word in word_tokenize(sent)] for sent in corpus]

(2)过滤停用词

直接使用 NLTK 提供的英文停用词词典


In [4]:from nltk.corpus import stopwords
       english_stopwords = stopwords.words("english")
       corpus_filter_stop=[[word for word in words if not word in english_stopwords] for words in corpus_token]

(3)过滤标点符号

使用自定义英文表单符号列表进行标点过滤


In [5]:english_punctuations = [',', '.', ':', ';', '?', '(', ')', '[', ']', '!', '@', '#', '%', '$', '*'] 
       corpus_filter_pun=[[word for word in words if not word in english_punctuations] for words in corpus_filter_stop]

(4)词干化处理

使用 nltk lancaster 模块下定义的 LancasterStemmer 类进行词干化处理


In [6]:from nltk.stem.lancaster import LancasterStemmer
       st = LancasterStemmer()
       corpus_stem=[[st.stem(word) for word in words] for words in corpus_filter_pun]
       # 查看部分预处理结果
       corpus_stem[:2]
Out[6]:[[u'wel',u"'m",u'sur',……,u'got',u'pow',u'unfortun'],
        [u'yeah',u'expect',u'peopl',……,u'bak',u'timmon',u'ii']]

7.3.3 文本数据结构化处理

利用 gensim 库 TfidfModel 类计算 TF-IDF 矩阵


In [7]:from gensim import corpora
       dictionary = corpora.Dictionary(corpus_stem)
       text = [dictionary.doc2bow(words) for words in corpus_stem]
       tfidf_model = models.TfidfModel(text) 
       text_tfidf = tfidf_model[text]

7.3.4 构建 LSI 模型,计算文本相似度

gensim 库 similarities 包的 docsim 模块定义了计算向量空间中文档集合相似度的类和函数,其中最重要的类就是 Similarity,该类可以为文档集合构建一个索引,只要指定一个文档,我们可以轻松的得知其余各个文档和该文档的相似程度。如果需要计算相似度的文档已经转化为 LSI 空间向量,需要用到的类是 MatrixSimilarity,该类初始化方式为:实例=MatrixSimilarity(corpus, num_best=None, dtype=, num_features=None, chunksize=256, corpus_len=None)

部分参数说明:

corpus:需要计算相似度为文档特征数据

num_best:输出的最相似的文档个数,若不指定,则返回全部文档的相似度

num_features:为文档特征数,如果不指定的话默认为传入文档的特征数,一般为字典长度或者主题模型主题数

get_similarities 方法用于返回指定文档的与全部文档的相似度,调用方式为:实例.get_similarities(query),参数 query 即为指定文档,也可同时传入多个文档,返回结果即为一个反映多个指定文档与全部文档相似度的二维表。但是 gensim 官方文档建议不要直接调用该方法,而是使用“实例[query]”的方式计算指定文档的相似度。

将上步计算得到的 TF-IDF 矩阵传入初始化的 MatrixSimilarity 类,构建文档相似度索引


In [8]:from gensim.similarities import MatrixSimilarity
       sim_index = MatrixSimilarity(text_lsi)
       # 输出第一篇文档与其他文档之间的相似度
       sim_index[text_lsi[0]]
Out[8]:array([ 1.        ,  0.1223305 ,  0.73435599, ...,  0.05217935,
               0.01776145,  0.16315971], dtype=float32)
In [9]:print list(enumerate(sim_index[text_lsi[0]])) # 利用 enumerate 返回以上结果的枚举形式,直观上看是返回了相似度和对应的文档序号
Out[9]:[(0, 1.0), (1, 0.1223305), (2, 0.73435599), ...,0.052179348), (11312, 0.017761454), (11313, 0.16315971)]
In [10]:sort_sims = sorted(enumerate(sim_index[text_lsi[0]]), key=lambda item: item[1],reverse=True)  # 利用 sorted 函数按照相似度从大到小排序
        print sort_sims[0:10]  # 输出最为相似的前 10 个文档编号及相似度
Out[10]:[(0, 1.0), (5519, 0.82798922), (3580, 0.82728314), (1405, 0.82274032), (6148, 0.82230043), (3668, 0.81276625), (8016, 0.80825418), (7875, 0.80753094), (3706, 0.80649906), (2632, 0.80520225)]
In [11]:for j in [i[0] for i in sort_sims[0:10]]:
            print j,"\n",corpus[j]   #输出原始文档内容,查看检索效果
Out[11]:0 
        Well i'm not sure about the story nad it did seem biased. What I disagree with is your statement that the U.S. Media is out to……It is unfortunate.

        5519 
        You are conveniently ommitting the fact that the Arab governments told the Arab citizens of Israel to leave Israel, join with the Arab armies so that……you claim to know so much about.

           Steve
        -- 
        ……
        ppear to be.  When you realize that you can't care for other people while you hate yourself you might actually begin to do some good.

查看以上输出的较为相似的 10 个文档内容,发现均有提及 Israels、Jews 、Nazi 等相关政治、人权话题。

results matching ""

    No results matching ""