Fasttext 优化 - 调整 NGram 和损失函数
1 课程概览
本课讲解 Fasttext 优化手段四和五:增加 n-gram 特征和调整损失函数。n-gram 从 1-gram 改为 2-gram(相邻两个词一起训练)。损失函数从传统 softmax 改为 hs(层次 softmax,使用哈夫曼树和负采样)。实际开发需要一步步调参,没有固定最优参数。
2 核心概念与定义
- n-gram:n 个相邻词的组合。1-gram 是单个词,2-gram 是相邻两个词。
- hs(Hierarchical Softmax):层次 softmax,使用哈夫曼树和负采样。
- 损失函数:传统 softmax vs 层次 softmax。
3 模型与算法详解
优化手段四:增加 n-gram 特征
从 1-gram 改为 2-gram,相邻两个词一起训练。
| 参数 | 默认值 | 调整后 | 说明 |
|---|---|---|---|
| wordNgrams | 1 | 2 | 相邻两个词一起训练 |
n-gram 示例
2-gram 是相邻两个词的组合。
| n-gram | 示例 | 说明 |
|---|---|---|
| 1-gram | "I", "love", "NLP" | 单个词 |
| 2-gram | "I love", "love NLP" | 相邻两个词 |
| 3-gram | "I love NLP" | 相邻三个词 |
实际开发建议
实际开发一般最多到 3-gram。
- 2-gram 效果不错
- 3-gram 也可以
- 不要太大(如 5-gram),会接近句子
优化手段五:调整损失函数
从传统 softmax 改为层次 softmax(hs)。
| 参数 | 默认值 | 调整后 | 说明 |
|---|---|---|---|
| loss | softmax | hs | 层次 softmax |
层次 softmax(hs)
使用哈夫曼树和负采样。
- 哈夫曼树:层次 softmax
- 负采样:降低计算量
- 一行代码搞定,不需要自己实现
实际开发调参
没有固定最优参数,需要一步步测。
- 没有一套最佳参数
- 需要自己测
- 给方向,不是给答案
- 可以自己改算法
4 数学原理与推导
n-gram 特征
$$\text{n-gram}(w_1, w_2, ..., w_n) = {(w_i, w_{i+1}, ..., w_{i+n-1})}$$
层次 softmax
$$P(y) = \prod_{i=1}^{d} \sigma(v_{n_i}^T h)$$
其中:
- $d$ 是哈夫曼树深度
- $n_i$ 是路径上的节点
- $\sigma$ 是 sigmoid 函数
- $h$ 是隐藏层输出
5 代码示例
import fasttext
def dm05_ngram():
"""优化手段四:增加 n-gram 特征"""
# 在上部基础上增加 n-gram 特征(1-gram → 2-gram)
model = fasttext.train_supervised(
input="data/cooking_pre_train.txt",
epoch=25,
lr=1.0,
wordNgrams=2 # n-gram 特征:1 → 2
)
# 评估
metrics = model.test("data/cooking_pre_validate.txt")
print(f"Precision@1: {metrics[1]}")
return model
def dm06_loss():
"""优化手段五:调整损失函数"""
# 在上部基础上调整损失函数(softmax → hs)
model = fasttext.train_supervised(
input="data/cooking_pre_train.txt",
epoch=25,
lr=1.0,
wordNgrams=2,
loss='hs' # 损失函数:softmax → hs(层次 softmax)
)
# 评估
metrics = model.test("data/cooking_pre_validate.txt")
print(f"Precision@1: {metrics[1]}")
return model
# 测试
if __name__ == "__main__":
print("=== 优化手段四:增加 n-gram 特征 ===")
model1 = dm05_ngram()
print("\n=== 优化手段五:调整损失函数 ===")
model2 = dm06_loss()
代码说明
| 代码 | 说明 |
|---|---|
wordNgrams=2 | n-gram 特征:1 → 2 |
loss='hs' | 损失函数:softmax → hs(层次 softmax) |
6 重难点与易错提醒
- ❗重点:2-gram 是相邻两个词一起训练。
- ❗重点:hs 是层次 softmax,使用哈夫曼树和负采样。
- ⚠️易错:实际开发一般最多到 3-gram。
- 💡深入理解:没有固定最优参数,需要一步步测。
7 课堂问答精选
Q1:什么是 n-gram?
A:n-gram 是 n 个相邻词的组合。1-gram 是单个词,2-gram 是相邻两个词(如 "I love", "love NLP")。
Q2:如何增加 n-gram 特征?
A:在 train_supervised() 中设置 wordNgrams=2(默认 1)。实际开发一般最多到 3-gram。
Q3:如何调整损失函数?
A:在 train_supervised() 中设置 loss='hs'(层次 softmax)。hs 使用哈夫曼树和负采样,不需要自己实现。
Q4:实际开发如何调参?
A:没有固定最优参数,需要一步步测。给方向,不是给答案。可以自己改算法,只要效果提升即可。
8 本课小结
- 优化手段四:增加 n-gram 特征(wordNgrams=2)。
- 优化手段五:调整损失函数(loss='hs')。
- hs 是层次 softmax,使用哈夫曼树和负采样。
- 实际开发一般最多到 3-gram。
- 没有固定最优参数,需要一步步测。
9 延伸思考
- 如何自动调参?
- 多标签多分类如何处理?