人工智能之语言领域 自然语言处理 第四章 文本表示方法

人工智能之语言领域

第四章 文本表示方法


文章目录

  • 人工智能之语言领域
  • [前言 文本表示方法](#前言 文本表示方法)
    • [4.1 传统离散表示方法](#4.1 传统离散表示方法)
      • [4.1.1 词袋模型(BoW)与词频统计](#4.1.1 词袋模型(BoW)与词频统计)
      • [4.1.2 TF-IDF模型:原理与实现](#4.1.2 TF-IDF模型:原理与实现)
      • [4.1.3 n-gram模型:上下文窗口与语义捕捉](#4.1.3 n-gram模型:上下文窗口与语义捕捉)
    • [4.2 分布式表示方法(词嵌入)](#4.2 分布式表示方法(词嵌入))
      • [4.2.1 经典词嵌入模型](#4.2.1 经典词嵌入模型)
        • [4.2.1.1 Word2Vec:CBOW 与 Skip-gram](#4.2.1.1 Word2Vec:CBOW 与 Skip-gram)
        • [4.2.1.2 GloVe:全局词频与局部上下文结合](#4.2.1.2 GloVe:全局词频与局部上下文结合)
        • [4.2.1.3 FastText:子词级别的表示](#4.2.1.3 FastText:子词级别的表示)
      • [4.2.2 词嵌入的训练与调优](#4.2.2 词嵌入的训练与调优)
      • [4.2.3 句嵌入与篇章嵌入基础](#4.2.3 句嵌入与篇章嵌入基础)
    • [4.3 现代上下文相关表示](#4.3 现代上下文相关表示)
      • [4.3.1 预训练模型的表示逻辑](#4.3.1 预训练模型的表示逻辑)
      • [4.3.2 表示向量的下游适配方法](#4.3.2 表示向量的下游适配方法)
    • 补充:文本表示方法演进对比
    • 小结
  • 资料关注

前言 文本表示方法

在自然语言处理(NLP)中,文本表示是将人类可读的语言转化为计算机可计算的数值形式的核心步骤。没有合适的表示,模型就无法"理解"语言。本章将系统介绍从传统离散表示到现代上下文相关表示的演进路径,涵盖原理、实现、优缺点及代码示例,帮助你掌握如何为不同任务选择合适的文本表示方法。


4.1 传统离散表示方法

传统方法将文本视为符号集合,忽略语序和语义,但因其简单高效,仍在某些场景(如关键词检索、基线模型)中广泛使用。

4.1.1 词袋模型(BoW)与词频统计

核心思想

  • 忽略词序,仅统计每个词在文档中出现的次数。
  • 文档表示为一个高维稀疏向量,维度 = 词汇表大小。

🌰 示例:

词汇表:["我", "喜欢", "自然语言", "处理", "AI"]

句子:"我喜欢自然语言处理,我也喜欢AI"

→ 向量:[2, 2, 1, 1, 1]

python 复制代码
from sklearn.feature_extraction.text import CountVectorizer

corpus = [
    "我喜欢自然语言处理",
    "我也喜欢AI",
    "自然语言处理很有趣"
]

vectorizer = CountVectorizer(token_pattern=r'(?u)\b\w+\b')  # 中文需自定义分词
# 实际中应先分词,此处简化
corpus_seg = [" ".join(list(s)) for s in corpus]  # 按字切分(仅演示)

X = vectorizer.fit_transform(corpus_seg)
print("词汇表:", vectorizer.get_feature_names_out())
print("BoW矩阵:\n", X.toarray())

⚠️ 缺陷:

  • 维度灾难(词汇表大时向量极稀疏)
  • 无法捕捉语义("喜欢"和"热爱"被视为无关)

4.1.2 TF-IDF模型:原理与实现

TF-IDF(Term Frequency--Inverse Document Frequency) 改进 BoW,降低常见词权重,提升区分性词的重要性。

  • TF(词频):词在文档中出现频率
  • IDF(逆文档频率)log(总文档数 / 包含该词的文档数)

✅ 直觉:

"的"在所有文档都出现 → IDF 小 → 权重低

"BERT"只在一篇出现 → IDF 大 → 权重高

python 复制代码
from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer(token_pattern=r'(?u)\b\w+\b')
X_tfidf = tfidf.fit_transform(corpus_seg)

print("TF-IDF 矩阵:\n", X_tfidf.toarray().round(3))
# 输出每篇文档中各词的TF-IDF权重

💡 应用:搜索引擎排序、关键词提取、文本相似度(余弦相似度)


4.1.3 n-gram模型:上下文窗口与语义捕捉

n-gram 将连续 n 个词作为单元,部分保留局部语序。

  • unigram (1-gram):单个词(即 BoW)
  • bigram (2-gram):"自然 语言"、"语言 处理"
  • trigram (3-gram):"自然 语言 处理"
python 复制代码
from sklearn.feature_extraction.text import CountVectorizer

ngram_vec = CountVectorizer(ngram_range=(1, 2), token_pattern=r'\S+')
# 假设已分词为列表
corpus_tokenized = [["我", "喜欢", "自然语言", "处理"], ["自然语言", "处理", "很", "有趣"]]
corpus_str = [" ".join(doc) for doc in corpus_tokenized]

X_ngram = ngram_vec.fit_transform(corpus_str)
print("n-gram 特征:", ngram_vec.get_feature_names_out())
print("矩阵:\n", X_ngram.toarray())

✅ 优点:捕捉局部搭配(如"机器学习")

❌ 缺点:维度爆炸,仍无法处理长距离依赖


4.2 分布式表示方法(词嵌入)

分布式表示(Distributed Representation)将词映射为稠密低维向量,相似词在向量空间中距离相近,突破了离散表示的局限。

4.2.1 经典词嵌入模型

4.2.1.1 Word2Vec:CBOW 与 Skip-gram

由 Google 于 2013 年提出,基于局部上下文预测

模型 输入 → 输出 适用场景
CBOW 上下文词 → 目标词 数据少、高频词
Skip-gram 目标词 → 上下文词 数据多、低频词

Skip-gram
目标词
Predict 上下文1
Predict 上下文2
CBOW
上下文词1
Average
上下文词2
Predict 目标词

训练目标:最大化上下文共现概率。

python 复制代码
# 使用 gensim 训练 Word2Vec
from gensim.models import Word2Vec

sentences = [["我", "喜欢", "自然语言", "处理"],
             ["自然语言", "处理", "很", "有趣"],
             ["AI", "改变", "世界"]]

model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, sg=1)  # sg=1 表示 Skip-gram
print("'自然语言' 的向量:", model.wv['自然语言'])
print("与'处理'最相似的词:", model.wv.most_similar('处理', topn=2))

🔍 注意:实际需大规模语料(如 Wikipedia)才能学出高质量向量。


4.2.1.2 GloVe:全局词频与局部上下文结合

由 Stanford 提出(2014),直接建模词共现矩阵

  • 构建全局共现矩阵 X ,其中 X_{ij} = 词 i 和 j 共同出现的次数
  • 优化目标: w_i\^T \\tilde{w}_j + b_i + \\tilde{b}*j \\approx \\log X*{ij}

✅ 优点:利用全局统计信息,训练更稳定

❌ 缺点:对低频词共现噪声敏感

python 复制代码
# GloVe 需使用官方 C 代码训练,但可加载预训练模型
# 此处展示加载方式(需下载 glove.6B.100d.txt)
# import numpy as np
# embeddings_index = {}
# with open('glove.6B.100d.txt', encoding='utf8') as f:
#     for line in f:
#         values = line.split()
#         word = values[0]
#         coefs = np.asarray(values[1:], dtype='float32')
#         embeddings_index[word] = coefs

4.2.1.3 FastText:子词级别的表示

由 Facebook 提出(2016),将词拆分为字符 n-gram(subword)。

  • "apple" → <ap, app, ppl, ple, le>
  • 词向量 = 所有子词向量之和

✅ 优势:

  • 能表示未登录词(OOV):如"apples"可通过"appl"+"ples"近似
  • 对形态丰富语言(如德语、阿拉伯语)效果显著
python 复制代码
# 使用 gensim 的 FastText
from gensim.models import FastText

fasttext_model = FastText(sentences, vector_size=100, window=5, min_count=1)
print("OOV 词 '自然语言学' 的向量(即使未出现):")
print(fasttext_model.wv['自然语言学'])  # 不会报错!

4.2.2 词嵌入的训练与调优

关键超参数

  • vector_size:向量维度(通常 100--300)
  • window:上下文窗口大小(中文建议 5--10)
  • min_count:过滤低频词(避免噪声)
  • sg:0=CBOW, 1=Skip-gram

调优技巧

  • 使用预训练向量初始化(迁移学习)
  • 在下游任务上微调(fine-tune) 词向量
  • 对中文,确保输入为分词后序列

4.2.3 句嵌入与篇章嵌入基础

词向量无法直接表示句子。常用聚合方法:

方法 描述 缺点
平均池化 对句中所有词向量求均值 忽略词序
TF-IDF 加权平均 用 TF-IDF 作为权重 仍无序
SIF(Smooth Inverse Frequency) 改进加权,去除主成分 效果较好
python 复制代码
import numpy as np

def sentence_embedding(words, model, method='average'):
    vectors = []
    for w in words:
        if w in model.wv:
            vectors.append(model.wv[w])
    if not vectors:
        return np.zeros(model.vector_size)
    if method == 'average':
        return np.mean(vectors, axis=0)
    # 可扩展 TF-IDF 加权等

sent1 = ["自然语言", "处理", "很", "有趣"]
emb1 = sentence_embedding(sent1, model)
print("句向量维度:", emb1.shape)  # (100,)

🚀 进阶方案:Sentence-BERTInferSentSimCSE(见 4.3 节)


4.3 现代上下文相关表示

传统词嵌入是静态 的("苹果"在任何句子中向量相同),而现代预训练模型提供动态上下文相关表示

4.3.1 预训练模型的表示逻辑

BERT 为例:

  • 输入:[CLS] 我 喜欢 苹果 [SEP]
  • 输出:每个 token 对应一个向量(如"苹果"在"吃苹果" vs "买苹果手机"中不同)
  • [CLS] 向量常用于句子级任务

Token IDs
Word + Position + Segment Embedding
Transformer Encoder x12
Contextualized Vectors

CLS\] Vector → Sentence Representation Token Vectors → NER, SRL... > ✅ 优势: > > * 一词多义自动区分 > * 捕捉长距离依赖 > * 支持多种下游任务 ```python # 使用 transformers 库获取 BERT 句向量 from transformers import AutoTokenizer, AutoModel import torch tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese") model = AutoModel.from_pretrained("bert-base-chinese") text = "我喜欢自然语言处理" inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True) with torch.no_grad(): outputs = model(**inputs) cls_vector = outputs.last_hidden_state[:, 0, :] # [CLS] 向量 print("BERT 句向量形状:", cls_vector.shape) # torch.Size([1, 768]) ``` > 🌐 中文推荐模型:`bert-base-chinese`、`hfl/chinese-roberta-wwm-ext`、`Langboat/mengzi-bert-base-fin` *** ** * ** *** #### 4.3.2 表示向量的下游适配方法 预训练向量不能直接用于任务,需**适配(Adaptation)**: | 方法 | 说明 | 适用场景 | |------------------------------|----------------|------------| | **特征提取(Feature Extraction)** | 固定预训练模型,只训练任务头 | 数据少、计算资源有限 | | **微调(Fine-tuning)** | 端到端训练整个模型 | 数据充足、追求高性能 | | **Prompt Tuning** | 设计提示模板,引导模型输出 | 少样本学习 | ```python # 微调示例:文本分类(使用 Hugging Face Trainer) from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments model = AutoModelForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=2) # 后续配置数据集、训练参数即可微调 ``` > 💡 实践建议: > > * 小数据集 → 冻结 BERT,只训分类头 > * 大数据集 → 全模型微调 > * 超大数据 → 使用 LoRA 等参数高效微调技术 *** ** * ** *** ### 补充:文本表示方法演进对比 1950s : 词袋模型 (BoW) 1970s : TF-IDF 1990s : n-gram 2013 : Word2Vec 2014 : GloVe 2016 : FastText 2018 : BERT (上下文相关) 2020+ : Sentence-BERT, SimCSE, Embedding-as-Service 文本表示方法演进 *** ** * ** *** ### 小结 文本表示方法经历了从**离散→稠密→上下文感知**的演进: * **传统方法**(BoW/TF-IDF)简单有效,适合基线或资源受限场景; * **词嵌入**(Word2Vec/GloVe/FastText)引入语义相似性,是深度学习时代的基石; * **预训练模型**(BERT 等)提供动态、深层语义表示,已成为现代 NLP 的标准输入。 选择表示方法时,需权衡**任务需求、数据规模、计算资源** 。未来方向包括**多模态表示** 、**知识增强嵌入** 和**高效推理嵌入**。 *** ** * ** *** *** ** * ** *** ## 资料关注 咚咚王 《Python 编程:从入门到实践》 《利用 Python 进行数据分析》 《算法导论中文第三版》 《概率论与数理统计(第四版) (盛骤) 》 《程序员的数学》 《线性代数应该这样学第 3 版》 《微积分和数学分析引论》 《(西瓜书)周志华-机器学习》 《TensorFlow 机器学习实战指南》 《Sklearn 与 TensorFlow 机器学习实用指南》 《模式识别(第四版)》 《深度学习 deep learning》伊恩·古德费洛著 花书 《Python 深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》 《深入浅出神经网络与深度学习 +(迈克尔·尼尔森(Michael+Nielsen)》 《自然语言处理综论 第 2 版》 《Natural-Language-Processing-with-PyTorch》 《计算机视觉-算法与应用(中文版)》 《Learning OpenCV 4》 《AIGC:智能创作时代》杜雨 +\&+ 张孜铭 《AIGC 原理与实践:零基础学大语言模型、扩散模型和多模态模型》 《从零构建大语言模型(中文版)》 《实战 AI 大模型》 《AI 3.0》

相关推荐
deephub2 小时前
LangGraph vs Semantic Kernel:状态图与内核插件的两条技术路线对比
人工智能·python·深度学习·大语言模型·agent
文心快码 Baidu Comate2 小时前
Comate 4.0的自我进化:后端“0帧起手”写前端、自己修自己!
前端·人工智能·后端·ai编程·文心快码·ai编程助手
搬砖者(视觉算法工程师)2 小时前
3D Gaussian Splatting高斯泼溅技术简单介绍
人工智能
ShineWinsu2 小时前
2026年AI Agent变现新思路:告别传统电商,拥抱自动化矩阵与服务套利
运维·人工智能·自动化
数据中穿行2 小时前
基于Cesium的综合态势显示系统总体方案
人工智能
数据中穿行2 小时前
基于osgEarth的综合态势显示系统总体方案
人工智能
GEO_Huang2 小时前
工作流定制选数谷,Agentoffice 让办公快人一步
大数据·人工智能·aigc·rpa·geo
hsg772 小时前
简述:openclaw应用二三事
人工智能·学习
razelan2 小时前
本地大模型系列:1.配置本地lm Studio的大模型助手(another)
人工智能·ollama