在自然语言处理(NLP)领域,文本预处理是连接原始文本数据与模型训练的关键桥梁。它贯穿于数据输入到模型之前的全流程,承担着数据清洗、指导超参数确定、提升模型效果的核心作用。本文将系统梳理文本预处理的核心环节与实现方法,帮助读者全面掌握这一基础且关键的技术。

一、文本处理的基本方法

文本处理的核心是将原始文本拆解为机器可理解的基础单元,主要包含分词、命名实体识别(NER)、词性标注(POS)三大核心环节。

1. 分词

分词是将连续的字序列按规范重组为词序列的过程,是语意理解的基础。英文因天然空格分隔符无需复杂分词,而中文需精准寻找分词边界。主流分词工具为 jieba,支持三种核心模式:

  • 精确模式:贴合人类词汇表达习惯,是最常用的分词方式;
  • 全模式:尽可能切分出所有可能成词的词汇;
  • 搜索引擎模式:在精确模式基础上对长粒度词汇二次切分。同时,jieba 支持繁体中文分词,还可通过加载自定义词典优化分词效果,自定义词典格式为「词语 词频(可选) 词性(可选)」。

python

运行

import jieba
content = "我喜欢学习"
# 精确模式(返回列表)
print(jieba.lcut(content, cut_all=False))
# 全模式
print(jieba.lcut(content, cut_all=True))
# 搜索引擎模式
print(jieba.lcut_for_search(content))
# 加载自定义词典
jieba.load_userdict("自定义词典路径")
print(jieba.lcut(content))

2. 命名实体识别(NER)

命名实体识别旨在从文本中提取人名、地名、机构名、时间、日期等专有名词,是 NLP 高阶任务的重要基础。常见的命名实体包含 7 大类,其实现核心分为两步:第一步是命名实体边界识别(token 级分类任务),第二步是对识别出的 span 进行分类(句子级分类任务)。

3. 词性标注(POS)

词性标注是对分词后的每个词汇标注词性(动词、名词、形容词等),jieba 的 posseg 模块可便捷实现该功能:

python

运行

import jieba.posseg as pseg
content = "我喜欢学习"
result = pseg.lcut(content)
for word, flag in result:
    print(f"词汇:{word},词性:{flag}")

二、文本张量的表示方法

将文本转换为向量(张量)是模型能处理文本的前提,核心有 One-Hot、Word2Vec、Word Embedding 三种方式。

1. One-Hot(独热编码)

为词表中每个词汇生成一个长度为词表大小的向量,向量中仅对应位置为 1,其余为 0。优点是简单易理解,缺点是无法体现词汇相似度,且大语料下占用资源极高。

python

运行

import jieba
from tensorflow.keras.preprocessing.text import Tokenizer

def onehot_gen(sent: str):
    # 构建词表
    vocabs = list(set(jieba.lcut(sent)))
    # 实例化Tokenizer并拟合词表
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(vocabs)
    # 生成每个词汇的One-Hot编码
    for vocab in vocabs:
        zero_list = [0] * len(vocabs)
        idx = tokenizer.word_index[vocab] - 1  # Tokenizer索引从1开始
        zero_list[idx] = 1
        print(f"{vocab}\t{zero_list}")

sent = '两只黄鹂鸣翠柳,一行白鹭上青天。'
onehot_gen(sent)

2. Word2Vec

Word2Vec 是无监督的词向量训练方法,通过训练模型将参数矩阵作为词向量,核心有两种训练方式:

  • CBOW:利用上下文词汇预测中间目标词;
  • Skip-gram:利用中间词预测上下文词汇,每个窗口更新 n-1 次,训练更充分。

可通过 FastText 工具快速实现 Word2Vec 训练:

python

运行

import fasttext

# 训练并保存模型
model = fasttext.train_unsupervised('./data/fil9', model="cbow", dim=300)
model.save_model('./data/fil9.bin')

# 加载模型并查询词向量、邻近词
model = fasttext.load_model('./data/fil9.bin')
print("the的词向量:", model.get_word_vector("the"))
print("sports的邻近词:", model.get_nearest_neighbors("sports"))

3. Word Embedding(词嵌入)

针对 Word2Vec 静态词向量无法处理多义词的问题,Word Embedding 通过神经网络的 Embedding 层生成动态词向量,向量参数随模型训练迭代更新。

python

运行

import torch
import torch.nn as nn
import jieba
from tensorflow.keras.preprocessing.text import Tokenizer

sentences = ['阿里巴巴是一家上市公司,旗下有天猫品牌。', "我爱自然语言处理"]
# 分词
word_list = [jieba.lcut(s) for s in sentences]
# 构建词汇映射
tokenizer = Tokenizer()
tokenizer.fit_on_texts(word_list)
sequence2id = tokenizer.texts_to_sequences(word_list)

# 创建Embedding层(词汇量×向量维度)
embed = nn.Embedding(num_embeddings=len(tokenizer.word_index), embedding_dim=8)
# 查看词汇对应的词向量
for idx in range(len(tokenizer.index_word)):
    word = tokenizer.index_word[idx + 1]
    vec = embed(torch.tensor(idx))
    print(f"{word}:{vec}")

三、文本语料的数据分析

数据分析是理解语料、指导模型超参数设定的关键,核心包含三类分析:

1. 标签数量分析

用于判断样本类别是否均衡,若类别分布差异过大,需通过增删数据解决。可借助 seaborn 绘制计数图直观展示:

python

运行

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

plt.style.use('fivethirtyeight')
train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
# 绘制标签分布
sns.countplot(x="label", data=train_data, hue="label")
plt.title("训练集标签分布")
plt.show()

2. 句子长度分析

模型通常要求固定长度的输入,通过分析句子长度分布,可确定文本补齐 / 截断的阈值。可通过柱状图、核密度图、散点图展示:

python

运行

# 添加句子长度列
train_data["sentence_length"] = train_data["sentence"].apply(len)
# 柱状图展示长度分布
sns.countplot(x="sentence_length", data=train_data)
plt.xticks([])
plt.show()
# 核密度图展示分布趋势
sns.displot(x="sentence_length", data=train_data, kde=True)
plt.show()

3. 词频统计和关键词词云

词频统计可掌握语料的词汇规模,词云能直观发现脏数据。以形容词词云为例:

python

运行

from wordcloud import WordCloud
from itertools import chain
import jieba.posseg as pseg

# 提取形容词
def get_a_list(text):
    return [g.word for g in pseg.lcut(text) if g.flag == "a"]

# 生成词云
def gen_wordcloud(word_list):
    wc = WordCloud(font_path='SimHei.ttf', max_words=100, background_color="white")
    wc.generate(" ".join(word_list))
    plt.imshow(wc, interpolation="bilinear")
    plt.axis("off")
    plt.show()

# 积极样本形容词词云
p_train = train_data[train_data["label"] == 1]["sentence"]
p_a_words = list(chain(*p_train.apply(get_a_list)))
gen_wordcloud(p_a_words)

四、文本特征处理

1. 添加 N-gram 特征

将 n 个连续相邻的词汇组合为新特征,丰富文本表示维度(如 2-gram:「我爱」「爱黑马」):

python

运行

def add_n_gram(word_list, n=2):
    return set(zip(*[word_list[i:] for i in range(n)]))

print(add_n_gram([1, 3, 2, 1, 5, 3]))

2. 文本长度规范

通过补齐(填充 0)或截断,将文本统一为模型要求的长度:

python

运行

from keras.preprocessing import sequence

# 统一长度为10,后置填充、前置截断
x_train = [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1], [2, 32, 1, 23, 1]]
x_train_padded = sequence.pad_sequences(x_train, maxlen=10, padding="post", truncating="pre")
print(x_train_padded)

五、文本数据增强

回译数据增强是常用方式,通过「中文→韩文→英文→中文」的翻译循环扩展数据集,解决样本量不足的问题,尤其适用于小语料场景。

总结

文本预处理是 NLP 模型训练的基础,其质量直接决定模型效果。从基础的分词、NER、POS,到张量表示的 One-Hot、Word2Vec、Embedding,再到数据分析、特征处理和数据增强,每个环节都需结合业务场景灵活调整。只有做好文本预处理,才能让后续的模型训练事半功倍,真正发挥 NLP 技术的价值。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐