03.文本数据分析
学习目标
- 了解文本数据分析的作用。
- 掌握常用的几种文本数据分析方法。
文本数据分析的作用
文本数据分析能够有效帮助我们理解数据语料,快速检查出语料可能存在的问题,并指导之后模型训练过程中一些超参数的选择。
常用的几种文本数据分析方法
- 标签数量分布
- 句子长度分布
- 词频统计与关键词词云
说明:我们将基于真实的中文酒店评论语料来讲解常用的几种文本数据分析方法。
中文酒店评论语料
- 属于二分类的中文情感分析语料
- 该语料存放在
./cn_data
目录下。 - 其中
train.tsv
代表训练集,dev.tsv
代表验证集,二者数据样式相同。
train.tsv 数据样式
数据样式说明:
- 第一列数据代表具有感情色彩的评论文本
- 第二列数据,0或1,代表每条文本数据是积极或者消极的评论
- 0代表消极
- 1代表积极
sentence | label |
---|---|
早餐不好,服务不到位,晚餐无西餐,早餐晚餐相同,房间条件不好,餐厅不分吸烟区。房间不分有无烟房. |
0 |
去的时候,酒店大厅和餐厅在装修,感觉大厅有点挤。由于餐厅装修本来该享受的早饭,也没有享受 (他们是 8 点开始每个房间送,但是我时间来不及了) 不过前台服务员态度好 |
0 |
有很长时间没有在西藏大厦住了,以前去北京在这里住的较多。这次住进来发现换了液晶电视,但网络不是很好,他们自己说是收费的原因造成的。其它还好。 |
0 |
非常好的地理位置,住的是豪华海景房,打开窗户就可以看见栈桥和海景。记得很早以前也住过,现在重新装修了。总的来说比较满意,以后还会住 |
1 |
交通很方便,房间小了一点,但是干净整洁,很有香港的特色,性价比较高,推荐一下哦 |
1 |
酒店的装修比较陈旧,房间的隔音,主要是卫生间的隔音非常差,只能算是一般的 |
0 |
酒店有点旧,房间比较小,但酒店的位子不错,就在海边,可以直接去游泳。8 楼的海景打开窗户就是海。如果想住在热闹的地带,这里不是一个很好的选择,不过威海城市 |
1 |
位置很好,走路到文庙、清凉寺 5 分钟都用不了,周边公交车很多很方便,就是出租车不太爱去 (老城区路窄爱堵车),因为是老宾馆所以设施要陈旧些, |
1 |
酒店设备一般,套房里卧室的不能上网,要到客厅去。 |
0 |
条件不好,餐厅不分吸烟区。房间不分有无烟房. |
0 |
获得训练集和验证集的标签数量分布
# 导入必备工具包
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
# 设置显示风格
plt.style.use('fivethirtyeight')
# 分别读取训练tsv和验证tsv
train_data = pd.read_csv(r"D:\learn\000人工智能数据大全\nlp\NLP基础课所有数据和代码\cn_data\train.tsv", sep="\t")
valid_data = pd.read_csv(r"D:\learn\000人工智能数据大全\nlp\NLP基础课所有数据和代码\cn_data\dev.tsv", sep="\t")
# 获得训练数据标签数量分布
sns.countplot(x="label", data=train_data)
plt.title("train_data")
plt.show()
# 获取验证数据标签数量分布
sns.countplot(x="label", data=valid_data)
plt.title("valid_data")
plt.show()
训练集标签数量分布
- 图中展示了训练集中标签为 0 和 1 的样本数量分布,可直观了解正负样本的比例情况。
验证集标签数量分布

- 图中展示了验证集中标签为 0 和 1 的样本数量分布,与训练集分布对比可判断数据分布是否一致。
分析:
- 在深度学习模型评估中,我们一般使用ACC作为评估指标
- 若想将ACC的基线定义在50%左右,则需要正负样本比例维持在1:1左右
- 上图中训练和验证集正负样本都稍有不均衡,可以进行一些数据增强
句子长度分布
# 在训练数据中添加新的句子长度列
train_data["sentence_length"] = list(map(lambda x: len(x), train_data["sentence"]))
#map(function, iterable) 将函数 function 应用到 iterable 的每个元素上。这里,它将 lambda x: len(x) 应用到 train_data["sentence"] 的每个句子上,生成一个包含所有句子长度的迭代器。
#其实上面代码可以将lambda省略,写成:train_data["sentence_length"] = list(map(len, train_data["sentence"]))
# 绘制句子长度列的数量分布图
sns.countplot(x="sentence_length", data=train_data)
plt.xticks([])
plt.show()
# 绘制dis长度分布图
sns.displot(train_data["sentence_length"])
plt.yticks([])
plt.show()
# 在验证数据中添加新的句子长度列
valid_data["sentence_length"] = list(map(lambda x: len(x), valid_data["sentence"]))
# 绘制句子长度列的数量分布图
sns.countplot(x="sentence_length", data=valid_data)
plt.xticks([])
plt.show()
# 绘制dis长度分布图
sns.displot(valid_data["sentence_length"])
plt.yticks([])
plt.show()
训练集句子长度分布
验证集句子长度分布

分析:
- 通过绘制句子长度分布图,可以得知语料中大部分句子长度的分布范围
- 模型的输入要求为固定尺寸的张量,合理的长度范围对之后进行句子截断补齐(规范长度)起到关键指导作用
- 上图中大部分句子长度的范围大致为20-250之间
训练集和验证集的正负样本长度散点分布
# 绘制训练集长度分布的散点图
sns.stripplot(y='sentence_length', x='label', data=train_data)
plt.show()
# 绘制验证集长度分布的散点图
sns.stripplot(y='sentence_length', x='label', data=valid_data)
plt.show()
训练集正负样本的长度散点分布
验证集正负样本的长度散点分布

分析:
- 通过查看正负样本长度散点图,可以有效定位异常点的出现位置
- 帮助我们更准确进行人工语料审查
- 上图中在训练集正样本中出现了异常点,它的句子长度近3500左右,需要我们人工审查
训练集与验证集不同词汇总数统计
# 导入jieba用于分词
# 导入chain方法用于扁平化列表
import jieba
from itertools import chain
# 进行训练集的句子进行分词,并统计出不同词汇的总数
train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"])))
print("训练集共包含不同词汇总数为:", len(train_vocab))
# 进行验证集的句子进行分词,并统计出不同词汇的总数
valid_vocab = set(chain(*map(lambda x: jieba.lcut(x), valid_data["sentence"])))
print("验证集共包含不同词汇总数为:", len(valid_vocab))
*map(...):
map 对象解包为多个独立参数,传递给函数或可迭代上下文。
- 不解包时:
map
本身是一个迭代器,不能直接查看内容(打印会显示<map object>
)。- 解包时:将
map
的每个元素作为单独的参数传递(例如func(*map)
相当于func(elem1, elem2, ...)
)。- 不生成中间列表,适合内存敏感的场景。
nums = [1, 2, 3] # 解包 map 作为多个参数传递给 chain from itertools import chain combined = chain(*map(lambda x: [x, x+1], nums)) # 相当于 chain([1,2], [2,3], [3,4]) print(list(combined)) # 输出:[1, 2, 2, 3, 3, 4]
特性 list(map(...))
*map(...)
返回值类型 列表( list
)解包后的多个参数(无单独类型) 内存占用 生成完整列表,占用内存 惰性迭代,不生成中间列表 用途 需要多次访问结果时 直接传递结果给函数或扁平化操作 可重用性 可多次遍历(列表保存结果) 只能迭代一次( map
是迭代器)
输出效果
训练集共包含不同词汇总数为: 12147
验证集共包含不同词汇总数为: 6857
获得训练集正负样本高频形容词词云
# 使用jieba中的词性标注功能
import jieba.posseg as pseg
# 导入chain方法用于扁平化列表
from itertools import chain
import matplotlib.pyplot as plt
import pandas as pd
# 导入绘制词云的工具包
from wordcloud import WordCloud
# 筛选目标语句中所有的形容词
def get_a_list(text):
"""用于获取形容词列表"""
# 使用jieba的词性标注方法切分文本,获得具有词性属性flag和词汇属性word的对象,
# 从而判断flag是否为形容词,来返回对应的词汇
r = []
for g in pseg.lcut(text):
if g.flag == "a":
r.append(g.word)
return r
#绘制词云
def get_word_cloud(keywords_list):
# 实例化绘制词云的类,其中参数font_path是字体路径,为了能够显示中文,
# max_words指词云图像最多显示多少个词,background_color为背景颜色
wordcloud = WordCloud(font_path=r"C:\Users\luzhanshi\AppData\Local\Microsoft\Windows\Fonts\simhei.ttf",max_words=100, background_color="white")
# 将传入的列表转化成词云生成器需要的字符串形式
keywords_string = " ".join(keywords_list)
# 生成词云
wordcloud.generate(keywords_string)
# 绘制图像并显示
plt.figure()
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.show()
# 分别读取训练tsv和验证tsv
train_data = pd.read_csv(r"D:\learn\000人工智能数据大全\nlp\NLP基础课所有数据和代码\cn_data\train.tsv", sep="\t")
valid_data = pd.read_csv(r"D:\learn\000人工智能数据大全\nlp\NLP基础课所有数据和代码\cn_data\dev.tsv", sep="\t")
# 获得训练集上正样本
p_train_data = train_data[train_data["label"] == 1]["sentence"]
# 对正样本的每个句子提取形容词
train_p_a_vocab = chain(*map(lambda x: get_a_list(x), p_train_data))
# 获得训练集上负样本
n_train_data = train_data[train_data["label"] == 0]["sentence"]
# 对负样本的每个句子提取形容词
train_n_a_vocab = chain(*map(lambda x: get_a_list(x), n_train_data))
# 调用绘制词云函数
get_word_cloud(train_p_a_vocab)
get_word_cloud(train_n_a_vocab)
训练集正样本形容词词云
训练集负样本形容词词云

获得验证集正负样本形容词词云
# 获得验证集上正样本
p_valid_data = valid_data[valid_data["label"] == 1]["sentence"]
# 对正样本的每个句子提取形容词
valid_p_a_vocab = chain(*map(lambda x: get_a_list(x), p_valid_data))
# 获得验证集上负样本
n_valid_data = valid_data[valid_data["label"] == 0]["sentence"]
# 对负样本的每个句子提取形容词
valid_n_a_vocab = chain(*map(lambda x: get_a_list(x), n_valid_data))
# 调用绘制词云函数
get_word_cloud(valid_p_a_vocab)
get_word_cloud(valid_n_a_vocab)
验证集正样本形容词词云
验证集负样本形容词词云

分析:
- 根据高频形容词词云显示,我们可以对当前语料质量进行简单评估
- 同时对违反语料标签含义的词汇进行人工审查和修正,来保证绝大多数语料符合训练标准
- 上图中的正样本大多数是褒义词,而负样本大多数是贬义词,基本符合要求
- 但是负样本词云中也存在"便利"这样的褒义词,因此可以人工进行审查
小节总结
-
学习了文本数据分析的作用:
- 能够有效帮助我们理解数据语料
- 快速检查出语料可能存在的问题
- 指导之后模型训练过程中一些超参数的选择
-
学习了常用的几种文本数据分析方法:
- 标签数量分布
- 句子长度分布
- 词频统计与关键词词云
-
学习了基于真实的中文酒店评论语料进行几种文本数据分析方法:
- 获得训练集和验证集的标签数量分布
- 获取训练集和验证集的句子长度分布
- 获取训练集和验证集的正负样本长度散点分布
- 获得训练集与验证集不同词汇总数统计
- 获得训练集上正负样本的高频形容词词云