使用TF-IDF对文本集中的单篇文本制作词云

使用TF-IDF制作整个文档集的词云有不少人讲过,如何对文档集中的单篇文档制作TF-IDF词云,却很少人写过。参照别人的代码,自己花不少时间琢磨代码里的逻辑,改动后,终于能对文档集中的单篇文档制作TF-IDF词云了。

一、对文本进行分词、去标点,并将每篇文本分词后的结果存为一个列表元素,最终将整个文档集合表示成一个二维列表。
(1)导入Jieba分词工具

import os
import jieba

(2)文本路径

file_path = r'.\story'  ## 故事文件路径
dictionary = r'.\专名汇总.txt' ##专名词表路径
stop_path = r'.\stopwords.txt' ##停用词文件路径

(3)定义需被去除的标点,及读入停用词

split_chars = " …《》,、。?!;:“”‘’'\n\r-=—()().【】"
with open(stop_path, 'r', encoding = 'utf-8-sig') as f:
    stopwords = [s.strip() for s in f.readlines()]

(4)加载词典

jieba.load_userdict(dictionary)

(5)分词、去停用词,并将文档集合存为一个二维列表

storiesL = []  ##存储所有故事的列表
for i in range(1,41):
    story_path = os.path.abspath(os.path.join(file_path, 'S' + str(i) + '.txt'))
    with open(story_path, 'r', encoding = 'utf-8-sig') as f:
        text = f.read()
        text = text.replace('\n', ' ')
        for char in split_chars:
            text = text.replace(char, ' ')
        seg_text = jieba.cut(text, cut_all = False)    
        
        tempL = []   #装故事文本去除了停用词的词序列
        for word in seg_text:
            word = word.strip()
            if word not in stopwords:
                tempL.append(word)    
        
        storiesL.append(' '.join(tempL))   ##词云

二、制作单个文本的TF-IDF词云
(1)导入相关模块

from sklearn import feature_extraction
from sklearn.feature_extraction.text import TfidfTransformer  
from sklearn.feature_extraction.text import CountVectorizer  
from collections import defaultdict
#制作词云
from wordcloud import WordCloud, ImageColorGenerator
from PIL import Image
import matplotlib.pyplot as plt

(2)统计词袋中所有词的TF-IDF权重

tlist = storiesL
vectorizer=CountVectorizer()#该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
transformer = TfidfTransformer(smooth_idf = False)#该类会统计每个词语的tf-idf权值
tfidf = transformer.fit_transform(vectorizer.fit_transform(tlist))  #第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵  

word=vectorizer.get_feature_names()#获取词袋模型中的所有词语  
weight=tfidf.toarray()#将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重  (矩阵的列维度表示词汇总数) document*word

(3)配置词云对象参数

font_path = 'msyh.ttc'
wc = WordCloud(font_path=font_path,  # 设置字体
               background_color="white",  # 背景颜色
               max_words=100,  # 词云显示的最大词数
               stopwords=stopwords,
               max_font_size=100,  # 字体最大值
               width=1000, height=860, margin=2,# 设置图片默认的大小,但是如果使用背景图片的话,那么保存的图片大小将会按照其大小保存,margin为词语边缘距离
#               prefer_horizontal=1,
               )

(4)生成单个故事的TF-IDF词云

for i in range(40):
    filename = str(i+1)+'.png'
    tfidf_list = defaultdict(list)
    tfidf_avg = {}
    for j in range(len(word)):
        tfidf_list[word[j]].append(weight[i][j])
    
    for i,j in tfidf_list.items():
        tfidf_avg[i] = sum(j)/len(j)
    
    wc.generate_from_frequencies(tfidf_avg)
    plt.imshow(wc, interpolation="bilinear")
    plt.axis("off")
    wc.to_file(filename)  

本文的代码与其他对整个文本集生成TF-IDF词云的代码差异处就在这部分。对整个文本集生成TF-IDF在处理此部分的代码如下:

tfidf_list = defaultdict(list)
tfidf_avg = {}
for i in range(len(weight)):#打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for遍历某一类文本下的词语权重  
    for j in range(len(word)): 
        #获取每个词语对应的权重值
        tfidf_list[word[j]].append(weight[i][j]) ## tfidef_list为 词:列表 构成的键值对,word为总词数,document为列表的长度,该列表记录某个词在每个文件中的词频
#对每个词语求权重值平均
for i,j in tfidf_list.items():
    tfidf_avg[i] = sum(j)/len(j)

wc.generate_from_frequencies(tfidf_avg)
plt.imshow(wc, interpolation="bilinear")
plt.axis("off")
wc.to_file(filename)  

可以发现,在本文中,求平均 tf-idf值 的代码和制作词云的代码都是放在第一个for循环中,而制作整个文本集的词云时,这些操作是放在for循环外。

这里展示下其中一个单篇文本生成的词云:
使用TF-IDF对文本集中的单篇文本制作词云_第1张图片

你可能感兴趣的:(自然语言处理,python,机器学习,sklearn)