1. N-Gram和TF-IDF:通俗易懂的解析
1.1 N-Gram:让AI学会"猜词"的技术
1.1.1 基本概念
N-Gram是一种让计算机理解语言规律的基础方法,主要用于预测文本中下一个可能出现的词。它的核心思想很简单:假设一个词的出现只和前面的几个词有关。
举个例子:
- "我想吃"后面接"苹果"的概率,可能比接"游泳"更高
- 输入法在你打出"dddd"时推荐"带带弟弟"就是基于这种原理
1.1.2 工作原理
- 分段统计:把文本拆成连续的词组合(比如2个词的"我吃",3个词的"我想吃"),统计每个组合出现的次数
- 计算概率:用"下一个词出现的次数除以当前组合出现的总次数"得到条件概率
- 处理零概率:给从未出现过的组合分配很小的概率,避免完全排除可能性
1.1.3 常见类型
- Unigram(一元组):单个词为一组(如"我"、“喜欢”)
- Bigram(二元组):两个连续词为一组(如"我喜欢"、“喜欢学习”)
- Trigram(三元组):三个连续词为一组(如"我喜欢学习")
1.1.4 应用场景
- 手机输入法候选词预测
- 文本生成(如自动补全句子)
- 拼写检查(判断词语组合是否合理)
- 搜索引擎查询扩展
1.1.5 优缺点
✅ 优点:
- 简单易实现,计算效率高
- 可解释性强,易于调试
❌ 缺点:
- 只能记住有限上下文(长句子容易出错)
- 需要大量数据训练
- 对未见过的新词组合预测能力差
1.2 TF-IDF:衡量词语重要性的尺子
1.2.1 基本概念
TF-IDF(词频-逆文档频率)是一种评估词语重要性的方法,它考虑两个因素:
- 词频(TF):词在文档中出现的频率
- 逆文档频率(IDF):词在整个文档集合中的罕见程度
简单说:一个词在本文中出现越多(TF高),同时在别的文章中出现越少(IDF高),就越重要。
1.2.2 计算公式
TF-IDF = TF × IDF
其中:
- TF = 词在文档中的出现次数 / 文档总词数
- IDF = log(文档总数 / 包含该词的文档数)
1.2.3 为什么需要TF-IDF?
直接统计词频会有一个问题:像"的"、"是"这种词虽然出现很多,但对理解内容没帮助。TF-IDF通过IDF降低了这类词的权重。
1.2.4 应用场景
- 搜索引擎排序(找出文档真正重要的词)
- 文本分类(如新闻分类)
- 关键词自动提取
- 推荐系统(分析用户兴趣)
1.2.5 实际案例
如果分析专利文档:
- "中国"可能词频高但IDF低(很多文档都提到)
- "专利"词频适中但IDF高(较少文档提到)
→ "专利"的TF-IDF值会更高,更能代表主题
1.2.6 优缺点
✅ 优点:
- 简单有效,易于计算
- 能自动过滤常见无意义词
❌ 缺点:
- 不考虑词语顺序和语义关系
- 对同义词处理不好(如"电脑"和"计算机")
1.3 总结对比
特性 | N-Gram | TF-IDF |
---|---|---|
主要用途 | 预测下一个词/生成文本 | 评估词语重要性/文档特征提取 |
核心思想 | 词语出现的概率依赖前几个词 | 重要=在本文档多见+在其它文档少见 |
典型应用 | 输入法、机器翻译、拼写检查 | 搜索引擎、文本分类、关键词提取 |
优势 | 保持语言连贯性 | 识别文档关键主题词 |
局限 | 长距离依赖差、需要大量训练数据 | 忽略词语顺序和语义关系 |
两者常结合使用,比如先用TF-IDF提取重要词,再用N-Gram分析这些词的关系。
简单示例
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
# 示例词库
words = [
"苹果", "香蕉", "橙子", "葡萄", "菠萝",
"芒果", "西瓜", "草莓", "蓝莓", "樱桃",
"苹果手机", "苹果电脑", "苹果汁", "红苹果", "青苹果"
]
# 定义n-gram函数(这里使用2-gram)
def get_ngrams(word, n=2):
return [word[i:i+n] for i in range(len(word)-n+1)]
# 为每个词生成n-gram特征
word_ngrams = [" ".join(get_ngrams(word)) for word in words]
print("词语的2-gram表示示例:")
for word, ngram in zip(words[:5], word_ngrams[:5]):
print(f"{
word} → {
ngram}")
# 使用TF-IDF向量化
vectorizer = TfidfVectorizer(tokenizer=lambda x: x.split())
tfidf_matrix = vectorizer.fit_transform(word_ngrams)
# 定义查找相似词的函数
def find_similar_words(target_word, top_n=5):
# 生成目标词的n-gram
target_ngram = " ".join(get_ngrams(target_word))
# 转换为TF-IDF向量
target_vec = vectorizer.transform([target_ngram])
# 计算余弦相似度
similarities = cosine_similarity(target_vec, tfidf_matrix)
# 获取最相似的词
similar_indices = np.argsort(similarities[0])[::-1][1:top_n+1] # 排除自己
print(f"\n与'{
target_word}'最相似的{
top_n}个词:")
for idx in similar_indices:
print(f"{
words[idx]}: {
similarities[0][idx]:.3f}")
# 测试示例
find_similar_words("苹果", top_n=5)
find_similar_words("菠萝", top_n=3)
find_similar_words("苹果手机", top_n=3)
2. Word Embedding(词嵌入)
2.1 🌍 把词语变成"坐标"
想象你是一个外星人,第一次来地球学习人类的语言。你发现:
- 单词 “猫” 和 “狗” 经常一起出现(因为它们都是宠物)。
- 单词 “苹果” 和 “香蕉” 也经常一起出现(因为它们都是水果)。
- 但 “猫” 和 “苹果” 几乎不会同时出现(因为它们属于不同类别)。
于是,你决定给每个单词分配一个 “坐标”(比如在三维空间里的位置):
- "猫" →
[0.8, 0.2, 0.1]
- "狗" →
[0.7, 0.3, 0.1]
- "苹果" →
[0.1, 0.9, 0.4]
- "香蕉" →
[0.2, 0.8, 0.3]
这样:
✅ 相似的词(比如猫和狗)坐标接近。
❌ 不相似的词(比如猫和苹果)坐标远离。
2.2 🔍 Word Embedding 是什么?
Word Embedding 就是通过数学方法,把单词变成 一串数字(向量),让计算机能通过这些数字:
- 理解词语的意思(比如"猫"和"狗"都是动物)。
- 计算词语的关系(比如"国王 - 男 + 女 ≈ 女王")。
2.3 💡 为什么要用 Word Embedding?
直接给单词编号(比如"猫=1,狗=2")会丢失语义信息。而 Word Embedding 能:
- 压缩信息:用少数几个数字表示复杂含义。
- 发现规律:自动学习"猫→狗"和"苹果→香蕉"的相似关系。
- 兼容算法:机器学习模型(如神经网络)只能处理数字,不能直接处理文字。
2.4 🛠️ 举个实际例子
假设用 3 维向量表示词语:
- "科技" →
[0.9, 0.1, 0.2]
- "手机" →
[0.8, 0.2, 0.3]
- "水果" →
[0.1, 0.9, 0.4]
计算机看到:
"科技"
和"手机"
的向量接近 → 它们相关。"科技"
和"水果"
的向量远离 → 它们无关。
2.5 📚 常见的 Word Embedding 方法
- Word2Vec:通过上下文预测词语(比如"猫爱吃__" → 预测"鱼")。
- GloVe:统计词语共同出现的频率(比如"猫"和"狗"经常一起出现)。
- BERT(现代方法):结合上下文动态调整向量(比如"苹果"在"吃苹果"和"苹果手机"中含义不同)。
2.6 ❓ 简单总结
Word Embedding 就是 让计算机通过数字"理解"词语,像人类一样知道"猫和狗相似,但和苹果无关"。它是自然语言处理(NLP)的基础技术,用于翻译、搜索、聊天机器人等场景。
3. Word2Vec
3.1 Word2Vec的两种模型
(1) CBOW (Continuous Bag of Words)
- 目标:用上下文词语预测中心词(适合小型数据集)。
- 例子:
句子:"我 爱 自然 语言 处理"
假设窗口大小为 2(左右各 2 个词),则:- 输入:
["我", "爱", "语言", "处理"]
(上下文) - 输出:
"自然"
(中心词)
- 输入:
(2) Skip-gram
- 目标:用中心词预测上下文词语(适合大型数据集)。
- 例子:
同一句子"我 爱 自然 语言 处理"
,窗口大小为 2:- 输入:
"自然"
(中心词) - 输出:
["我", "爱", "语言", "处理"]
(上下文)
- 输入:
CBOW vs Skip-gram:
- CBOW 训练更快,适合高频词。
- Skip-gram 对低频词效果更好,但需要更多数据。
3.2 Word2Vec的实现步骤
Step 1: 数据预处理
- 分词(如用
jieba
对中文分词)。 - 构建词汇表(给每个词分配唯一 ID,如
我=0, 爱=1, 自然=2...
)。
Step 2: 构建神经网络模型
Word2Vec 本质上是一个 单隐层神经网络,结构如下:
输入层 → 隐藏层(Embedding 层) → 输出层(Softmax)
- 输入层:词语的 one-hot 编码(如
"自然" = [0, 0, 1, 0, 0]
)。 - 隐藏层:权重矩阵(即词向量表),维度 =
[词汇表大小, 嵌入维度]
(如 300 维)。 - 输出层:预测上下文词的概率(Softmax 归一化)。
Step 3: 训练模型
- 输入一个词(如
"自然"
的 one-hot 向量[0, 0, 1, 0, 0]
)。