One-Hot、BOW、TF-IDF、N-Gram区别

发布于:2025-06-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

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]]

总结与关系

  1. One-Hot 是最基础的原子表示。

  2. BOW 是 One-Hot 在文档级别的频率扩展。 BOW 本质上就是基于 Unigram (1-gram)。

  3. TF-IDF 是 BOW 的重要加权改进版。 它在词频(TF)基础上引入了逆文档频率(IDF)来抑制常见词、提升关键词语义权重。TF-IDF 通常作用于 Unigram,但也可以作用于 N-Gram。

  4. N-Gram 改变了基本单元。 它不是基于单个词,而是基于连续的词序列(词组/片段)。这使其能够捕捉局部词序信息。N-Gram 模型本身只定义了单元,通常需要结合 BOW 或 TF-IDF 来形成文档的向量表示(即 N-Gram BOW 或 N-Gram TF-IDF)。

  5. 它们都缺乏深层次语义理解。 这些方法都无法真正理解单词的含义(语义)或复杂的上下文关系。捕捉语义需要更高级的技术,如词嵌入(Word2Vec, GloVe)和上下文相关的语言模型(BERT, GPT)。

选择哪种方法取决于具体任务的需求、计算资源以及对词序和语义的要求。TF-IDF 和 N-Gram (通常是 Bigram/TF-IDF) 在传统机器学习方法中应用非常广泛且有效。而深度学习方法(如基于Transformer的模型)则能更好地捕捉语义和长距离依赖。


网站公告

今日签到

点亮在社区的每一天
去签到