近 2 年多来,在系统精益化治理中,通过对设备故障文本的词频及分布规律缝隙,以及深耕多年的系统认识,做了一些比较复杂的系统改造工作,取得了一些别人没有实现的业绩。

不过,在业绩展示时,多数人员一看数据就翻过去,看都不看一样,囧!因此,用词云图来展示业绩是非常必要的。这里用自己的案例来做个演示。

导入函数库

# -*- coding: utf-8 -*-

import numpy as np              # numpy数据处理库
import pandas as pd

import codecs
import re                       # 正则表达式库
import jieba                    # 结巴分词
import jieba.posseg             # 词性获取
import jieba.analyse

# 设置时间变量,便于对存储的文件进行版本管理
import time
import datetime

对相关文本内容进行分词处理

本案例以某一文件的特定列内容进行分词处理为例;但在实际工作中,则可能是上千个包含5w+的文件,由于一般的办公电脑内存都不超过 4GB ,加载太多文件就需要考虑内存优化等一系列问题了,否则系统崩溃不说,还丢了中间版本的成果。网友说,一般地,pandas一次处理的文件不建议大于 100MB,特别是不建议大于 1GB。因此,内存管理、版本管理、数据清洗等复杂的操作,这里就不展开了。

这里演示的日志文件为 txt 格式,读取特定列内容进行分词,并连同原始数据一并保存为 csv 格式(方便调试过程中比对分词是否正确等)。

# 记录开始时间
tx1 = time.time()
tx2 = str(int(round(tx1 * 1000)))  # 时间戳字符串

# 开启并行分词模式(仅支持非 Windows 系统),参数为并行进程数
jieba.enable_parallel(3)

# 设定自定义词语组合
jieba.load_userdict("jieba_segmenter_dict.txt")

# 读取停用词数据(包括去除:区域名、常用调节词、无意义的编号/特殊符号等)
stopwords = pd.read_csv('jieba_stopword_dict.txt', encoding='utf8', names=['stopword'], index_col=False)
# 转化停用词列表
stop_list = stopwords['stopword'].tolist()

# TXT文件特征:事先已由 ANSI 转换为 UTF-8 格式,分隔符是 \t,默认无标题
# 加载TXT文件(header=None, names 表示添加标题、数量与 tab 数量相当;设置index_col=0避免首列被当做索引);read_table、read_csv 等效
f1=pd.read_csv('./EventTxt/EVENT20200627.txt', sep='\t', encoding='utf_8_sig', \
                index_col=0, header=None, \
                names=['序号','时间','路径','描述','操作信息','补充信息','主机','备注'])

# 生成分词
f1['分词'] =  f1['描述'].apply(lambda x : [i for i in jieba.cut(x) if i not in stop_list])  # 去除停用词
# print(stop_list[10])

# 保存处理后的文件
f1.to_csv("./t4-EventCsv/t4_" + str(count) + "_" + EVENT20200627 + ".csv", encoding='utf_8_sig')

# 显示行列数量
rowNum=f1.shape[0] #不包括表头
colNum=f1.columns.size
print("\n表" + str(count-1) + "\t" +str(rowNum) + " 行\t" + str(colNum)+ " 列")

# 抽样查看数据情况
print(f1['分词'].loc[20])

# 显示耗时时间
tx3 = time.time()
tm_cost = tx3 - tx1
print('{:.2f}'.format(tm_cost) + " s.")   # str(round(tm_cost,3))

上述涉及的分词、停用词字典内容暂时不分享,因为相关论文还没有发表,得等到论文发表了再公开吧。毕竟做词云图并不复杂,复杂的是数据如何清洗、权重识别等等,这绝对是考验基层工作经验的。
毫无疑问,那些比我会编程的厂家,为啥做不了我做的技改,最核心一点,就是因为我拥有他们从未拥有过的大量实际生产数据!

词频分析

  1. 导入相应的函数库
from PIL import Image               # 图像处理库       
import matplotlib.pyplot as plt     # 图像展示库(这里以plt代表库的全称)
from wordcloud import WordCloud     # 词云展示库
from imageio import imread

import collections                  # 词频统计库
import ast                          # 解决 pandas 读取的列的内容需要转换为 子列表的问题

# 重复调用
import time
import pandas as pd
  1. 进行词频分析
tx4 = time.time()   # 时间戳,计算耗时情况
tx4s = str(int(round(tx4 * 1000)))  # 时间戳字符串,文件标记,版本管理用

# 读入表格第 8 列(首行为标题),得到  DataFrame
fq1 = pd.read_csv('./t4-EventCsv/t4_1_EVENT20200628.csv', header=0, usecols=[8])
# print(fq1.dtypes)

# 将所有的分词合并
words = []
for content in fq1['分词']:
    words.extend(ast.literal_eval(content))   # 字符转列表,然后列表追加到新列表末尾

# 对汇总后的分词进行词频统计
fq2 = pd.DataFrame(words, columns=['分词汇总'])
result = pd.value_counts(fq2['分词汇总']) 

result.head(20)  # 不指明参数显示前 5 行,否则按指定参数显示

# 创建词频文件
result.to_csv("./t4-WordCloud/t4_wordcloud_" + tx4s + "_1_input.txt", header=0)
print("词频分析文件已保存。")

词云图绘制

  1. 上传相关的资源文件到代码可以访问的目录

背景图 China-map.jpg,去国家统计局官网下载的。
字体文件 simhei.ttf,在 Windows 系统目录中拷贝出来的。

  1. 词云图绘制
# 背景图
bg1=imread("../resource/China-map.jpg")

# 读取词频文件
with open("./t4-WordCloud/t4_wordcloud_" + tx4s + "_1_input.txt","r") as file:
    txt=file.read()

# 生成词云
wc_pic1=WordCloud(background_color="white",font_path='../resource/simhei.ttf',width=1800,height=1500,mask=bg1).generate(txt)

# 保存词云图到本地
wc_pic1.to_file('./t4-WordCloud/t4_wordcloud_' + tx4s + '_2_output.png')
print("词云图片文件已保存。")

# 使用plt库显示图片
plt.imshow(wc_pic1)
plt.axis("off")
plt.show()

# 显示耗时时间
tx5 = time.time()
tm_cost = tx5 - tx4
print(str(round(tm_cost,3)) + " s.")

最终效果如下:

词云图效果演示

上仅做效果演示用,并非笔者的技改项目的最终成果;但未经许可,请勿使用,谢谢!