04_文本特征处理与数据增强

文本特征处理

文本特征处理指的是为语料添加具有普适性的文本特征, 如:n-gram特征, 以及对加入特征之后的文本语料进行必要的处理, 如: 长度规范,这些特征处理工作能够有效的将重要的文本特征加入模型训练中, 增强模型评估指标。

1. n-gram特征

n-gram特征是自然语言处理中一种重要的特征表示方式。它通过将文本中的相邻n个词(或字符)组合起来,形成新的特征表示,可以用于很多任务,如文本分类、语言建模、机器翻译等。

例如

假设给定分词列表: ["是谁", "敲动", "我心"]

对应的数值映射列表为: [1, 34, 21]

我们可以认为数值映射列表中的每个数字是词汇特征.

除此之外, 我们还可以把"是谁"和"敲动"两个词共同出现且相邻也作为一种特征加入到序列列表中,

假设1000就代表"是谁"和"敲动"共同出现且相邻

此时数值映射列表就变成了包含2-gram特征的特征列表: [1, 34, 21, 1000]

这里的"是谁"和"敲动"共同出现且相邻就是bi-gram特征中的一个.

"敲动"和"我心"也是共现且相邻的两个词汇, 因此它们也是bi-gram特征.

假设1001代表"敲动"和"我心"共同出现且相邻

那么, 最后原始的数值映射列表 [1, 34, 21] 添加了bi-gram特征之后就变成了 [1, 34, 21, 1000, 1001]
  • n-gram的作用

    捕捉文本中词语之间的局部上下文信息,这些信息在许多NLP任务中非常重要。

  • 优势

    • 捕捉局部上下文信息:
      • n-gram 不像 uni-gram那样孤立地看待词语,而是将相邻的词语组合起来,从而捕捉到了词语之间的局部上下文信息。
      • 例如,“not happy” 这个 bigram 与 uni-gram “happy” 表达的含义完全相反,使用 n-gram 可以更好地捕捉这种关系。
    • 简单高效:
      • n-gram 特征的生成和使用相对简单,计算效率高。
      • 不需要复杂的语法分析和语义理解。
    • 无需预训练:
      • n-gram 特征不需要预先训练,可以直接在数据集中生成。
    • 可用于各种 NLP 任务:
      • n-gram 特征广泛应用于各种 NLP 任务,例如文本分类、情感分析、信息检索、语言模型等。
  • n-gram实现举例

  from sklearn.feature_extraction.text import CountVectorizer

  # 一般n-gram中的n取2或者3, 这里取2为例
  ngram_range = 2


  def create_ngram_set(corpus):
      # 默认使用 uni-gram(ngram_range=(1,1))
      # 默认会将文本转换为小写,并去除标点符号
      # 默认会过滤掉单字符词
      vectorizer = CountVectorizer(ngram_range=(ngram_range, ngram_range))
      X = vectorizer.fit_transform(corpus)
      # 输出词袋矩阵和词汇表
      print("词汇表:", vectorizer.get_feature_names_out())
      print("特征矩阵:\n", X.toarray())


  if __name__ == '__main__':
      corpus = [
          "I love NLP.",
          "NLP is fun!",
          "I study natural language processing."]
      create_ngram_set(corpus)

2.文本长度规范

一般模型的输入需要等尺寸大小的矩阵, 因此在进入模型前需要对每条文本数值映射后的长度进行规范, 此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度, 对超长文本进行截断, 对不足文本进行补齐(一般使用数字0), 这个过程就是文本长度规范。

  • 作用

    • 深度学习模型输入要求:
      • 大多数深度学习模型,例如循环神经网络(RNN)、长短期记忆网络(LSTM)、Transformer 等,都要求输入固定长度的序列。
      • 如果文本长度不一致,则需要进行填充或截断等处理,才能将文本数据输入到模型中。
    • 计算效率:
      • 如果文本长度差异过大,则会影响模型的计算效率,因为模型需要处理更长的序列。
      • 通过统一文本长度,可以减少计算量,加快训练速度。
    • 数据一致性:
      • 统一文本长度可以使数据更加一致,从而方便进行后续的统计分析和可视化。
      • 如果长度差异太大,则难以进行比较和分析。
    • 防止过拟合:
      • 过长的文本可能包含过多的噪声和冗余信息,导致模型过拟合。
      • 截断过长的文本可以减少噪声,提高模型的泛化能力。
    • 避免信息丢失:
      • 过短的文本可能包含较少的信息,导致模型无法学习到足够的特征。
      • 可以通过填充等方式,让短文本补充一定的信息,提高模型的准确性。
  • 方法

    • 截断 (Truncation):
      • **方法:**将文本截断到指定的最大长度,丢弃超过长度的部分。
      • **适用场景:**当文本长度过长,且我们只需要文本的前面部分时,可以使用截断。
      • **优点:**简单易行,计算效率高。
      • **缺点:**可能丢失文本尾部的信息。
      • **策略:**可以选择从文本开头截断(前截断)或从文本结尾截断(后截断)。
    • 填充 (Padding):
      • **方法:**将文本填充到指定的最大长度,通常使用特殊字符(例如, 或 0)进行填充。
      • **适用场景:**当文本长度过短,需要补充信息时,可以使用填充。
      • **优点:**可以使短文本保持固定的长度。
      • **缺点:**会引入一些额外的数据,可能影响模型的训练。
      • **策略:**可以选择在文本开头填充(前填充)或在文本结尾填充(后填充)。
    • 截断 + 填充:
      • **方法:**结合截断和填充,将文本统一到一个指定的长度。 对于长度超过指定长度的文本进行截断,对于长度短于指定长度的文本进行填充。
      • **适用场景:**适用于大部分场景,可以处理长度过长或过短的文本。
  • 代码实现举例

  from tensorflow.keras.preprocessing import sequence

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

  def padding_truncating(x_train):
      # 使用sequence.pad_sequences即可完成
      # truncating:pre->表示从前面截断 默认 post->表示从后面截断
      # padding:pre->表示从前面补齐 默认 post->表示从后面补齐
      return sequence.pad_sequences(sequences=x_train,  maxlen=cutlen, truncating='pre', padding='pre')


  if __name__ == '__main__':
      x_train = [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1],
                 [2, 32, 1, 23, 1]]

      res = padding_truncating(x_train)
      print(res)

文本数据增强

文本数据增强(Text Data Augmentation)是通过生成语义不变的文本变体来扩充训练数据的技术,常用于解决数据不足、提升模型鲁棒性。

为何需要文本增强?
  • 小样本学习:标注数据稀缺时扩展训练集
  • 防止过拟合:增加数据多样性,提升泛化能力
  • 鲁棒性提升:使模型适应拼写错误、表述差异等现实场景
  • 类别平衡:对少数类样本进行过采样
常用的文本数据增强方法——回译数据增强法
  • 基本原理

基于Google、有道等翻译接口, 将文本数据翻译成另外一种语言(一般选择小语种), 之后再翻译回原语言, 即可认为得到与原语料同标签的新语料, 新语料加入到原数据集中即可认为是对原数据集数据增强,这样能够增加数据多样性,帮助模型更好地理解语言中的多样性和变化。

  • 优势

    • 多样性:生成不同句式但语义相似的文本,增加训练集的多样性。
    • 避免过拟合:由于模型会接触到不同的句子结构,模型对文本的理解会更加泛化,从而降低过拟合风险。
    • 不需要标注数据:回译能够在没有人工标注的情况下生成额外的数据,对于需要大量标注的任务尤为有用。
  • 存在问题

    在短文本回译过程中, 新语料与原语料可能存在很高的重复率, 并不能有效增大样本的特征空间。

  • 高重复率解决办法

    进行连续的多语言翻译, 如: 中文→韩文→日语→英文→中文, 根据经验, 最多只采用3次连续翻译, 更多的翻译次数将产生效率低下, 语义失真等问题。

  • 基础实现

  # 需要科学上网才能访问谷歌翻译
  from googletrans import Translator
  # pip install googletrans==4.0.0-rc1 -i https://mirrors.aliyun.com/pypi/simple/

  def back_translate(text, src_lang='zh-cn', intermediate_lang='en'):
      # 回译数据增强
      # param text: 原始文本
      # param src_lang: 原始语言(默认中文)
      # param intermediate_lang: 中间语言(默认英语)
      # return: 回译后的文本
      translator = Translator()

      # 将原始文本翻译为中间语言
      translated = translator.translate(text=text, src=src_lang, dest=intermediate_lang)
      intermediate_text = translated.text

      # 将中间语言翻译回原始语言
      back_translated = translator.translate(intermediate_text, src=intermediate_lang, dest=src_lang)
      back_translated_text = back_translated.text

      return back_translated_text


  if __name__ == '__main__':
      # 示例
      original_text = "这个价格非常便宜!"
      augmented_text = back_translate(original_text)
      print("原始文本:", original_text)
      print("回译文本:", augmented_text)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值