1. One-Hot Encoding (独热编码)
核心思想: 为语料库(所有文档的集合)中的每个唯一单词创建一个维度。对于一个特定的单词,在其对应的维度上标记为
1
,在所有其他维度上标记为0
。表示: 一个非常长的二进制向量(大部分是0),长度等于语料库的词汇表大小(|V|)。
特点:
简单直观: 最容易理解。
高维稀疏: 向量维度极高(词汇量大),且每个向量中只有少数几个位置是1(文档中出现的词),其余都是0,极其稀疏。
无词序信息: 完全丢失了单词在句子中的顺序信息。“猫吃鱼”和“鱼吃猫”的表示完全一样。
无频率信息: 只记录单词是否出现(1),不记录出现的次数。出现一次和出现十次没有区别。
无语义信息: 无法捕捉单词之间的任何语义关系(同义词、反义词等)。“好”和“优秀”被视为完全不同的、无关的维度。
应用场景: 非常基础的文本表示,常用于类别型特征(如标签)的编码。在文本中单独使用较少,常作为构建其他模型(如BOW)的基础组件或用于表示类别标签。
例子:
词汇表:
[我, 爱, 自然, 语言, 处理]
(|V| = 5)句子 "我爱自然语言处理" 的 One-Hot 向量:
[1, 1, 1, 1, 1]
句子 "我爱编程" 的 One-Hot 向量:
[1, 1, 0, 0, 0]
(假设词汇表不变,且"编程"不在词汇表中则无法表示,这是其局限)
2. Bag-of-Words (词袋模型, BOW)
核心思想: 建立在 One-Hot 的基础上。忽略单词的顺序、语法和上下文,只关心词汇表中每个单词在文档中出现的频率。
表示: 一个长度为 |V| 的整数向量(或有时是实数向量)。每个位置的值表示对应单词在当前文档中出现的次数。
特点:
简单高效: 计算相对简单。
包含频率信息: 比 One-Hot 更进一步,记录了单词出现的次数。
依然高维稀疏: 维度与词汇表大小 |V| 相同,向量中大部分位置仍然是0(该文档未出现的词)。
依然无词序信息: 和 One-Hot 一样,完全丢失了单词顺序。"猫吃鱼"和"鱼吃猫"的 BOW 向量相同。
依然无语义信息: 无法捕捉单词之间的语义关系。
受常见词影响大: "的"、"是"、"在"等常见词(停用词)在所有文档中频繁出现,在向量中占据很大的值,但它们通常携带的信息量很少,可能会淹没真正重要的词。
应用场景: 文本分类(如垃圾邮件识别、情感分析初探)、主题建模(如LDA的基础)等对词序要求不高且需要简单快速模型的任务。
例子 (续用One-Hot词汇表):
词汇表:
[我, 爱, 自然, 语言, 处理]
(|V| = 5)句子 "我爱自然语言处理" 的 BOW 向量:
[1, 1, 1, 1, 1]
句子 "我爱自然,自然美丽" 的 BOW 向量:
[1, 1, 2, 0, 0]
("自然"出现2次)
3. TF-IDF (词频-逆文档频率)
核心思想: 对 BOW 的重要改进。旨在解决 BOW 中常见词权重过高的问题。它认为:
一个词在当前文档中出现的次数越多(TF - Term Frequency,词频),它对描述该文档越重要。
但是,如果这个词在整个语料库的很多文档中都出现(DF - Document Frequency,文档频率很高),那么它就越常见、越普通,区分不同文档的能力就越弱。因此需要降低其权重。
IDF - Inverse Document Frequency (逆文档频率) 就是用来惩罚这种常见词的。IDF 值与该词的文档频率 DF 成反比。
IDF(t) = log(N / (DF(t) + 1))
(N 是语料库中文档总数,DF(t) 是包含词 t 的文档数,+1 避免除0)。
计算: 对于文档
d
中的词t
:TF(t, d)
: 词t
在文档d
中出现的频率(可以是原始计数、标准化计数、对数化等)。IDF(t)
:log(N / (DF(t) + 1))
。TF-IDF(t, d) = TF(t, d) * IDF(t)
表示: 一个长度为 |V| 的实数向量。每个位置的值是相应单词在当前文档中的 TF-IDF 权重。
特点:
降低常见词权重,提高重要词权重: 这是 TF-IDF 的核心优势。常见词(如"的"、"是")虽然 TF 可能高,但 IDF 极低(因为 DF 极高),导致其 TF-IDF 值很低。而只在少数特定文档中频繁出现的词(如专业术语、主题关键词)会同时拥有较高的 TF 和较高的 IDF,因此获得很高的 TF-IDF 值。
包含频率信息: 基于 TF。
考虑语料库全局信息: 通过 IDF 引入了语料库级别的统计信息。
依然高维稀疏: 维度 |V| 大,向量稀疏。
依然无词序信息: 和 BOW/One-Hot 一样。
依然无语义信息: 无法捕捉语义关系。
应用场景: 信息检索(搜索引擎排序)、文本分类、关键词提取、文档相似度计算等。是 BOW 的强有力替代者,在实践中应用非常广泛。
例子 (简化):
假设语料库有 1000 个文档 (N=1000)。
词 "自然" 出现在 100 个文档中 (DF=100),其
IDF(自然) = log(1000 / 101) ≈ log(9.9) ≈ 2.29
。词 "的" 出现在 990 个文档中 (DF=990),其
IDF(的) = log(1000 / 991) ≈ log(1.01) ≈ 0.01
。在某个特定文档 d 中:
"自然" 出现了 5 次 (
TF(自然, d) = 5
) ->TF-IDF(自然, d) ≈ 5 * 2.29 = 11.45
。"的" 出现了 20 次 (
TF(的, d) = 20
) ->TF-IDF(的, d) ≈ 20 * 0.01 = 0.2
。
尽管"的"在文档 d 中出现次数更多 (TF更高),但其 TF-IDF 权重远低于"自然",因为"自然"更能代表该文档的特性。
4. N-Gram
核心思想: 不同于前三种方法(主要关注单个词),N-Gram 关注连续的词序列。它将文本视为由连续的 N 个单词组成的单元(称为 gram)构成的序列。
Unigram (1-gram)
: 单个词。本质上就是 BOW/TF-IDF 所基于的单元。Bigram (2-gram)
: 连续的两个词。例如:"我爱","爱自然","自然语言","语言处理"。Trigram (3-gram)
: 连续的三个词。例如:"我爱自然","爱自然语言","自然语言处理"。以此类推。
表示: 构建一个基于 N-Gram 的词汇表。然后可以用 BOW 或 TF-IDF 的方式来表示文档:
N-Gram BOW: 向量长度为 N-Gram 词汇表大小,每个位置的值是相应 N-Gram 在当前文档中出现的次数。
N-Gram TF-IDF: 向量长度为 N-Gram 词汇表大小,每个位置的值是相应 N-Gram 在当前文档中的 TF-IDF 权重。
特点:
捕捉局部词序信息: 这是 N-Gram 最大的优势!通过组合连续的词,它部分地保留了单词之间的顺序和上下文信息。使用 Bigram 就能区分"猫吃鱼"("猫吃", "吃鱼")和"鱼吃猫"("鱼吃", "吃猫")。
缓解未登录词问题: 即使一个词没在训练语料中出现过,包含它的 N-Gram(特别是较低阶的)可能出现过,模型仍能处理。
维度爆炸: N-Gram 词汇表的大小远大于单词词汇表的大小(|V|^N 量级)。对于 Bigram,词汇表大小约为 |V|^2;Trigram 约为 |V|^3。这导致特征向量维度急剧膨胀(比 One-Hot/BOW/TF-IDF 高得多),稀疏性也更高。实际应用中 N 通常取 2 或 3,很少超过 5。
语义信息有限: 虽然捕捉了局部共现,但仍然不能很好地理解深层次的语义关系或长距离依赖。例如,"好"和"优秀"作为不同词,它们的 N-Gram 仍然是不同的特征。
应用场景: 需要捕捉局部词序的任务,如:
拼写检查(纠正错词需要前后文)
机器翻译(短语结构)
语音识别(声学模型与语言模型结合)
基础的文本生成(预测下一个词)
结合 BOW/TF-IDF 用于文本分类(提供比 unigram 更丰富的特征)
关键区别总结表
特性 | One-Hot | BOW (词袋模型) | TF-IDF | N-Gram | ||
---|---|---|---|---|---|---|
基本单元 | 单个词 | 单个词 | 单个词 | 连续的 N 个词序列 | ||
核心信息 | 词是否存在 (0/1) | 词在当前文档中的频率 | 词在当前文档中的重要性 (TF * IDF) | 局部词序 (上下文片段) | ||
频率信息 | ❌ (只有存在性) | ✅ (词频) | ✅ (加权词频) | ✅ (N-Gram 频次或加权频次) | ||
词序信息 | ❌ | ❌ | ❌ | ✅ (在 N 窗口内) | ||
语义信息 | ❌ | ❌ | ❌ | ⚠️ (有限,仅局部共现) | ||
维度/稀疏性 | 极高维 / 极稀疏 | 高维 / 稀疏 | 高维 / 稀疏 | 极高维 ( | V | ^N) / 极稀疏 |
解决常见词问题 | ❌ | ❌ | ✅ (IDF惩罚) | ❌ (本身不解决,可结合TF-IDF) | ||
主要优势 | 简单,表示类别 | 简单,包含词频 | 强调区分性强的词 | 捕捉局部上下文和顺序 | ||
主要缺点 | 高维稀疏,无频率/顺序/语义 | 无顺序/语义,受常见词影响大 | 无顺序/语义 | 维度爆炸,仅局部顺序 | ||
关系 | BOW 的基础 | 可视为 Unigram (1-gram) 频率 | 常作用于 Unigram 或 N-Gram | 可结合 BOW/TF-IDF 使用 |
代码示例
1. One-Hot 编码
代码示例
Python
from sklearn.preprocessing import OneHotEncoder # 示例数据:3 个样本,每个样本是一个类别 data = [["cat"], ["dog"], ["cat"]] # 初始化 One-Hot 编码器 encoder = OneHotEncoder() encoded = encoder.fit_transform(data) # 输出结果 print("One-Hot 编码结果:\n", encoded.toarray()) print("类别映射:", encoder.categories_)
输出:
One-Hot 编码结果: [[1. 0.] [0. 1.] [1. 0.]] 类别映射: [array(['cat', 'dog'], dtype=object)]
2. BOW(Bag of Words,词袋模型)
代码示例
Pytho
from sklearn.feature_extraction.text import CountVectorizer # 示例文本 corpus = [ "the cat sat on the mat", "the dog sat on the log", "the cat and the dog sat" ] # 初始化词袋模型 vectorizer = CountVectorizer() X = vectorizer.fit_transform(corpus) # 输出结果 print("词汇表:", vectorizer.get_feature_names_out()) print("BOW 向量:\n", X.toarray())
输出:
词汇表: [and' 'cat' 'dog' 'log' 'mat' 'on' 'sat' 'the'] BOW 向量: [[0 1 0 0 1 1 1 2] [0 0 1 1 0 1 1 2] [1 1 1 0 0 1 1 3]]
3. TF-IDF(Term Frequency-Inverse Document Frequency)
代码示例
Python
from sklearn.feature_extraction.text import TfidfVectorizer # 使用相同的文本数据 vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(corpus) # 输出结果 print("词汇表:", vectorizer.get_feature_names_out()) print("TF-IDF 向量:\n", X.toarray())
输出:
词汇表: ['and' 'cat' 'dog' 'log' 'mat' 'on' 'sat' 'the'] TF-IDF 向量: [[0. 0.57735027 0. 0. 0.57735027 0.57735027 0.57735027 0. ] [0. 0. 0.57735027 0.57735027 0. 0.57735027 0.57735027 0. ] [0.68346878 0.34173439 0.34173439 0. 0. 0.34173439 0.34173439 0. ]]
4. N-Gram 模型
Python
from sklearn.feature_extraction.text import CountVectorizer # 使用 Bigram(ngram_range=(2,2)) vectorizer = CountVectorizer(ngram_range=(2, 2)) X = vectorizer.fit_transform(corpus) # 输出结果 print("Bigram 词汇表:", vectorizer.get_feature_names_out()) print("Bigram 向量:\n", X.toarray())
输出:
Bigram 词汇表: ['cat sat' 'dog sat' 'log the' 'mat the' 'on the' 'sat on' 'the cat' 'the dog' 'the log' 'the mat' 'the sat'] Bigram 向量: [[0 0 0 1 1 1 1 0 0 1 0] [0 0 1 0 1 1 0 1 1 0 0] [0 1 0 0 1 1 1 1 0 0 1]]
总结与关系
One-Hot 是最基础的原子表示。
BOW 是 One-Hot 在文档级别的频率扩展。 BOW 本质上就是基于 Unigram (1-gram)。
TF-IDF 是 BOW 的重要加权改进版。 它在词频(TF)基础上引入了逆文档频率(IDF)来抑制常见词、提升关键词语义权重。TF-IDF 通常作用于 Unigram,但也可以作用于 N-Gram。
N-Gram 改变了基本单元。 它不是基于单个词,而是基于连续的词序列(词组/片段)。这使其能够捕捉局部词序信息。N-Gram 模型本身只定义了单元,通常需要结合 BOW 或 TF-IDF 来形成文档的向量表示(即 N-Gram BOW 或 N-Gram TF-IDF)。
它们都缺乏深层次语义理解。 这些方法都无法真正理解单词的含义(语义)或复杂的上下文关系。捕捉语义需要更高级的技术,如词嵌入(Word2Vec, GloVe)和上下文相关的语言模型(BERT, GPT)。
选择哪种方法取决于具体任务的需求、计算资源以及对词序和语义的要求。TF-IDF 和 N-Gram (通常是 Bigram/TF-IDF) 在传统机器学习方法中应用非常广泛且有效。而深度学习方法(如基于Transformer的模型)则能更好地捕捉语义和长距离依赖。