zoukankan      html  css  js  c++  java
  • Python NLPIR2016 与 wordcloud 结合生成中文词云

    前叙

    该博文继承之前的文章,进一步介绍NLPIR2016的使用,三个内容(利用NLPIR 的发现新词功能自动提取文本内的新词汇,解决worldcloud中英文混合只显示中文的问题,NLPIR与worldcloud结合生成词云)
    写作本博客需要一个小时,阅读需要十二分钟.

    使用 NLPIR2016 获取新词

    # 之前已经展示过的代码,介绍了NLPIR2016中获取新词的三个方式
    # 获得新词,第二个参数控制新词的个数,排名按照TF-IDF(term frequency–inverse document frequency)排序
    # 该功能可以和AddUserWord()方法配合使用,以更好地获取分词效果
    # strs1 = GetNewWords(text,c_int(10),[c_char_p, c_int, c_bool])
    # print strs1
    # 获得新词(从txt文件中),第二个参数控制新词的个数,排名按照TF-IDF(term frequency–inverse document frequency)排序
    # strs10 = GetFileNewWords(text,c_int(10),[c_char_p, c_int, c_bool])
    # print strs10
    # WindowsError: exception: access violation reading 0x0000000000000000
    # 获得关键词,第二个参数控制新词的个数,排名按照TF-IDF(term frequency–inverse document frequency)排序
    # strs2= GetKeyWords(text,c_int(10),[c_char_p, c_int, c_bool])
    # print strs2
    
    # 我们将在代码中利用内存文本发现新词的方法封装起来
    # 第一个参数是要加入而文本,第二个参数是获取的新词个数
    def getNewWordsByNLPIR(text, number):
        txt1 = GetNewWords(text, c_int(number), [c_char_p, c_int, c_bool])
        txt2 = txt1.split('#')
        txt3 = []
        txt4 = []
        txt5 = []
    
        for item2 in txt2:
            txt3.append(item2.encode('utf-8').split('/'))
            if txt3 != []:
                txt4.append(txt3)
            txt3 = []
        for i in txt4:
            for j in i:
                if j[0] != [] and j[0] != '':
                    txt5.append(j[0])
    
        return txt5
    #注意返回的是numpy的列表类型
    # 然后你就可以通过一个简单的循环将其添加进NLPIR的词典
    for item in NewWord
        AddUserWord(item)

    worldcloud 无法显示中文的问题

    1. 谈谈解决时的思考过程
      博主在写这篇博客时使用的是python2.7的,结果当NLPIR2016与wordcloud结合是,发现world只显示text中的英文,而不显示中文,而这和之前的结巴是不一样的,并非制定了字体就可以解决的.于是我便将整个程序运行过程中的编码格式都检查了一遍,最后确认每个环节都是utf-8的编码,而最后的输入worldcloud使用的是wordcloud.generate(text.encode(‘utf-8’)),但是结果还是不行.
      百般无奈之下,博主先停下先去读读其它书,便拿起一本数据清洗的书读,当我在读到其中一句话python2.x处理文本数据时最好在一开始读取文件的时候就设定好编码时,突然灵光一闪想到,即使使用了encode(‘utf-8’)难道其实内存中的编码格式还是不对?
      于是我试着使用codecs将text先存入硬盘,再按照utf-8读取出来,果然好了.但是很明显的代码真的很烂,但是我确实确定了确实是最后输入wordcloud的文本编码有问题,最起码并非真正的可用的utf-8编码(encode(‘utf-8’)并没有发挥作用),于是我试着直接将其替换为python内部使用的unicode对象,结果果然成功了.
    2. 原因与解决方案
    # 注意因为NLPIR2016在进行中文分词时会默认转换编码,所以输出的文本需要转化为utf-8的编码
    # 但是在python2.7中还能使用unicode(strs, encoding='utf8')将其转化为Unicode对象,而encode('utf-8')的是无法生效的.
    # 注意制定wordcloud的字体,否则中文可能显示乱码

    生成词云实例

    # - * - coding: utf - 8 -*-
    #
    # 作者:田丰(FontTian)
    # 创建时间:'2017/5/23'
    # 邮箱:fonttian@163.com
    # CSDN:http://blog.csdn.net/fontthrone
    
    from os import path
    from nlpir import *
    from scipy.misc import imread
    import matplotlib.pyplot as plt
    from wordcloud import WordCloud, ImageColorGenerator
    from ctypes import *
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    d = path.dirname(__file__)
    
    text_path = 'txt/lztest.txt'  # 设置要分析的文本路径
    stopwords_path = 'stopwordsstopwords1893.txt'  # 停用词词表
    text = open(path.join(d, text_path)).read()
    txt = seg(text)
    kw_list = []
    seg_list = []
    
    
    # 获得新词,第二个参数控制新词的个数,排名按照TF-IDF(term frequency–inverse document frequency排序
    # 该功能可以和AddUserWord()方法配合使用,以更好地获取分词效果
    
    # print strs1
    # print type(strs1)
    # 富山雅史/n_new/28.45#白王血裔/n_new/19.83#秘仪咒文/n_new/19.19#风纪委员会主席/n_new/15.30#龙族/n_new/14.48#龙类/n_new/13.79#龙族血裔/n_new/13.78#龙族血统/n_new/13.19#执行部/n_new/12.74#白王/n_new/12.68#炼金/n_new/11.75#
    # <type 'str'>
    
    def getNewWordsByNLPIR(text, number):
        txt1 = GetNewWords(text, c_int(number), [c_char_p, c_int, c_bool])
        txt2 = txt1.split('#')
        txt3 = []
        txt4 = []
        txt5 = []
    
        for item2 in txt2:
            txt3.append(item2.encode('utf-8').split('/'))
            if txt3 != []:
                txt4.append(txt3)
            txt3 = []
        for i in txt4:
            for j in i:
                if j[0] != [] and j[0] != '':
                    txt5.append(j[0])
    
        return txt5
    
    strs1 = getNewWordsByNLPIR(text, 10)
    for i in strs1:
        print i
    
    for t in txt:
        seg_list.append(t[0].encode('utf-8'))
    
    # 去除停用词
    def NLPIRclearText(seg_list):
        mywordlist = []
        liststr = "/ ".join(seg_list)
        f_stop = open(stopwords_path)
        try:
            f_stop_text = f_stop.read()
            f_stop_text = unicode(f_stop_text, 'utf-8')
        finally:
            f_stop.close()
        f_stop_seg_list = f_stop_text.split('
    ')
        for myword in liststr.split('/'):
            if not (myword.strip() in f_stop_seg_list) and len(myword.strip()) > 1:
                mywordlist.append(myword)
        return ''.join(mywordlist)
    
    
    # 去除完停用词的文本
    strs = NLPIRclearText(seg_list)
    # print s
    font_path = r'C:WindowsFontssimfang.ttf'  # 为worldcloud设置中文字体路径没
    
    # 设置词云属性
    wc = WordCloud(font_path=font_path,  # 设置字体
                   background_color="white",  # 背景颜色
                   max_words=200,  # 词云显示的最大词数
                   max_font_size=100,  # 字体最大值
                   random_state=42,
                   width=1000, height=860, margin=2,  # 设置图片默认的大小,但是如果使用背景图片的话,那么保存的图片大小将会
                   )
    
    # 因为NLPIR在处理中文时,会自动修改文本编码,所以在使用worldcloud时需要修改文本编码
    # 否则会造成:无法在wordcloud中显示NLPIR分词后的汉语词语,而只能显示其中的英文
    
    
    wc.generate(unicode(strs, encoding='utf8'))
    
    plt.imshow(wc)
    plt.axis("off")
    plt.show()
    
    wc.to_file('test001.png')
  • 相关阅读:
    webservice时间类型XMLGregorianCalendar和Date的转换
    webservice中jaxws:server 和jaxws:endpoint的区别
    使用CXF开发JAX-WS类型的WebService
    使用TCP/IP Monitor监视Soap协议
    Webservice优缺点总结
    WebService两种调用方法
    DOS命令运行java文件,批量引用jar包
    eclipse创建的maven项目无法部署到tomcat
    图片翻转效果
    掷骰子效果
  • 原文地址:https://www.cnblogs.com/fonttian/p/7294824.html
Copyright © 2011-2022 走看看