[python] LDA处理文档主题分布及分词、词频、tfidf计算

        这篇文章主要是讲述如何通过LDA处理文本内容TXT,并计算其文档主题分布,主要是核心代码为主。其中LDA入门知识介绍参考这篇文章,包括安装及用法:
        [python] LDA处理文档主题分布代码入门笔记

        1.输入输出

        输入是test.txt文件,它是使用Jieba分词之后的文本内容,通常每行代表一篇文档。
        该文本内容原自博客:文本分析之TFIDF/LDA/Word2vec实践 ,推荐大家去阅读。

新春 备 年货 , 新年 联欢晚会
新春 节目单 , 春节 联欢晚会 红火
大盘 下跌 股市 散户
下跌 股市 赚钱
金猴 新春 红火 新年
新车 新年 年货 新春
股市 反弹 下跌
股市 散户 赚钱
新年 , 看 春节 联欢晚会
大盘 下跌 散户

        输出则是这十篇文档的主题分布,Shape(10L, 2L)表示10篇文档,2个主题。
        具体结果如下所示:

shape: (10L, 2L)
doc: 0 topic: 0
doc: 1 topic: 0
doc: 2 topic: 1
doc: 3 topic: 1
doc: 4 topic: 0
doc: 5 topic: 0
doc: 6 topic: 1
doc: 7 topic: 1
doc: 8 topic: 0
doc: 9 topic: 1

        同时调用 matplotlib.pyplot 输出了对应的文档主题分布图,可以看到主题Doc0、Doc1、Doc8分布于Topic0,它们主要描述主题新春;而Doc2、Doc3、Doc9分布于Topic1,主要描述股市。

        其过程中也会输出描述LDA运行的信息,如下图所示:

        2.核心代码

        其中核心代码如下图所示,包括读取文本、LDA运行、输出绘图等操作。

# coding=utf-8
import os
import sys
import numpy as np
import matplotlib
import scipy
import matplotlib.pyplot as plt
from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import HashingVectorizer 

if __name__ == "__main__":

    #存储读取语料 一行预料为一个文档
    corpus = []
    for line in open('test.txt', 'r').readlines():
        #print line
        corpus.append(line.strip())
    #print corpus

    #将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频
    vectorizer = CountVectorizer()
    print vectorizer

    X = vectorizer.fit_transform(corpus)
    analyze = vectorizer.build_analyzer()
    weight = X.toarray()

    print len(weight)
    print (weight[:5, :5])

    #LDA算法
    print 'LDA:'
    import numpy as np
    import lda
    import lda.datasets
    model = lda.LDA(n_topics=2, n_iter=500, random_state=1)
    model.fit(np.asarray(weight))     # model.fit_transform(X) is also available
    topic_word = model.topic_word_    # model.components_ also works

    #文档-主题(Document-Topic)分布
    doc_topic = model.doc_topic_
    print("type(doc_topic): {}".format(type(doc_topic)))
    print("shape: {}".format(doc_topic.shape))

    #输出前10篇文章最可能的Topic
    label = []
    for n in range(10):
        topic_most_pr = doc_topic[n].argmax()
        label.append(topic_most_pr)
        print("doc: {} topic: {}".format(n, topic_most_pr))

    #计算文档主题分布图
    import matplotlib.pyplot as plt
    f, ax= plt.subplots(6, 1, figsize=(8, 8), sharex=True)
    for i, k in enumerate([0, 1, 2, 3, 8, 9]):
        ax[i].stem(doc_topic[k,:], linefmt='r-',
                   markerfmt='ro', basefmt='w-')
        ax[i].set_xlim(-1, 2)     #x坐标下标
        ax[i].set_ylim(0, 1.2)    #y坐标下标
        ax[i].set_ylabel("Prob")
        ax[i].set_title("Document {}".format(k))
    ax[5].set_xlabel("Topic")
    plt.tight_layout()
    plt.show()  

        同时如果希望查询每个主题对应的问题词权重分布情况如下:

    import matplotlib.pyplot as plt
    f, ax= plt.subplots(2, 1, figsize=(6, 6), sharex=True)
    for i, k in enumerate([0, 1]):         #两个主题
        ax[i].stem(topic_word[k,:], linefmt='b-',
                   markerfmt='bo', basefmt='w-')
        ax[i].set_xlim(-2,20)
        ax[i].set_ylim(0, 1)
        ax[i].set_ylabel("Prob")
        ax[i].set_title("topic {}".format(k))  

    ax[1].set_xlabel("word")  

    plt.tight_layout()
    plt.show()

        运行结果如下图所示:共2个主题Topics,15个核心词汇。


        绘图推荐文章:http://blog.csdn.net/pipisorry/article/details/37742423
        PS:讲到这里,整个完整的LDA算法就算结束了,你可以通过上面的代码进行LDA主题分布的计算,下面是一些问题。

        3.TFIDF计算及词频TF计算

        特征计算方法参考:Feature Extraction - scikit-learn

    #计算TFIDF
    corpus = []

    #读取预料 一行预料为一个文档
    for line in open('test.txt', 'r').readlines():
        #print line
        corpus.append(line.strip())
    #print corpus

    #将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频
    vectorizer = CountVectorizer()

    #该类会统计每个词语的tf-idf权值
    transformer = TfidfTransformer()

    #第一个fit_transform是计算tf-idf 第二个fit_transform是将文本转为词频矩阵
    tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))

    #获取词袋模型中的所有词语
    word = vectorizer.get_feature_names()

    #将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
    weight = tfidf.toarray()

    #打印特征向量文本内容
    print 'Features length: ' + str(len(word))
    for j in range(len(word)):
        print word[j]

    #打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
    for i in range(len(weight)):
        for j in range(len(word)):
            print weight[i][j],
        print '\n'

        输出如下图所示,共统计处特征词15个,对应TF-IDF矩阵,共10行数据对应txt文件中的10个文档,每个文档15维数据,存储TF-IDF权重,这就可以通过10*15的矩阵表示整个文档权重信息。

Features length: 15
下跌 反弹 大盘 年货 散户 新年 新春 新车 春节 红火 联欢晚会 股市 节目单 赚钱 金猴

0.0 0.0 0.0 0.579725686076 0.0 0.450929562568 0.450929562568 0.0 0.0 0.0 0.507191470855 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.356735384792 0.0 0.458627428458 0.458627428458 0.401244805261 0.0 0.539503693426 0.0 0.0
0.450929562568 0.0 0.579725686076 0.0 0.507191470855 0.0 0.0 0.0 0.0 0.0 0.0 0.450929562568 0.0 0.0 0.0
0.523221265036 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.523221265036 0.0 0.672665604612 0.0
0.0 0.0 0.0 0.0 0.0 0.410305398084 0.410305398084 0.0 0.0 0.52749830162 0.0 0.0 0.0 0.0 0.620519542315
0.0 0.0 0.0 0.52749830162 0.0 0.410305398084 0.410305398084 0.620519542315 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.482964462575 0.730404446714 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.482964462575 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.568243852685 0.0 0.0 0.0 0.0 0.0 0.0 0.505209504985 0.0 0.649509260872 0.0
0.0 0.0 0.0 0.0 0.0 0.505209504985 0.0 0.0 0.649509260872 0.0 0.568243852685 0.0 0.0 0.0 0.0
0.505209504985 0.0 0.649509260872 0.0 0.568243852685 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 

        但是在将TF-IDF用于LDA算法model.fit(np.asarray(weight))时,总是报错如下:
        TypeError: Cannot cast array data from dtype('float64') to dtype('int64') according to the rule 'safe'
        所以后来LDA我采用的是统计词频的方法进行的,该段代码如下:

    #存储读取语料 一行预料为一个文档
    corpus = []
    for line in open('test.txt', 'r').readlines():
        #print line
        corpus.append(line.strip())
    #print corpus

    #将文本中的词语转换为词频矩阵 矩阵元素a[i][j] 表示j词在i类文本下的词频
    vectorizer = CountVectorizer()

    #fit_transform是将文本转为词频矩阵
    X = vectorizer.fit_transform(corpus)

    #获取词袋模型中的所有词语
    word = vectorizer.get_feature_names()
    analyze = vectorizer.build_analyzer()
    weight = X.toarray()

    #打印特征向量文本内容
    print 'Features length: ' + str(len(word))
    for j in range(len(word)):
        print word[j], 

    #打印每类文本词频矩阵
    print 'TF Weight: '
    for i in range(len(weight)):
        for j in range(len(word)):
            print weight[i][j],
        print '\n'

    print len(weight)
    print (weight[:5, :5])

        输出如下所示:

Features length: 15
下跌 反弹 大盘 年货 散户 新年 新春 新车 春节 红火 联欢晚会 股市 节目单 赚钱 金猴 TF Weight:

0 0 0 1 0 1 1 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 1 1 1 0 1 0 0
1 0 1 0 1 0 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 1 1 0 0 1 0 0 0 0 1
0 0 0 1 0 1 1 1 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0 0 0 0 1 0 1 0
0 0 0 0 0 1 0 0 1 0 1 0 0 0 0
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 

10
[[0 0 0 1 0]
 [0 0 0 0 0]
 [1 0 1 0 1]
 [1 0 0 0 0]
 [0 0 0 0 0]]

        得到weight权重后,然后调用对应的算法即可执行不用的应用,如:
        import lda
        model = lda.LDA(n_topics=20, n_iter=500, random_state=1)
        model.fit(np.asarray(weight)) 
        from sklearn.cluster import KMeans  
        clf = KMeans(n_clusters=4)   #景区 动物 人物 国家  
        s = clf.fit(weight)  

        4.百度互动主题分布例子

        输入数据主要是前面讲述过的爬取百度百科、互动百科的景区、动物、人物、国家四类信息,具体如下所示:

        输出如下所示,共12行数据,其中doc0~doc2主题分布为topic1,其主题表示景区;doc3~doc5主题分布为topic3,其主题表示动物;doc6~doc8主题分布为topic0,其主题表示人物;doc9~doc11主题分布为topic2,其主题表示国家。

shape: (12L, 4L)
doc: 0 topic: 1
doc: 1 topic: 1
doc: 2 topic: 1
doc: 3 topic: 3
doc: 4 topic: 3
doc: 5 topic: 3
doc: 6 topic: 0
doc: 7 topic: 0
doc: 8 topic: 0
doc: 9 topic: 2
doc: 10 topic: 2
doc: 11 topic: 2

        讲到此处你也应该理解了LDA的基本用法和适用场景,你可以通过它进行新闻主题分布,同时再进行引文推荐、聚类算法等操作。
        总之,希望这篇基础性的文章对你有所帮助吧!还是那句话:
        虽然我写这类文章看起来很简单,尤其对于机器学习的大牛来说,感觉没什么实质内容;但是如果你刚接触这类知识,还是非常头疼的,想找到一个可运行的算法很困难。
        这也是为什么总感觉以前学习了一些原理或理论的东西,而实际应用不是很明白,这种感觉就像学游泳,在岸上看别人感觉什么都会了,但想要学会还是得下水,一步一步来,而我写的这类基础文章就相当于带你下水吧!后面你才能做些自己喜欢的算法和研究。
        最近真的很忙,同时我认识了一位很优秀的女生,总算迈出了人生最重要的一步,就是真正的勇敢的出去接触些异性朋友,这感觉非常不错的。同时学校工作那边仍然在等消息,真心想回家当一名软件相关的教师啊~
        最后附上最近朋友圈的一条信息:

        哎!感叹下时光吧,仅以此诗纪念这三年写博客的坚持和北理最后的四个月:
        但行好事,莫问前程。
        待随满天李桃,再追学友趣事。
        (By:Eastmount 2016-03-15 深夜3点  http://blog.csdn.net/eastmount/ )

时间: 2024-10-25 18:18:43

[python] LDA处理文档主题分布及分词、词频、tfidf计算的相关文章

[python] LDA处理文档主题分布代码入门笔记

以前只知道LDA是个好东西,但自己并没有真正去使用过.同时,关于它的文章也非常之多,推荐大家阅读书籍<LDA漫游指南>,最近自己在学习文档主题分布和实体对齐中也尝试使用LDA进行简单的实验.这篇文章主要是讲述Python下LDA的基础用法,希望对大家有所帮助.如果文章中有错误或不足之处,还请海涵~ 一. 下载安装 LDA推荐下载地址包括:其中前三个比较常用.        gensim下载地址:https://radimrehurek.com/gensim/models/ldamodel.ht

Python中的文档测试模块

  这篇文章主要介绍了Python中的文档测试模块,代码基于Python2.x版本,需要的朋友可以参考下 如果你经常阅读Python的官方文档,可以看到很多文档都有示例代码.比如re模块就带了很多示例代码: ? 1 2 3 4 >>> import re >>> m = re.search('(?<=abc)def', 'abcdef') >>> m.group(0) 'def' 可以把这些示例代码在Python的交互式环境下输入并执行,结果与文

python读取word文档的方法

  本文实例讲述了python读取word文档的方法.分享给大家供大家参考.具体如下: 首先下载安装win32com ? 1 2 3 4 5 6 from win32com import client as wc word = wc.Dispatch('Word.Application') doc = word.Documents.Open('c:/test') doc.SaveAs('c:/test.text', 2) doc.Close() word.Quit() 这种方式产生的text文档

Python开发者面向文档编程的正确姿势

概述 秦人不暇自哀,而后人哀之;后人哀之而不鉴之,亦使后人而复哀后人也! –论面向文档编程的重要性 如果想看见识一个人写代码的功力,注释其实是区分老司机和小鲜肉的一个显著的分界线(有没有观察到你们公司的领导基本都在开会或者写文档),通常情况下老司机的文档量与代码量是1:1的比例,而新人往往认为写完功能模块就已经可以完成任务了.生产环境中需要面对现实中大量复杂的业务逻辑和数据校验并与各方对接,文档质量和代码质量就被提升到了相同的高度.很多人没有写注释的习惯,大多数不是因为懒惰,一方面是没有意识到写

Lucene 3.6.2入门(14) SolrJ操作索引和搜索文档以及整合中文分词

package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.sol

Word文档中对表格中数据进行计算的方法

  Word文档中对表格中数据进行计算的方法          1.在表格的最后一个单元格中单击放置插入点光标,然后在"表格工具-布局"选项卡中单击"数据"组中的"公式"按钮,如图1所示. 图1 单击"公式"按钮 2.打开"公式"对话框,在"编号格式"下拉列表中选择公式结果的显示格式,在"粘贴函数"下拉列表中选择需要使用的函数,如图2所示.此时公式将被粘贴到"

使用PYTHON创建XML文档_python

当用GOOGLE查的时候,内容几乎都是一样的.但是你想要的东西,一个也没有.例如,我就找不到中国人写的如何使用PYTHON来创建一个XML文件.当然,直接用文件写的方式也能够达到同样的效果,但是毕竟容易出错,而且看起来不优雅.最后,我看了很多资料,终于明白如何使用PYTHON写一个XML文件了.以下就是一个简单的例子,这个例子是已经调试通过的,大家可以放心使用. 复制代码 代码如下: import xml.dom.minidom from xml.dom.DOMImplementation im

转一篇NGINX+UWSGI+PYTHON+DJANGO部署文档

高远弄的,,专业,明晓..感谢哈哈.   http://blog.csdn.net/tmpbook/article/details/42873667  

AI瑞文智力测验超美国人平均IQ,计算模型用类比推理解决视觉问题

作为广泛应用于无国界的智力/推理能力测试,瑞文标准推理测验可以测验一个人的观察力及推理能力.在此前一项广受争议的对超过 80 个国家和地区进行的 IQ 调查中,曾得出了所谓的"国家(和地区)平均 IQ".美国西北大学的研究团队开发出了一个新的模型,能够在标准智力测试中超过到美国人的平均 IQ 水平.这项研究构建了用类比推理解决视觉问题的模型,研究者表示:"目前绝大多关于视觉的 AI 研究都集中在对象识别或场景标记,而非推理.但是识别只有能够为后续推理所用才有其意义.我们的研究