自然语言处理 NLP 实战
文本分类/情感分析、命名实体识别 NER、文本摘要、机器翻译
NLP 任务概览
自然语言处理(Natural Language Processing,NLP)是人工智能领域的重要分支,致力于让计算机理解、生成和处理人类语言。根据输入输出形式的不同,NLP 核心任务可以分为三大类别:
| 任务类别 | 输入 | 输出 | 典型任务 |
|---|---|---|---|
| 句子级任务 | 单个句子或文本 | 分类标签或数值 | 文本分类、情感分析、文本蕴含 |
| 词元级任务 | 文本序列 | 每个词元的标签 | 命名实体识别、词性标注、分词 |
| 生成式任务 | 源文本 | 生成的目标文本 | 文本摘要、机器翻译、对话生成 |
当前 NLP 领域的主流范式是 预训练-微调(Pre-training + Fine-tuning):首先在大规模无标注语料上预训练一个语言模型(如 BERT、GPT、T5),然后在下游任务的小规模标注数据上进行微调。这一范式大幅降低了标注成本,并在几乎所有 NLP 基准上取得了最佳效果。
下面围绕四个经典任务展开,分别介绍任务定义、模型方案、评测指标和代码实践。
文本分类与情感分析
任务定义
文本分类是 NLP 中最基础的任务之一,目标是为给定的文本分配一个或多个类别标签。
- 情感极性分类:判断文本的情感倾向,通常为二分类(正面/负面)或三分类(正面/负面/中性)。
- 多标签分类:同一文本可能同时属于多个类别,例如一篇文章同时涉及"科技"和"教育"两个主题。
模型方案
基于预训练语言模型做文本分类的标准做法是在模型顶部添加一个线性分类头(Classification Head)。以 BERT 为例,取 [CLS] 标记的隐层表示,经过全连接层和 Softmax 得到类别概率分布。
常用模型:
- BERT:双向 Transformer 编码器,适合文本理解类任务。
- RoBERTa:BERT 的改进版本,采用动态 Mask 机制、更大的 batch size 和更多的训练数据,通常效果优于 BERT。
评测指标
| 指标 | 说明 | 适用场景 |
|---|---|---|
| 准确率(Accuracy) | 预测正确的样本数占总样本数的比例 | 类别均衡的数据集 |
| 精确率(Precision) | 预测为正类中真正为正类的比例 | 关注假阳性的场景 |
| 召回率(Recall) | 真正为正类中被预测为正类的比例 | 关注假阴性的场景 |
| F1 值 | 精确率和召回率的调和平均数 | 类别不均衡、需要综合评估的场景 |
| 混淆矩阵 | 以矩阵形式展示预测值与真实值的交叉统计 | 分析模型在各类别上的表现 |
代码示例
方式一:使用 pipeline 快速推理
from transformers import pipeline
classifier = pipeline(
"sentiment-analysis",
model="distilbert-base-uncased-finetuned-sst-2-english"
)
texts = [
"This product is absolutely amazing! I love it.",
"The service was terrible and the food was cold."
]
results = classifier(texts)
for text, result in zip(texts, results):
print(f"文本: {text}")
print(f"标签: {result['label']}, 置信度: {result['score']:.4f}")
print("-" * 40)方式二:基于预训练模型微调(核心训练循环)
from transformers import (
AutoTokenizer,
AutoModelForSequenceClassification,
Trainer,
TrainingArguments
)
# 加载预训练模型和分词器
model_name = "roberta-base"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(
model_name,
num_labels=3 # 三分类:正面、负面、中性
)
# 数据预处理
def preprocess_function(examples):
return tokenizer(
examples["text"],
truncation=True,
padding="max_length",
max_length=128
)
# 配置训练参数
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
save_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=32,
num_train_epochs=3,
weight_decay=0.01,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer,
)
trainer.train()命名实体识别 NER
任务定义
命名实体识别(Named Entity Recognition,NER)旨在从文本中识别出具有特定意义的实体,并将其归类到预定义的类别中。
常见实体类型:
| 实体类型 | 说明 | 示例 |
|---|---|---|
| 人名(PER) | 人物姓名 | 张三、Albert Einstein |
| 地名(LOC) | 地理位置 | 北京、太平洋 |
| 机构名(ORG) | 组织、公司、政府机构 | 联合国、Google |
| 时间(TIME) | 日期、时间表达 | 2024 年、下周三 |
标注格式
NER 数据通常采用序列标注的方式,主流标签体系有 BIO 和 BIOES 两种:
- BIO:B 表示实体开始(Begin),I 表示实体内部(Inside),O 表示非实体(Outside)。
- BIOES:在 BIO 基础上增加了 E(实体结尾,End)和 S(单字实体,Single)。
以 BIO 标注为例,"张三在北京大学工作" 的标注结果为:
| 张 | 三 | 在 | 北 | 京 | 大 | 学 | 工 | 作 | | B-PER | I-PER | O | B-ORG | I-ORG | I-ORG | I-ORG | O | O |
模型方案
BERT + CRF 是当前最主流的 NER 方案:
- BERT:作为编码器,为每个词元生成上下文相关的表示。
- CRF(条件随机场)层:在解码时引入标签之间的转移约束(如 I-PER 之前必须是 B-PER 或 I-PER),保证标签序列的合法性。
代码示例
from transformers import (
AutoTokenizer,
AutoModelForTokenClassification,
pipeline
)
# 加载 NER 模型
model_name = "dslim/bert-base-NER"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForTokenClassification.from_pretrained(model_name)
# 使用 pipeline 进行推理
ner_pipeline = pipeline(
"ner",
model=model,
tokenizer=tokenizer,
aggregation_strategy="simple" # 合并同一个实体的多个子词
)
text = "Elon Musk founded SpaceX in Hawthorne, California."
entities = ner_pipeline(text)
for entity in entities:
print(
f"实体: {entity['word']:15s} | "
f"类型: {entity['entity_group']:5s} | "
f"置信度: {entity['score']:.4f}"
)文本摘要
任务定义
文本摘要的目标是将长文本压缩为包含核心信息的短文本。根据摘要生成方式可分为两类:
| 类型 | 生成方式 | 特点 | 适用场景 |
|---|---|---|---|
| 抽取式(Extractive) | 从原文中选取重要句子组成摘要 | 忠实于原文,但缺乏连贯性 | 新闻摘要、文档摘要 |
| 生成式(Abstractive) | 理解原文后重新组织语言生成摘要 | 更接近人类表达,但可能偏离原文 | 报告总结、故事浓缩 |
模型方案
主流的生成式摘要模型均采用 Seq2Seq 架构:
| 模型 | 架构特点 | 优势 |
|---|---|---|
| BART | 去噪自编码器,结合 BERT 双向编码和 GPT 自回归解码 | 在摘要和翻译任务上表现优异 |
| T5 | 统一的 Text-to-Text 框架,所有任务统一为文本生成 | 灵活通用,多任务能力强 |
| Pegasus | 预训练目标为 Gap Sentence Generation,专门针对摘要优化 | 在多个摘要基准上达到最优 |
评测指标
ROUGE(Recall-Oriented Understudy for Gisting Evaluation)是文本摘要最常用的评测指标,通过比较生成摘要与参考摘要之间的 n-gram 重叠来评估质量:
- ROUGE-1:单字(unigram)的重叠召回率。
- ROUGE-2:二元组(bigram)的重叠召回率,衡量短语级别的匹配度。
- ROUGE-L:基于最长公共子序列(LCS)的评分,考虑句子的语序。
代码示例
from transformers import pipeline
# 加载摘要模型
summarizer = pipeline(
"summarization",
model="facebook/bart-large-cnn"
)
long_text = """
The Transformer architecture has revolutionized the field of natural language
processing. First introduced in the paper "Attention Is All You Need" by Vaswani
et al. in 2017, the Transformer relies entirely on self-attention mechanisms to
model relationships between words in a sequence, without using recurrence or
convolution. Since then, Transformer-based models such as BERT, GPT, and T5
have achieved state-of-the-art results on a wide range of NLP benchmarks.
These models are pre-trained on large text corpora and fine-tuned for specific
tasks, leading to significant improvements in tasks such as text classification,
named entity recognition, question answering, and machine translation.
"""
summary = summarizer(
long_text,
max_length=50,
min_length=20,
do_sample=False
)
print("原文长度:", len(long_text), "字符")
print("摘要:", summary[0]["summary_text"])
print("摘要长度:", len(summary[0]["summary_text"]), "字符")机器翻译
任务定义
机器翻译(Machine Translation,MT)的目标是将源语言文本自动转换为目标语言文本,同时保持语义不变。这是 NLP 中最具挑战性的任务之一,涉及对两种语言的深层理解。
模型方案
编码器-解码器架构是机器翻译的标准范式。编码器将源语言句子编码为上下文表示,解码器基于该表示逐词生成目标语言句子。Transformer 通过自注意力机制解决了长距离依赖问题,使并行训练成为可能,成为当前机器翻译的事实标准。
常用多语言翻译模型:
| 模型 | 支持的语种 | 特点 |
|---|---|---|
| M2M-100 | 100 种语言 | 支持任意语言之间的直接翻译,无需经过英语中介 |
| NLLB | 200 种语言 | Facebook 推出的 No Language Left Behind 项目模型 |
| MarianMT | 涵盖 Indo-European 语系 | 轻量级,针对特定语对优化,适合生产部署 |
评测指标
BLEU(Bilingual Evaluation Understudy)是机器翻译最广泛使用的自动评测指标。它通过计算生成译文与参考译文之间的 n-gram 精确匹配率来评估翻译质量。
BLEU 取值范围为 0 到 1(通常以百分比表示),值越高表明翻译质量越好。BLEU 的优点是计算快速、与人工评分有一定相关性,缺点是过度依赖 n-gram 精确匹配,对同义表达的变体不够敏感。
代码示例
from transformers import MarianMTModel, MarianTokenizer
# 指定翻译方向(中文 -> 英文)
model_name = "Helsinki-NLP/opus-mt-zh-en"
tokenizer = MarianTokenizer.from_pretrained(model_name)
model = MarianMTModel.from_pretrained(model_name)
# 待翻译文本
chinese_texts = [
"自然语言处理是人工智能领域的重要分支。",
"深度学习技术极大地推动了机器翻译的发展。"
]
# 编码与翻译
inputs = tokenizer(
chinese_texts,
return_tensors="pt",
padding=True,
truncation=True
)
translated = model.generate(**inputs)
# 解码输出
results = [
tokenizer.decode(t, skip_special_tokens=True)
for t in translated
]
for src, tgt in zip(chinese_texts, results):
print(f"源文: {src}")
print(f"译文: {tgt}")
print("-" * 40)各任务对比总结
| 维度 | 文本分类 | 命名实体识别 | 文本摘要 | 机器翻译 |
|---|---|---|---|---|
| 任务类型 | 句子级 | 词元级 | 生成式 | 生成式 |
| 输出形式 | 类别标签 | 标签序列 | 压缩文本 | 翻译文本 |
| 典型模型 | BERT, RoBERTa | BERT + CRF | BART, T5, Pegasus | M2M-100, NLLB, MarianMT |
| 主流评测指标 | Accuracy / F1 | F1 (实体级别) | ROUGE-1/2/L | BLEU |
| 标注成本 | 低(仅需标签) | 高(需逐词标注) | 高(需人工摘要) | 高(需双语平行语料) |
| 推理速度 | 快 | 中等 | 慢 | 慢 |
总结
本文涵盖了 NLP 四大核心实战任务:文本分类与情感分析、命名实体识别、文本摘要和机器翻译。每个任务都有其独特的任务定义、模型方案和评测体系。在实际工程中,选择合适的预训练模型和评测指标是项目成功的关键。随着大语言模型(LLM)的快速发展,许多 NLP 任务正在被统一到基于 Prompt 的生成式框架中,但理解上述经典范式仍然是深入学习和应用 NLP 技术的重要基础。