四、文本数据分析

文本数据分析能够有效帮助我们理解数据预料,快速查出预料可能存在的问题,并指导之后模型训练过程中一些超参数的选择。

常用的几种文本数据分析方法,包括:

  • 标签数量分布:数据中正负样本的分布最好接近1:1
  • 句子长度分别:通过观察句子的长短来挑选合适的处理方法
  • 词频统计与关键词词云:

数据集选择的是ChnSentiCorp_htl_all数据集(见知乎【NLP入门】文本分类:酒店评论),内容为酒店评论。共有7766条数据。类别仅有好坏两种,正面评价5322个,负面评价2444个,有一定的不平衡。内容如下:

数据中第一列为label,其中0表示该条样本是负面评价,1表示正面评价。剩余部分为具体评价内容。应该不难理解。


一、标签数量分布

import seaborn as sns  # 绘制直方图的库
import pandas as pd
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv('./Datasets/ChnSentiCorp_htl_all.txt', sep=',')

sns.countplot('label', data=data)  # 统计标签“label”列中各个标签的数量
plt.title(label='标签数量分布', fontdict={'family': 'SimHei'})  # 设置图像显示的题目
plt.show()  # 展示图像

显示结果如下:

可以看出,正负样本的分布是不平衡的。在深度学习模型的评估中,一般使用ACC(accuracy,准确率)作为评估指标,ACC=预测正确的样本数/总样本数,若想将ACC的基线定义在50%左右,则需要我们的正负样本比例维持在1:1左右,否则就要进行必要的数据增强或数据删减。(50%基线的解释基线的意思就是,假设模型没有任何的预测能力,只能像掷硬币一样随机猜测是正样本还是负样本,那么对于正:负=1:1的数据集来说,根据概率很容易可以算出,模型的准确率在50%左右,因为不是正就是负,就是瞎猜。但是,如果数据不平衡,比如正:负=9:1,那么模型很有可能变成,不管是正还是负样本,我都预测为正样本,这样的话,模型还是有90%的准确率,看似准确率很高,但其实这是个很垃圾的模型

上图中明显看出,正负样本的分布是不平衡的,所以要进行模型训练的话,需要进行数据增强。

二、句子长度分布

1、全部数据集的句子长度分布直方图 

import seaborn as sns  # 绘制直方图的库
import pandas as pd
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv('./Datasets/ChnSentiCorp_htl_all.txt', sep=',')

# 计算每行review的长度
sentence_len = [len(str(s)) for s in data['review']]
# 创建新列数据
new_col_data = pd.Series(sentence_len, name='sentence_len')
# 将新列添加到DataFrame
data['sentence_len'] = new_col_data

# for i in data['review']:
#     print(len(i), ':', i)

sns.countplot('sentence_len', data=data)  # 统计标签“label”列中各个标签的数量
plt.title(label='句子长度分布', fontdict={'family': 'SimHei'})  # 设置图像显示的题目
plt.xticks([])  # 不显示x轴,显示的话,数太多了,很乱
plt.show()  # 展示图像

sns.displot(data['sentence_len'])
plt.show()

数据集的句子长度分布如下:

可以看出,数据集中,句子的分布长度绝大部分都在500以下,甚至300以下。

通过绘制句子长度分布图,可以得知我们的语料中大部分句子长度的分布范围,因为模型的输入要求为固定尺寸的张量,合理的长度范围对之后进行句子截断补齐(统一长度)起到关键的指导作用。上图的大部分句子长度范围为20-250之间

2、数据集中正负样本上的句子长度散点分布

import seaborn as sns  # 绘制直方图的库
import pandas as pd
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv('./Datasets/ChnSentiCorp_htl_all.txt', sep=',')

sentence_len = [len(str(s)) for s in data['review']]
# 创建新列数据
new_col_data = pd.Series(sentence_len, name='sentence_len')
# 将新列添加到DataFrame
data['sentence_len'] = new_col_data

# 散点分布
sns.stripplot(y='sentence_len', x='label', data=data)
plt.show()

正负样本上的散点分布图如下:

通过查看正负样本长度散点图,可以有效定位异常点的出现位置,帮助我们更准确进行人工语料的审查。如上图中label=0中,明显出现一个离群点,句子长度接近3000.明显是异常点,写评价写三千字,一般人干不出来!

三、不同词汇的总数统计

itertools.chain 函数在Python标准库中的 itertools 模块中,它的主要作用是将一个或多个可迭代对象(如列表、元组、字符串或其他迭代器)串联起来,形成一个新的迭代器。这个新的迭代器会依次返回第一个可迭代对象的所有元素,接着是第二个可迭代对象的元素,依此类推,就像是把所有输入的序列“链”成一个连续的序列。

统计词汇的代码如下:

import jieba  # 用于分词
from itertools import chain
import pandas as pd

# 读取数据
data = pd.read_csv('./Datasets/ChnSentiCorp_htl_all.txt', sep=',')
# 对数据集进行分词,并统计不同词汇的总数
diff_vocab = set(chain(*[jieba.lcut(str(x)) for x in data['review']]))
# 打印不同词汇的总数
print(len(diff_vocab))

经过打印,共有29716个不同的词汇。

四、获取数据集上的形容词词云

词云(Word Cloud)是一种数据可视化技术,它通过字体大小和颜色的差异来突出显示文本数据中单词的重要性或频率。词云将文本中出现次数较多的词汇以较大的字号展示出来,而较少出现的词汇则以较小字号呈现。这种视觉效果使得人们能够快速地从大量文本中直观感知到高频关键词及其相对权重。如下图所示:

# 使用jieba中的词性标注功能
import jieba.posseg as pseg
# 导入绘制词云的工具包
from wordcloud import WordCloud
import matplotlib.pylab as plt
import pandas as pd
from itertools import chain

def get_a_list(text):
    """用于获取形容词词表

    Args:
        text (str): 使用jieba的词性标注方法需要切分的文本

    Returns:
        list: 返回文本中所有的形容词
    """
    # 使用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):
    """绘制词云图像

    Args:
        keywords_list (list): 存放分词的词表
    """
    # 实例化绘制词云的类,其中参数font_path是字体路径,为了能够显示中文
    # max_words指词云图像最多显示多少个词,background_color为背景颜色
    wordcloud = WordCloud(font_path=r'./model/simhei.ttf',
                          max_words=100, background_color='black')
    # 将传入的列表转化成词云生成器需要的字符串形式,如'便宜 宽敞 大 干净 ...'
    keywords_string = " ".join(keywords_list)
    # 生成词云
    wordcloud.generate(keywords_string)

    # 绘制图像并显示
    plt.figure()
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis('off') # 不需要坐标,关闭坐标轴
    plt.show()

# 读取数据
data = pd.read_csv('./Datasets/ChnSentiCorp_htl_all.txt', sep=',')
# 对label==1的正样本进行分词
pos_token_a = chain(*[get_a_list(str(s))
                      for s in data[data['label'] == 1]['review']])
# 画出正样本的词云分布图
get_word_cloud(pos_token_a)

# 对label==0的负样本进行分词
neg_token_a = chain(*[get_a_list(str(s))
                      for s in data[data['label'] == 0]['review']])
# 画出负样本的词云分布图
get_word_cloud(neg_token_a)

整体数据集中正样本词云的输出: 

整体数据集中负样本词云的输出:  

根据高频形容词词云显示,我们可以对当前预料质量进行简单评估,同时对违反预料标签含义的词汇进行人工审查和修正,来保证绝大多数语料符合训练标准,上图中的正样本大多数是褒义词,而负样本大多数是贬义词,基本符合要求,但是负样本词云中也存在“便利”、“舒服”这样的褒义词,因此可以人工进行审查。

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

并不傻的狍子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值