自然语言处理
→ 返回应用领域
自然语言处理(NLP)让机器能理解、生成和操作人类语言。大语言模型的出现统一了大多数 NLP 任务,但理解经典任务的定义和评估方式仍是必要的基础。
核心任务
| 任务 | 说明 | 代表场景 |
|---|---|---|
| 文本分类 | 给文本分配类别标签 | 情感分析、意图识别、垃圾过滤 |
| 命名实体识别(NER) | 识别文本中的人名/地名/机构名等 | 信息抽取、知识图谱 |
| 关系抽取 | 识别两个实体之间的关系 | ”苹果 → 创立 → 乔布斯” |
| 机器翻译 | 源语言 → 目标语言 | Google 翻译、DeepL |
| 文本摘要 | 压缩长文为短摘要 | 新闻摘要、会议纪要 |
| 问答系统 | 基于上下文回答问题 | 文档问答、知识库问答 |
| 信息检索 | 从文档集中找相关内容 | 搜索引擎、RAG |
| 对话系统 | 多轮对话管理 | 客服机器人、聊天助手 |
文本表示演进
One-Hot → 稀疏,无语义
↓
Word2Vec → 密集向量,捕捉词义相似性(2013)
↓
ELMo → 动态上下文表示(2018)
↓
BERT → 双向 Transformer 预训练(2018)
↓
GPT 系列 → 自回归生成,规模涌现(2020–)
↓
ChatGPT → RLHF 对齐,通用助手(2022–)
经典任务实现
文本分类(BERT Fine-tuning)
from transformers import (
AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
)
from datasets import Dataset
import torch
tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")
model = AutoModelForSequenceClassification.from_pretrained(
"hfl/chinese-roberta-wwm-ext",
num_labels=2, # 正面/负面
)
def tokenize(examples):
return tokenizer(examples["text"], truncation=True, max_length=128)
# 准备数据
data = Dataset.from_dict({
"text": ["这个产品很好用", "太差劲了,不推荐", "还行吧"],
"label": [1, 0, 1],
})
tokenized = data.map(tokenize, batched=True)
# 训练
args = TrainingArguments(
output_dir="./output",
num_train_epochs=3,
per_device_train_batch_size=16,
evaluation_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
)
trainer = Trainer(model=model, args=args, train_dataset=tokenized)
trainer.train()NER(命名实体识别)
from transformers import pipeline
ner = pipeline("ner", model="dslim/bert-base-NER", aggregation_strategy="simple")
text = "苹果公司的 Tim Cook 在北京发布了 iPhone 16。"
results = ner(text)
for entity in results:
print(f"{entity['word']}: {entity['entity_group']} ({entity['score']:.2f})")
# 输出:
# 苹果公司: ORG (0.98)
# Tim Cook: PER (0.99)
# 北京: LOC (0.97)
# iPhone 16: MISC (0.89)文本相似度
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
sentences = [
"今天天气真好",
"今天的气候非常不错",
"我喜欢编程",
]
embeddings = model.encode(sentences)
sim_matrix = cosine_similarity(embeddings)
# sentences[0] 和 sentences[1] 相似度高
print(sim_matrix[0][1]) # ~0.88
print(sim_matrix[0][2]) # ~0.15信息抽取流水线
import spacy
import json
nlp = spacy.load("zh_core_web_sm")
def extract_info(text: str) -> dict:
doc = nlp(text)
return {
# 命名实体
"entities": [
{"text": ent.text, "label": ent.label_, "start": ent.start_char}
for ent in doc.ents
],
# 关键名词短语
"noun_chunks": [chunk.text for chunk in doc.noun_chunks],
# 句子切分
"sentences": [sent.text for sent in doc.sents],
}
result = extract_info("马云于 1999 年在杭州创立了阿里巴巴集团。")
print(json.dumps(result, ensure_ascii=False, indent=2))评估指标
| 任务 | 指标 |
|---|---|
| 分类 | Accuracy、F1、AUC |
| NER | F1(实体级别)、Precision、Recall |
| 翻译 | BLEU、COMET |
| 摘要 | ROUGE-1/2/L |
| 问答 | EM(完全匹配)、F1(词重叠) |
| 生成 | 人工评估、LLM-as-Judge |
大模型时代的 NLP
LLM 通过 Prompt 可以直接处理几乎所有 NLP 任务,不再需要针对每个任务微调专门模型:
import anthropic
client = anthropic.Anthropic()
def extract_entities(text: str) -> list[dict]:
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
messages=[{
"role": "user",
"content": f"""从以下文本中抽取命名实体,输出 JSON 数组:
[{{"entity": "实体文本", "type": "PER/ORG/LOC/MISC"}}]
文本:{text}
只输出 JSON:"""
}]
)
import json
return json.loads(response.content[0].text)