文本预处理介绍

news2025/1/18 8:55:15

文本预处理

    • 文本预处理
        • 1.认识文本预处理
        • 2.文本处理的基本方法
          • 2.1.什么是分词
          • 2.2 什么是命名实体化
          • 2.3词性标注
        • 3.文本张量的表示方法
          • 3.1文本张量表示
          • 3.2 one-hot词向量表示
        • 4.Word2vec模型
          • 4.1模型介绍
          • 4.2word2vec的训练和使用
        • 5.词嵌入word embedding 介绍
        • 6.文本数据分析
          • 1.文本数据分析介绍
          • 2.数据集说明
          • 3.获取标签的数量分布
          • 4.获取句子长度分布
          • 5.获取正负样本长度散点分布
          • 6. 获取不用词汇总数统计
          • 7.获取训练集高频形容词词云
          • 8.获取验证集形容词词云
        • 7.文本特征处理
          • 1.特征处理的作用

文本预处理

1.认识文本预处理
  • 文本预处理及作用
前提:之前用pandas等进行数据分析,也属于文本预处理的范围
文本预处理作用:将文本转换成模型能够识别的张量形式,进而实现模型的训练
规范张量的尺寸,指导模型超参数的选择,提升模型的评估指标
  • 文本预处理的主要环节
1.文本处理的基本方法:分词、NER、POS
2.文本张量的表示方法:one-hot、word2vec、wordEmbedding
3.文本语料的数据分析:标签数量分析(类别不均衡问题)、句子长度分析、词频统计和关键词词云
4.文本特征处理:添加n-gram特征、文本长度规范
5.数据增强方法:回译数据增强
2.文本处理的基本方法
2.1.什么是分词
  • 将连续的字符串列按照一定的规范重新组合成词序列的过程.在英文当中,单词之间以空格作为自然分界符,而中文只是字,句和段能通过明显的分界符来简单划界,维度词没有形式上的分界符,分词就是找到这样的分界符的过程

举个例子:使用结巴分词

关关雎鸠,在河之洲;窈窕淑女,君子好逑!
['关关雎', '鸠', ',', '在', '河之洲', ';', '窈窕淑女', ',', '君子好逑', '!']

2.分词的作用

词作为语言语义理解的最小单元,是人类语言的基础. 
简化文本处理:使用分词,将原始文本分解为更小,更容易管理的片段,方便处理
提高效率:分词后文本更容易进行索引,从而提高信息检索的效率
理解语义结构:分词有助于解析句子的结构,帮助计算机理解文本的意义,这对于机器翻译系统等应用至关重要
减少数据维度:分词能够有效降低文本数据的维度,使模型训练更快,性能更好。

  • jieba 的特性:
支持多分类分词模式:
精确模式
全模式
搜索引擎
支持中文繁体分词
支持用户自定义词典
  • jieba的安装
pip install jieba
  • jieba的使用
  • 精确模式分词:
  • 试图将句子最精确的切分开,适合作文本分析
import jieba

# 1.默认为精确模式
content = '关关雎鸠,在河之洲;窈窕淑女,君子好逑!'
# 精确模式分词: 试图将句子最精确的切分开,适合作文本分析
# 分词默认模式为:精确模式 cut_call = False

res4 = jieba.cut(content)
# 直接打印返回一个生成器对象
# 无需使用列表直接使用jieba.lcut即可
res = jieba.lcut(content, cut_all=False)
# 可用列表承接分词结果
print(list(res4))
print('精确分词模式', res
  • 全模式分词:

  • 把句子中所有的可以成词的词语都扫描出来,速度很快,但不能消除歧义

# 2.全模式
# 无需要使用列表,直接使用jieba.lcut即可
content1 = '关关雎鸠,在河之洲'
res1 = jieba.lcut(content1, cut_all=True)
print('全模式', res1)
# 全模式 ['关关', '关关雎', '雎鸠', ',', '在', '河之洲']

# 注意1: 关关雎鸠 分为三个词
# 注意2: 符号也被分词
  • 搜索引擎模式
  • 在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
# 3.搜索引擎模式
# lcut_for_search:对搜索引擎优化,对长词进行精确模式分词,对短词进行全模式分词
res3 = jieba.lcut_for_search(content)
print('搜索引擎', res3)

# 搜索引擎 ['关关', '关关雎', '鸠', ',', '在', '河之洲', ';', '窈窕', '淑女', '窈窕淑女', ',', '君子', '好逑', '君子好逑', '!']
  • 中文繁体分词
# 4.繁体字分词
sent1 = '煩惱即是菩提,我暫且不提'
print('繁体字分词', jieba.lcut(sent1))

# 繁体字分词 ['煩惱', '即', '是', '菩提', ',', '我', '暫且', '不', '提']
2.2 什么是命名实体化
  • 命名实体化:通常就是将人名,地名,机构名等专有名词统称为命名实体化
  • 命名实体识别(简称NER):就是识别出一段文本中可能存在的命名实体
  • 举个例子
鲁迅, 浙江绍兴人, 五四新文化运动的重要参与者, 代表作朝花夕拾.

==>

鲁迅(人名) / 浙江绍兴(地名)人 / 五四新文化运动(专有名词) / 重要参与者 / 代表作 / 朝花夕拾(专有名词)
  • 作用:
信息提取:识别出文本中的实体,更好的提取文本信息,高效的进行数据挖掘
问答系统:在构建智能问答系统时:,通过人名,地名,等更准确的定位答案
机器翻译:对于多语言的信息系统,正确识别和保留专有名词有助于提高机器翻译的质量,确保名字,地点不被误翻译
2.3词性标注

词性:语言中对词的一种分类方法,以特征为主要依据.兼顾词汇意义对词进行划分的结果,常见的词性有14种,比如:名词,动词,形容词等.

词性标注:标注一段文本中每个词汇的词性

词性标注作用:

对文本中的每个单词分配一个适当的词性标签,比如名词、动词、形容词、副词等。
语法分析:是构建复杂语法分析的基础步骤,通过识别词语词性更好理解句子结构
信息检索:词性标注可以帮助提高查询的准确性和相关性,例如区分同形异义词的不同含义。
机器翻译:机器翻译系统需要了解源语言中词语的词性,以便选择正确的目标语言表达形式。
文本分类与情感分析:有助于从文本中提取特征,这在文本分类和情感分析等任务中特别有用,比如识别出评价性词汇(通常是形容词或副词)来判断文本的情感倾向。
命名实体化:在识别文本中的人名、地名、组织名等命名实体时,词性标注可以帮助缩小候选范围,提高识别准确性。
  • 使用jieba分词进行词性标注
import jieba.posseg as pseg
pseg.lcut("我爱北京天安门") 


# 输出结果为
[pair('我', 'r'), pair('爱', 'v'), pair('北京', 'ns'), pair('天安门', 'ns')]

3.文本张量的表示方法
3.1文本张量表示
  • 将一段文字使用张量表示,其中一般将词汇表示为向量,称为词向量,再由词向量按顺序组成矩阵.形成文本表示.
  • 举个例子:
["人生", "该", "如何", "起头"]
==>
# 每个词对应矩阵中的一个向量
[[1.32, 4,32, 0,32, 5.2],
 [3.1, 5.43, 0.34, 3.2],
 [3.21, 5.32, 2, 4.32],
 [2.54, 7.32, 5.12, 9.54]]
  • 文本张量表示的作用:
    • 将文本表示为张(矩阵)形式,能够使用文本作为计算机处理程序的输入
  • 文本张量的表示方法
  • one-hot编码
  • Word2vec
  • Word Embeding
3.2 one-hot词向量表示
  • 又称独热编码,将每个词表示成具有n个元素的向量,这些词向量只有一个元素1其他都为0,不用词汇之间位置不同,其中n的大小是整个语料中不同词汇的总数
  • 举个例子:
["改变", "要", "如何", "起手"]`
==>

[[1, 0, 0, 0],
 [0, 1, 0, 0],
 [0, 0, 1, 0],
 [0, 0, 0, 1]
  • one-hot编码实现:

进行onehot编码

import jieba
# 导入keras中的词汇映射器Tokenizer
from tensorflow.keras.preprocessing.text import Tokenizer
# 导入用于对象保存与加载的joblib
from sklearn.externals import joblib


def onehot_gen(sent):
    # 1.准备语料
    vocabs = list(set(jieba.lcut(sent)))

    # 2.实例化Tokenizer
    tokenizer = Tokenizer(vocabs)
    tokenizer.fit_on_texts(vocabs)

    # 3.查询单词idx,赋值zero_list
    for vocab in vocabs:
        zero_list = [0] * len(vocabs)
        # Tokenizer索引默认从1开始,所以要减1
        idx = tokenizer.word_index[vocab] - 1
        zero_list[idx] = 1
        print(vocab, '的独热编码', zero_list)

    # 4.使用joblib 保存模型
    my_path = './onehot_gen.pkl'
    joblib.dump(tokenizer, my_path)
    print('保存成功')

    # 打印
    print(tokenizer.word_index)
    print(tokenizer.index_word)
  • 输出结果为:
。 的独热编码 [1, 0, 0, 0, 0, 0]
关关雎 的独热编码 [0, 1, 0, 0, 0, 0]
在 的独热编码 [0, 0, 1, 0, 0, 0]
河之洲 的独热编码 [0, 0, 0, 1, 0, 0]
鸠 的独热编码 [0, 0, 0, 0, 1, 0]
, 的独热编码 [0, 0, 0, 0, 0, 1]
保存成功
{'。': 1, '关关雎': 2, '在': 3, '河之洲': 4, '鸠': 5, ',': 6}
{1: '。', 2: '关关雎', 3: '在', 4: '河之洲', 5: '鸠', 6: ','}
  • one-hot编码的使用
# 思路分析
# 1 加载已保存的词汇映射器Tokenizer joblib.load(mypath)
# 2 查询单词idx 赋值zero_list,生成onehot 以token为' 鸠'
# 3 token = "你好" 会出现异常
def onthot_use(char):
    # 1.加载词汇映射器
    my_path = './onehot_gen.pkl'
    my_tokenizer = joblib.load(my_path)
    # 2.查询index
    try:
        idx = my_tokenizer.word_index[char] - 1
    except:
        print('token没有这个')
    # 3.获取都热编码
    zero_list = [0] * len(my_tokenizer.word_index)
    zero_list[idx] = 1![请添加图片描述](https://i-blog.csdnimg.cn/direct/643a2a8655a144f5bf3cc9c957f9ffae.png)

    print(char, '的独热编码', zero_list)
  • 输出结果为
鸠 的独热编码 [0, 0, 0, 0, 1, 0]
  • one-hot编码的优劣势
    • 优势:操作简单,容易理解
    • 劣势:完全割裂词与词之间的联系,在语料集下,每个向量的长度过大,占据大量内存
4.Word2vec模型
4.1模型介绍
  • 将词汇表示成向量的无监督训练方法,该过程构建神经网络模型,将网络参数作为词汇表示,包含CBOW和skipgram两种方法

  • CBOW模式:连续词袋模型

  • 给定一段用于训练的文本语料,选定某段长度窗口 ,使用上下文词汇预测目标词汇

在这里插入图片描述

  • 分析
  • 窗口大小为9,使用前后4个词汇对目标词汇来预测
  • CBOW模式下的word2vec过程说明:
  • 假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是CBOW模式,所以将使用Hope和set作为输入,can作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘之后再相加, 得到上下文表示矩阵(3x1).

在这里插入图片描述

  • 接着, 将上下文表示矩阵与变换矩阵(参数矩阵5x3, 所有的变换矩阵共享参数)相乘, 得到5x1的结果矩阵, 它将与我们真正的目标矩阵即can的one-hot编码矩阵(5x1)进行损失的计算, 然后更新网络参数完成一次模型迭代.

在这里插入图片描述

最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.

  • skipgram模式:被称为跳词模型
  • 使用中心词来预测上下文文本
  • 如图所示: 将token进行one-hot编码与变换矩阵(即参数矩阵4x5, 这里的4是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(4x1).

在这里插入图片描述

假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),窗口大小为3,因此模型的第一个训练样本来自Hope can set,因为是skipgram模式,所以将使用can作为输入 ,Hope和set作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码. 如图所示: 将can的one-hot编码与变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘, 得到目标词汇表示矩阵(3x1).

在这里插入图片描述

最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵即参数矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.

  • 词向量的检索获取
  • 以下通过CBOW模型举例说明如何检a单词的词向量
  • 如下图所示:a的onehot编码[10000],用参数矩阵[3,5] * a的onehot编码[10000],可以把参数矩阵的第1列参数给取出来,这个[3,1]的值就是a的词向量。

在这里插入图片描述

4.2word2vec的训练和使用

1.词向量的训练保存和加载

fasttext 是facebook开源的一个词向量与文本分类工具,安装该工具包的方法

pip install fasttext-wheel

# 导入fasttext
import fasttext

def dm_fasttext_train_save_load():
    # 1 使用train_unsupervised(无监督训练方法) 训练词向量
    mymodel = fasttext.train_unsupervised('./data/fil9')
    print('训练词向量 ok')

    # 2 save_model()保存已经训练好词向量 
    # 注意,该行代码执行耗时很长 
    mymodel.save_model("./data/fil9.bin")
    print('保存词向量 ok')

    # 3 模型加载
    mymodel = fasttext.load_model('./data/fil9.bin')
    print('加载词向量 ok')


# 步骤1运行效果如下:
有效训练词汇量为124M,218316个单词
Read 124M words
Number of words:  218316
Number of labels: 0
Progress: 100.0% words/sec/thread:   53996 lr:  0.000000 loss:  0.734999 ETA:   0h 0m

2.查看单词对应的词向量

# 通过get_word_vector方法来获得指定词汇的词向量, 默认词向量训练出来是1个单词100特征
# 3.查看单词对应词向量
# 通过get_word_vector()方法获取指定的词向量,默认词向量训练出来1个单词100特征
def dm_fasttext_get_word_vector():
    # 1.加载模型
    my_model = fasttext.load_model('./data/fil9.bin')
    # 2.查询某个词汇的词向量
    # get_word_vector()查询词向量
    result = my_model.get_word_vector('donkey')
    print(f'donkey词向量为:{result}')
    print(f'donkey词向量类型为:{type(result)}')
    print(f'donkey词向量维度为:{result.shape}')
# 运行效果如下:
array([-0.03087516,  0.09221972,  0.17660329,  0.17308897,  0.12863874,
        0.13912526, -0.09851588,  0.00739991,  0.37038437, -0.00845221,
        ...
       -0.21184735, -0.05048715, -0.34571868,  0.23765688,  0.23726143],
      dtype=float32)

3.模型效果检验

# 4.检验模型效果
# 查看'运动'的近邻单词,可以看到'体育网','运动汽车','运动服'等
def dm_fasttext_get_nearset_neighbors():
    # 1.加载模型
    my_model = fasttext.load_model('./data/fil9.bin')
    # 2.查询sports的临近单词
    result1 = my_model.get_nearest_neighbors('sports')
    print(f'sports近邻单词为:{result1}')
    
    [(0.8414610624313354, 'sportsnet'), (0.8134572505950928, 'sport'), (0.8100415468215942, 'sportscars'), (0.8021156787872314, 'sportsground'), (0.7889881134033203, 'sportswomen'), (0.7863013744354248, 'sportsplex'), (0.7786710262298584, 'sporty'), (0.7696356177330017, 'sportscar'), (0.7619683146476746, 'sportswear'), (0.7600985765457153, 'sportin')]

    # 查询music的临近单词
    result2 = my_model.get_nearest_neighbors('music')
    print(f'music近邻单词为:{result2}')
    [(0.8908010125160217, 'emusic'), (0.8464668393135071, 'musicmoz'), (0.8444250822067261, 'musics'), (0.8113634586334229, 'allmusic'), (0.8106718063354492, 'musices'), (0.8049437999725342, 'musicam'), (0.8004694581031799, 'musicom'), (0.7952923774719238, 'muchmusic'), (0.7852965593338013, 'musicweb'), (0.7767147421836853, 'musico')]

    
    # 查询dog的临近单词
    result3 = my_model.get_nearest_neighbors('dog')
    print(f'dog近邻单词为:{result3}')
    [(0.8456876873970032, 'catdog'), (0.7480780482292175, 'dogcow'), (0.7289096117019653, 'sleddog'), (0.7269964218139648, 'hotdog'), (0.7114801406860352, 'sheepdog'), (0.6947550773620605, 'dogo'), (0.6897546648979187, 'bodog'), (0.6621081829071045, 'maddog'), (0.6605004072189331, 'dogs'), (0.6398137211799622, 'dogpile')]

4.模型超参数设定

在训练词向量过程中, 我们可以设定很多常用超参数来调节我们的模型效果, 如:
无监督训练模式: ‘skipgram’ 或者 ‘cbow’, 默认为’skipgram’, 在实践中,skipgram模式在利用子词方面比cbow更好.
词嵌入维度dim: 默认为100, 但随着语料库的增大, 词嵌入的维度往往也要更大.
#数据循环次数epoch: 默认为5, 但当你的数据集足够大, 可能不需要那么多次.
#学习率lr: 默认为0.05, 根据经验, 建议选择[0.01,1]范围内.
使用的线程数thread: 默认为12个线程, 一般建议和你的cpu核数相同.

# 5.模型超参数设置
# 无监督训练模式model可选'skipgram(默认) or 'cbow'
# 词嵌入维度dim 默认为0
# 循环次数epoch 默认为5
# 学习率lr默认为0.05 建议[0,0.1,1]
def dm_fasttest_train_args():
    my_model = fasttext.train_unsupervised('./data/fil9',
                                           'cbow',
                                           epoch=1,
                                           lr=0.1,
                                           dim=300,
                                           thread=8)
    # 保存模型
    my_model.save_model('./data/fil9.bin')
5.词嵌入word embedding 介绍
  • 通过一定方式将词汇映射到指定维度(一般是更高维度)空间
  • 广义的word embedding 包括所有词汇向量的表示方法,如之前学的word2vec,也可认为是word embedding一种
  • 狭义上讲word embedding指的是神经网络中加入embedding层,对整个网络进行训练同时产生embedding矩阵(embedding层参数),这个embedding矩阵就是训练过程中所有输入词汇的向量表示组成矩阵.

word embedding的可视化分析:

  • 通过使用tensorboared可视化嵌入的词向量
  • 1.导入数据包
import torch
import jieba
from tensorflow.keras.preprocessing.text import Tokenizer
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter
  • 2.获取语料
def embedding_show():
    # 1.获取语料数据
    sent1 = '床前明月光,疑是地上霜;举头望明月,低头思故乡!'
    sent2 = '关关雎鸠,在河之洲;窈窕阿港,君子好逑!'
    sents = [sent1, sent2]
  • 3.对句子分词并添加到word_list = []中
    # 2.对句子分词在word_list = []
    word_list = []
    for s in sents:
        word_list.append(jieba.lcut(s))
        print(f'word_list:{word_list}')
  • 4.实例化Tokenizer()训练语料数据获取word_index,index_word
    # 3.实例化Tokenizer
    my_tokenizer = Tokenizer()
    # 训练拿到每个词的索引下标1
    my_tokenizer.fit_on_texts(word_list)
    # word_index:词为键值,索引为值,索引从1开始
    print(my_tokenizer.word_index)
    # index_word:索引为键值,词为值
    print(my_tokenizer.index_word)
  • 5.拿到所有的token并打印句子下标
    # 4.拿到所有的token
    my_token_list = my_tokenizer.index_word.values()
    print(f'my_token_list:{my_token_list}')

    # 5.打印句子id
    # texts_to_sequences:将句子转换为id
    seq2id = my_tokenizer.texts_to_sequences(word_list)
    print(f'seq2id:{seq2id}')
  • 6.创建Embedding层,拿到词频向量矩阵
    # 6.拿到embedding矩阵,查表矩阵
    my_embed = nn.Embedding(num_embeddings=len(my_token_list), embedding_dim=8)
    print(f'my_embed.shape:', my_embed.weight.shape)
    print(my_embed.weight.data)
  • 7.查询token,和vec
    # 7.查询token,vec
    for idx in range(len(my_tokenizer.index_word)):
        vec = my_embed(torch.tensor(idx))
        word = my_tokenizer.index_word[idx + 1]
        print(word, ':', vec)

8.数据可视化

    # 8.可视化
    # logdir:日志文件保存路径
    logdir = './embedding_runs'
    # SummaryWriter:记录日志
    my_summary = SummaryWriter(log_dir=logdir)
    # add_embedding:记录embedding数据
    my_summary.add_embedding(my_embed.weight.data, my_token_list)
    my_summary.close()
    # 记得增加目录
    # 终端操作可视化:tensorboard --logdir=embedding_runs --host 0.0.0.0

进入终端窗口输入

tensorboard --logdir=day02/embedding_runs --host 0.0.0.0
得到以下链接

在这里插入图片描述
点击更该链接为127.0.0.1:6006
展示得到

在这里插入图片描述

6.文本数据分析
1.文本数据分析介绍
  • 文本数据分析作用

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

  • 常用的数据分析方法
  • 标签数量分布

作用:了解和分析标签数量分布更好的处理数据集特性,优化性能,适当处理数据不平衡问题

  • 类别不平衡问题
  • 数据集的多样性
  • 句子长度分布
  • 数据集的多样性:通过 句子长度分布,了解数据集中句子的长度变化范围,评估数据集的多样性和复杂性
  • 异常值检测:识别过长或过短的句子,可能存在异常值或噪声,需要进一步处理
  • 词频统计与关键词词云
  • 词频统计:停用词过滤,通过词频统计,可以识别常见的停用词,并在后续的处理中过滤掉停用词,减少噪声
  • 高频词汇可以作为特征选择的一部分,用于构建模型
  • 关键词词云:直观地展示关键词
  • 突出重要的词汇
2.数据集说明
  • 将基于真实的中文酒店评论语料来讲解常用的文本数据分析方法.
  • 中文酒店评论语料
    • 属于二分类的中文情感分析语料
    • 其中划分有训练集和测试集,二者数据集样式相同
3.获取标签的数量分布
  • 导入数据包
# 导入必备工具包
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import jieba
# itertools方便地对数据进行迭代。
from itertools import chain
# posseg模块,用于分词,并返回词性
import jieba.posseg as pseg
# wordcloud用于绘制词云
from wordcloud import WordCloud
  • 查看标签的分布情况用于不处理样本不均衡问题
# 思路分析:获取标签数量的分布
# 0 什么标签数量分布:求标签0有多少个 标签1有多少个 标签2有多少个
# 1 设置显示风格plt.style.use('fivethirtyeight')
# 2 pd.read_csv(path, sep='\t') 读训练集 验证集数据
# 3 sns.countplot() 统计label标签的0、1分组数量
# 4 画图展示 plt.title() plt.show()
# 分组可视化
def dm_label_sns_countplot():

    # 1 设置显示风格plt.style.use('fivethirtyeight')
    plt.style.use('fivethirtyeight')

    # 2 pd.read_csv 读训练集 验证集数据
    train_data = pd.read_csv(filepath_or_buffer = './cn_data/train.tsv', sep='\t')
    dev_data = pd.read_csv(filepath_or_buffer = './cn_data/dev.tsv', sep='\t')

    # 3 sns.countplot() 统计label标签的0、1分组数量
    sns.countplot(x='label', data = train_data)

    # 4 画图展示 plt.title() plt.show()
    plt.title('train_label')
    plt.show()

    # 验证集上标签的数量分布
    # 3-2 sns.countplot() 统计label标签的0、1分组数量
    sns.countplot(x='label', data = dev_data)

    # 4-2 画图展示 plt.title() plt.show()
    plt.title('dev_label')
    plt.show()
  • 分析:

深度学习评估模型中,使用ACC 来评估模型,若想将ACC基线模型定义在50%左右,需要将正负样本比例维持在1:1左右,上图训练和验证集正负样本都稍有不均衡,需要数据值增强

4.获取句子长度分布
# 思路
# 思路分析 : 获取句子长度分布 -绘制句子长度分布-柱状图 句子长度分布-密度曲线图
# 0 什么是句子长度分布:求长度为50的有多少个 长度51的有多少个 长度为52的有多少个
# 1 设置显示风格plt.style.use('fivethirtyeight')
# 2 pd.read_csv(path, sep='\t') 读训练集 验证集数据
# 3 新增数据长度列:train_data['sentence_length'] = list(map(lambda x:len(x) , ...))
# 4-1 绘制数据长度分布图-柱状图 sns.countplot(x='sentence_length', data=train_data)
#  画图展示 plt.xticks([]) plt.show()
# 4-2  绘制数据长度分布图-曲线图 sns.displot(x='sentence_length', data=train_data)
# 画图展示 plt.yticks([]) plt.show()
def dm_len_sns_countplot_distplot():
    # 1 设置显示风格plt.style.use('fivethirtyeight')
    plt.style.use('fivethirtyeight')

    # 2 pd.read_csv 读训练集 验证集数据
    train_data = pd.read_csv(filepath_or_buffer='./cn_data/train.tsv', sep='\t')
    dev_data = pd.read_csv(filepath_or_buffer='./cn_data/dev.tsv', sep='\t')

    # 3 求数据长度列 然后求数据长度的分布
    train_data['sentence_length'] =  list( map(lambda x: len(x), train_data['sentence']))

    # 4 绘制数据长度分布图-柱状图
    sns.countplot(x='sentence_length', data=train_data)
    # sns.countplot(x=train_data['sentence_length'])
    plt.xticks([]) # x轴上不要提示信息
    # plt.title('sentence_length countplot')
    plt.show()

    # 5 绘制数据长度分布图-曲线图
    sns.displot(x='sentence_length', data=train_data)
    # sns.displot(x=train_data['sentence_length'])
    plt.yticks([]) # y轴上不要提示信息
    plt.show()

    # 验证集
    # 3 求数据长度列 然后求数据长度的分布
    dev_data['sentence_length'] = list(map(lambda x: len(x), dev_data['sentence']))

    # 4 绘制数据长度分布图-柱状图
    sns.countplot(x='sentence_length', data=dev_data)
    # sns.countplot(x=dev_data['sentence_length'])
    plt.xticks([])  # x轴上不要提示信息
    # plt.title('sentence_length countplot')
    plt.show()

    # 5 绘制数据长度分布图-曲线图
    sns.displot(x='sentence_length', data=dev_data)
    # sns.displot(x=dev_data['sentence_length'])
    pltyticks([])  # y轴上不要提示信息
    plt.show()
  • 分析:

通过绘制句子长度分布图,可以得知语料大部句子长度分布范围因为,模型输入要求固定尺寸张量,合理长度范围对句子截断补齐,规范长度起到关键作用.

5.获取正负样本长度散点分布
# 获取正负样本长度散点分布,也就是按照x正负样本进行分组 再按照y长度进行散点图
# train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))
#  sns.stripplot(y='sentence_length', x='label', data=train_data)
def dm03_sns_stripplot():
    # 1 设置显示风格plt.style.use('fivethirtyeight')
    plt.style.use('fivethirtyeight')

    # 2 pd.read_csv 读训练集 验证集数据
    train_data = pd.read_csv(filepath_or_buffer='./cn_data/train.tsv', sep='\t')
    dev_data = pd.read_csv(filepath_or_buffer='./cn_data/dev.tsv', sep='\t')

    # 3 求数据长度列 然后求数据长度的分布
    train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))

    # 4 统计正负样本长度散点图 (对train_data数据,按照label进行分组,统计正样本散点图)
    sns.stripplot(y='sentence_length', x='label', data=train_data)
    plt.show()

    sns.stripplot(y='sentence_length', x='label', data=dev_data)
    plt.show()
  • 分析

通过查看正负样本长度散点图,可以有效定位异常点出现的位置,及时处理异常点

6. 获取不用词汇总数统计

chain函数作用:将多个可迭代对象连接成一个单一的可迭代对象

*运算符:可以map对象解包,使其元素可作为在参数传递给另一个函数

# 导入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))
7.获取训练集高频形容词词云
# 使用jieba中的词性标注功能
import jieba.posseg as pseg
from wordcloud import WordCloud

# 每句话产生形容词列表
def get_a_list(text):
    r = []

    # 使用jieba的词性标注方法切分文本 找到形容词存入到列表中返回
    for g in pseg.lcut(text):
        if g.flag == "a":
            r.append(g.word)
    return r

# 根据词云列表产生词云
def  get_word_cloud(keywords_list):
    # 实例化词云生成器对象
    wordcloud = WordCloud(font_path="./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()


# 思路分析 训练集正样本词云 训练集负样本词云
# 1 获得训练集上正样本 p_train_data
#   eg: 先使用逻辑==操作检索符合正样本 train_data[train_data['label'] == 1]
# 2 获取正样本的每个句子的形容词 p_a_train_vocab = chain(*map(a,b))
# 3 调用绘制词云函数
def dm_word_cloud():
    # 1 获得训练集上正样本p_train_data
    #   eg: 先使用逻辑==操作检索符合正样本 train_data[train_data['label'] == 1]
    train_data = pd.read_csv(filepath_or_buffer='./cn_data/train.tsv', sep='\t')
    p_train_data = train_data[train_data['label'] == 1 ]['sentence']

    # 2 获取正样本的每个句子的形容词 p_a_train_vocab = chain(*map(a,b))
    p_a_train_vocab = chain(*map(lambda x: get_a_list(x) , p_train_data))
    # print(p_a_train_vocab)
    # print(list(p_a_train_vocab))

    # 3 调用绘制词云函数
    get_word_cloud(p_a_train_vocab)


    print('*' * 60 )
    # 训练集负样本词云
    n_train_data = train_data[train_data['label'] == 0 ]['sentence']

    # 2 获取正样本的每个句子的形容词 p_a_train_vocab = chain(*map(a,b))
    n_a_train_vocab = chain(*map(lambda x: get_a_list(x) , n_train_data)  )
    # print(n_a_dev_vocab)
    # print(list(n_a_dev_vocab))

    # 3 调用绘制词云函数
    get_word_cloud(n_a_train_vocab)
8.获取验证集形容词词云
# 获得验证集上正样本
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))
#print(train_p_n_vocab)

# 获得验证集上负样本
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)

分析

通过高频形容词词云显示.对当前语料进行简单评估,同时对违反语料标签含义的词汇进行人工审查和修正

7.文本特征处理
1.特征处理的作用
包括对语料添加具有普适性的文本特征,如n_gram特征,以对加入特征之后的文本语料进行必要处理,比如:长度规范,增强模型评估指标

常见的文本特征处理的必要方法:

添加n_ gram 特征

  • 给定一段文本序列,其中n个词或子相邻之间共线特征及n-gram特征是bi-gram和tri-gram特征,分别对应2和3
# 一般n-gram中的n取2或者3, 这里取2为例
ngram_range = 2

def create_ngram_set(input_list):
    """
    description: 从数值列表中提取所有的n-gram特征
    :param input_list: 输入的数值列表, 可以看作是词汇映射后的列表, 
                       里面每个数字的取值范围为[1, 25000]
    :return: n-gram特征组成的集合

    eg:
    >>> create_ngram_set([1, 3, 2, 1, 5, 3])
    {(3, 2), (1, 3), (2, 1), (1, 5), (5, 3)}
    """ 
    return set(zip(*[input_list[i:] for i in range(ngram_range)]))
  • 输出结果为
# 该输入列表的所有bi-gram特征
{(3, 2), (1, 3), (2, 1), (1, 5), (5, 3)}

文本长度规范及作用

  • 模型的输入需要等尺寸大小的矩阵,因此在进入模型之前需要对每条文本数值映射后的长度进行规范,将句子长度分析覆盖绝大多数文本的合理长度,对超出文本进行截断,对不足文本补齐(一般使用数字0)
  • 实现
from tensorflow.keras.preprocessing import sequence

# cutlen根据数据分析中句子长度分布,覆盖90%左右语料的最短长度.
# 这里假定cutlen为10
cutlen = 10

def padding(x_train):
    """
    description: 对输入文本张量进行长度规范
    :param x_train: 文本的张量表示, 形如: [[1, 32, 32, 61], [2, 54, 21, 7, 19]]
    :return: 进行截断补齐后的文本张量表示 
    """
    # 使用sequence.pad_sequences即可完成
    return sequence.pad_sequences(x_train, cutlen)

调用

# 假定x_train里面有两条文本, 一条长度大于10, 一天小于10
x_train = [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1],
           [2, 32, 1, 23, 1]]

res = padding(x_train)
print(res)

# 结果为

[[ 5 32 55 63  2 21 78 32 23  1]
 [ 0  0  0  0  0  2 32  1 23  1]]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2256260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣3381.长度可被K整除的子数组的最大元素和

力扣3381.长度可被K整除的子数组的最大元素和 题目 题目解析及思路 题目要求返回一段长度为K的倍数的最大子数组和 同余前缀和 代码 class Solution { public:long long maxSubarraySum(vector<int>& nums, int k) {int n nums.size();vector<long long>…

第三节、电机定速转动【51单片机-TB6600驱动器-步进电机教程】

摘要&#xff1a;本节介绍用定时器定时的方式&#xff0c;精准控制脉冲时间&#xff0c;从而控制步进电机速度 一、计算过程 1.1 电机每一步的角速度等于走这一步所花费的时间&#xff0c;走一步角度等于步距角&#xff0c;走一步的时间等于一个脉冲的时间 w s t e p t … ……

【数学建模】线性规划问题及Matlab求解

问题一 题目&#xff1a; 求解下列线性规划问题 解答&#xff1a; 先将题目中求最大值转化为求最小值&#xff0c;则有 我们就可以得到系数列向量: 我们对问题中所给出的不等式约束进行标准化则得到了 就有不等式约束条件下的变系数矩阵和常系数矩阵分别为&#xff1a; 等式…

云计算对定制软件开发的影响

在当代数字世界中&#xff0c;云计算是改变许多行业&#xff08;包括定制软件开发&#xff09;的最伟大的革命性趋势之一。由于这些公司努力寻求更好、更多不同的方式来履行职责&#xff0c;因此云计算与传统的内部部署基础设施相比具有许多不可否认的优势。这种范式转变对定制…

3D 生成重建020-Gaussian Grouping在场景中分割并编辑一切

3D 生成重建020-Gaussian Grouping在场景中分割并编辑一切 文章目录 0 论文工作1 方法2 实验结果 0 论文工作 最近提出的高斯Splatting方法实现了高质量的实时三维场景新视角合成。然而&#xff0c;它仅仅关注外观和几何建模&#xff0c;缺乏细粒度的物体级场景理解。为了解决…

GUI的最终选择:Tkinter

Tkinter是Python默认的GUI库&#xff0c;因此使用时直接导入即可&#xff1a;import tkinter 17.1 Tkinter之初体验 代码分析&#xff1a; tkinter.mainloop()通常是程序的最后一行代码&#xff0c;执行后程序进入主事件循环。 17.2 进阶版本 将代码封装成类&#xff1a; 运…

电子商务人工智能指南 3/6 - 聊天机器人和客户服务

介绍 81% 的零售业高管表示&#xff0c; AI 至少在其组织中发挥了中等至完全的作用。然而&#xff0c;78% 的受访零售业高管表示&#xff0c;很难跟上不断发展的 AI 格局。 近年来&#xff0c;电子商务团队加快了适应新客户偏好和创造卓越数字购物体验的需求。采用 AI 不再是一…

嵌入式软件C语言面试常见问题及答案解析(一)

本文中题目列表 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)2. 写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。3. 预处理器标识#error的目的是什么?4. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?5. …

从失败中学习:如何将错误转化为学习机会

失败是人生的一部分&#xff0c;无论是在个人生活还是职业生涯中&#xff0c;我们都难免会遇到挫折和错误。然而&#xff0c;失败并不意味着终结&#xff0c;而是一个潜在的学习机会。通过正确的态度和方法&#xff0c;我们可以从失败中汲取经验&#xff0c;转化为成长的动力。…

HarmonyOS NEXT的Navigation,跳转子页面后底部Tab不隐藏问题解决

问题复现 一直以来&#xff0c;首页的Tabs是这么用的&#xff1a; import Home from "../pages/home/Home" import ZhiHu from "../pages/song/Song" import Mine from "../pages/mine/Mine"Entry Component struct Index {State currentIndex…

基础排序算法详解:冒泡排序、选择排序与插入排序

引言 上一章&#xff0c;我们聊到了排序的基本概念和常见算法的分类。这一次&#xff0c;我们从基础开始&#xff0c;深入剖析三种常见的O(n) 排序算法&#xff1a;冒泡排序、选择排序 和 插入排序。 它们是学习排序算法的入门神器&#xff0c;不仅实现简单&#xff0c;还能帮…

番茄钟与Todo List:用Go构建高效的时间管理工具

引言 在当今快节奏的世界中&#xff0c;时间管理和任务组织变得越来越重要。为了帮助用户提高效率&#xff0c;我开发了一个基于Golang的开源项目&#xff0c;基于fyne的ui&#xff0c;它结合了经典的番茄工作法&#xff08;Pomodoro Technique&#xff09;和功能丰富的待办事…

Python-标识符、隐式转换和显式转换

记录python学习&#xff0c;直到学会基本的爬虫&#xff0c;使用python搭建接口自动化测试就算学会了&#xff0c;在进阶webui自动化&#xff0c;app自动化 python基础1 标识符约定动态语言和静态语言隐式转换和显式转换隐式转换显式转换 实践是检验真理的唯一标准 标识符约定…

【全网最新】使用 1panel面板 部署若依系统( springboot 和 vue)项目

​​​​​​使用 1panel面板 部署 springboot 和 vue_1panel部署vue项目-CSDN博客 准备工作: 准备好的网站后台代码文件准备好的网站前端页面安装好1panel1panel中安装好mysql1panel中安装好redis1panel中安装好Openresty部署后台接口 在application.yml中修改后台端口,这里…

力扣Hot100刷题日常(链表篇上)

相交链表 题目分析&#xff1a; 暴力解法&#xff1a; 计算链表的长度&#xff1a; 首先我们需要知道链表 A 和链表 B 的长度。因为在开始比较两个链表是否相交之前&#xff0c;我们需要确保它们有相同的起始点。从长度上来说&#xff0c;两个链表的交点一定会出现在它们后续部…

MySQL数据库安全与管理

1、创建两个新用户U_student1和U_student2,密码分别为1234和5678 create user U_student1@localhost identified by 1234, U_student2@localhost identified by 5678; 2、创建两个新用户的详细信息保存在MySQL数据库的user表中 use mysql; select user, host, authentication…

【数据库】关系代数和SQL语句

一 对于教学数据库的三个基本表 学生S(S#,SNAME,AGE,SEX) 学习SC(S#,C#,GRADE) 课程(C#,CNAME,TEACHER) &#xff08;1&#xff09;试用关系代数表达式和SQL语句表示&#xff1a;检索WANG同学不学的课程号 select C# from C where C# not in(select C# from SCwhere S# in…

在做题中学习(79):最小K个数

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogK)&#xff0c;K为k个元素 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#…

uniapp页面不跳转问题!(使用uni.$u.route或者原生uni.navigateTo)页面跳转ios无效果(既不报错也不跳转页面)

1.问题描述: 通常使用点击事件来触发页面跳转都没问题,但是现在业务需求,在一个方法中自动去携带参数跳转到另外一个页面,android真机无问题,就ios一直无法跳转过去! 2.解决方法: 2.1 必须使用setTimeout来延迟跳转 2.2 setTimeout的延迟时间必须要大于300 不要问为什么…

基于 Spring Boot + Vue 的宠物领养系统设计与实现

引言 近年来&#xff0c;随着人们生活水平的提高&#xff0c;宠物逐渐成为许多家庭的重要成员。然而&#xff0c;宠物的流浪和弃养问题日益严重&#xff0c;这促使社会对宠物领养的需求不断增长。为解决宠物领养中信息不对称、领养流程复杂等问题&#xff0c;设计并实现一个基…