前言
本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和参考文献请见《机器学习数学通关指南》
ima 知识库
知识库广场搜索:
知识库 | 创建人 |
---|---|
机器学习 | @Shockang |
机器学习数学基础 | @Shockang |
深度学习 | @Shockang |
正文
📚 引言
熵和交叉熵是机器学习和信息论中的基础概念,它们在模型优化、信息压缩和不确定性量化中扮演着核心角色。本文将系统地分析这两个概念,从理论到实践,帮助您构建完整的理解框架。
🔄 熵 (Entropy)
📝 定义
熵源于信息论,用于量化随机变量的不确定性或信息量。对于一个随机变量 X X X 的概率分布 P P P:
H ( P ) = − ∑ i = 1 n p i log 2 p i H(P) = -\sum_{i=1}^{n} p_i \log_2 p_i H(P)=−i=1∑npilog2pi
其中 p i p_i pi 是事件 i i i 发生的概率。单位通常是比特(bit)(使用以2为底的对数时)。
🔑 核心特性
- 非负性:熵始终 ≥ 0 \geq 0 ≥0
- 最大熵原理:均匀分布时熵最大
- 最小熵原理:确定事件(概率为1)时熵为0
- 加性:独立随机变量的联合熵等于各自熵之和
📊 直观理解
熵可以理解为平均信息量或平均惊讶度:
- 高熵:事件发生很"意外",需要更多信息来描述系统
- 低熵:事件发生很"平常",需要较少信息来描述系统
🌟 应用场景
- 决策树算法:通过信息增益(熵的减少)选择最优特征
- 数据压缩:信息熵决定了数据压缩的极限(香农极限)
- 密码学:评估密码的安全强度
- 特征选择:选择包含最多信息的特征
💻 Python代码实现
import numpy as npdef entropy(probabilities):"""计算信息熵"""# 过滤掉零概率(避免log(0))probabilities = np.array(probabilities)probabilities = probabilities[probabilities > 0]return -np.sum(probabilities * np.log2(probabilities))# 例子1: 均匀分布 [0.5, 0.5]
print(f"均匀二项分布的熵: {entropy([0.5, 0.5])}") # 结果为1,即最大熵# 例子2: 确定事件 [1, 0]
print(f"确定事件的熵: {entropy([1, 0])}") # 结果为0,即最小熵# 例子3: 偏斜分布 [0.9, 0.1]
print(f"偏斜分布的熵: {entropy([0.9, 0.1])}") # 结果约为0.469,熵较低
❌ 交叉熵 (Cross-Entropy)
📝 定义
交叉熵用于衡量两个概率分布的差异,特别是真实分布 P P P 和预测/估计分布 Q Q Q 之间的差异:
H ( P , Q ) = − ∑ i = 1 n p i log 2 q i H(P, Q) = -\sum_{i=1}^{n} p_i \log_2 q_i H(P,Q)=−i=1∑npilog2qi
🔍 与熵的关系
- 当 P = Q P = Q P=Q 时, H ( P , Q ) = H ( P ) H(P, Q) = H(P) H(P,Q)=H(P)
- 一般情况下, H ( P , Q ) ≥ H ( P ) H(P, Q) \geq H(P) H(P,Q)≥H(P)(信息不等式)
- 交叉熵 = 熵 + KL散度: H ( P , Q ) = H ( P ) + D K L ( P ∣ ∣ Q ) H(P, Q) = H(P) + D_{KL}(P || Q) H(P,Q)=H(P)+DKL(P∣∣Q)
🚀 作为损失函数的优势
- 梯度稳定性:相比均方误差,避免了梯度消失问题
- 概率解释性:直接对应最大似然估计
- 对错误预测的高惩罚:预测值远离真实值时惩罚显著增加
💻 Python代码实现
import numpy as np
import matplotlib.pyplot as pltdef cross_entropy(y_true, y_pred):"""计算交叉熵"""# 防止数值不稳定y_pred = np.clip(y_pred, 1e-15, 1 - 1e-15)return -np.sum(y_true * np.log2(y_pred))# 二分类示例
y_true = np.array([1, 0]) # 真实标签:第一个类为正例# 不同预测概率的交叉熵
predictions = np.linspace(0.1, 0.9, 9)
ce_values = []for pred in predictions:y_pred = np.array([pred, 1-pred]) # 预测概率ce_values.append(cross_entropy(y_true, y_pred))print(f"预测概率为[{pred:.1f}, {1-pred:.1f}]时,交叉熵为: {ce_values[-1]:.3f}")# 可视化交叉熵随预测概率变化
plt.figure(figsize=(10, 6))
plt.plot(predictions, ce_values, 'b-o', linewidth=2)
plt.axvline(x=1.0, color='g', linestyle='--', label='理想预测')
plt.xlabel('预测正例的概率')
plt.ylabel('交叉熵')
plt.title('交叉熵随预测概率的变化')
plt.grid(True)
plt.show()
📊 实际应用比较
熵与交叉熵的区别
特征 | 熵 | 交叉熵 |
---|---|---|
对象 | 单个概率分布的不确定性 | 两个分布的差异性 |
适用场景 | 信息量度量、特征选择 | 模型训练损失函数 |
最小值 | 确定事件(某事件概率=1)时为0 | 当预测分布=真实分布时取最小值 |
数学表达 | − ∑ p i log p i -\sum p_i \log p_i −∑pilogpi | − ∑ p i log q i -\sum p_i \log q_i −∑pilogqi |
对称性 | 不涉及(仅一个分布) | 非对称性( H ( P , Q ) ≠ H ( Q , P ) H(P, Q) \neq H(Q, P) H(P,Q)=H(Q,P)) |
🛠️ 实践应用
1. 决策树中的信息增益
# 计算信息增益
def information_gain(parent_entropy, feature_values, target_values):# 计算特征各取值的条件熵child_entropies = []weights = []unique_values = np.unique(feature_values)total_samples = len(target_values)for value in unique_values:indices = np.where(feature_values == value)[0]target_subset = target_values[indices]# 计算子集中不同类别的概率分布unique_targets = np.unique(target_subset)probs = [np.sum(target_subset == t) / len(target_subset) for t in unique_targets]# 计算条件熵child_entropy = entropy(probs)child_entropies.append(child_entropy)weights.append(len(indices) / total_samples)# 计算条件熵的加权平均conditional_entropy = np.sum(np.array(weights) * np.array(child_entropies))# 信息增益 = 父节点熵 - 条件熵return parent_entropy - conditional_entropy
2. 神经网络分类训练
# 基于TensorFlow/Keras的交叉熵损失示例
import tensorflow as tf
from tensorflow import keras
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split# 生成模拟数据
X, y = make_classification(n_samples=1000, n_classes=3, n_features=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 将类别转换为one-hot编码
y_train_onehot = keras.utils.to_categorical(y_train, 3)
y_test_onehot = keras.utils.to_categorical(y_test, 3)# 构建简单神经网络
model = keras.Sequential([keras.layers.Dense(64, activation='relu', input_shape=(20,)),keras.layers.Dense(32, activation='relu'),keras.layers.Dense(3, activation='softmax') # 3个输出类别
])# 使用交叉熵作为损失函数
model.compile(optimizer='adam',loss='categorical_crossentropy', # 多分类交叉熵metrics=['accuracy']
)# 训练模型
history = model.fit(X_train, y_train_onehot, epochs=10, validation_split=0.2, verbose=0)# 评估模型
test_loss, test_acc = model.evaluate(X_test, y_test_onehot)
print(f"测试精度: {test_acc:.4f}")
print(f"测试交叉熵损失: {test_loss:.4f}")
🔮 高级话题
1. 最大熵原理
最大熵原理是一种推断方法,当我们对未知分布只有部分信息时,应该选择满足已知条件下熵最大的分布,这样可以避免引入额外的不必要假设。
2. 信息瓶颈理论
信息瓶颈理论(Information Bottleneck Theory)是一种解释深度学习的理论框架,认为深度学习的目标是找到输入数据的一种表示,该表示:
- 尽可能多地保留与目标相关的信息
- 尽可能压缩输入的原始信息
3. 可变长度编码
熵确定了信息的最优编码长度。哈夫曼编码等算法利用了这一原理,为频率高的符号分配短码,频率低的符号分配长码。
🎯 小结
- 熵是量化单一分布不确定性的基础度量
- 交叉熵衡量两个分布的差异,是机器学习中常用的损失函数
- 理解这两个概念有助于理解信息论和机器学习中的许多算法和技术
- 实际应用中,交叉熵损失函数在分类任务中表现优异,尤其是对于概率预测问题
📖 延伸阅读
- 香农的信息论原始论文
- KL散度及其在变分推断中的应用
- 最大熵模型与其在自然语言处理中的应用
- 互信息与特征选择
- 深度学习中的信息瓶颈理论
希望这篇文章能帮助你理解熵和交叉熵这两个重要概念。在机器学习的旅途中,掌握这些基础数学工具将使你事半功倍!🚀