分布度量
分布差异主要描述两个分布(一般是二维矩阵)之间的差异,机器学习中常用的分布差异度量方法包括:基于熵的信息熵、互信息、条件熵、交叉熵、KL 散度、JS 散度以及 Wasserstein 距离。
1. 信息熵 (Entropy)
熵 Entropy 是一种量化数据中的信息的单位,一般用
当对数底为 2 时,表示的是编码概率分布
2. 互信息 (Mutual Information)
无监督学习中常用的损失函数,作用于标签时,最大化预测标签和真实标签的信息熵,可以促使预测标签 certain 且 diverse,
直观地说,如果把熵
3. KL散度 (KullbacK-Leibler Divergence)
也称相对熵。熵的大小可以度量编码
注意: 1)如果继续用 2 为底的对数计算,则 KL 散度值表示信息损失的二进制位数。 2)如果
Specializing to Gaussian measures
4. 条件熵 (Conditional Entropy)
条件熵是在已知随机变量 X 的条件下,Y 的条件概率分布的熵对随机变量 X 的数学期望
最小化条件熵让模型远离决策边界,可以应用在无监督数据上,以利用其数据分布信息。
5. 交叉熵 (Cross entropy)
- Cross entropy
为什么深度学习中用交叉熵而不用 KL 散度?
- 和 softmax 结合应用在深度学习中 softmax 原理
其中
6. JS 散度(Jensen-Shannon)
JS 散度度量了两个概率分布的相似度,基于 KL 散度的变体,解决了 KL 散度非对称的问题。一般地,JS 散度是对称的,其取值是 0 到 1 之间。定义如下:
KL 散度和 JS 散度度量的时候有一个问题: 如果两个分布 p, q 离得很远,完全没有重叠的时候,那么 KL 散度值是没有意义的,而 JS 散度值是一个常数。这在学习算法中是比较致命的,这就意味这这一点的梯度为 0,梯度消失了。
7. Wasserstein 距离
Wasserstein 距离度量两个概率分布之间的距离,定义如下:
直观上可以把
Wasserstein 距离相比 KL 散度和 JS 散度的优势在于:即使两个分布的支撑集没有重叠或者重叠非常少,仍然能反映两个分布的远近。而 JS 散度在此情况下是常量,KL 散度可能无意义。
Specializing to Gaussian measures
在域自适应领域,常用的分布差异度量方式(距离损失)有多种方法,每种方法有其独特的特点和适用条件。下面逐一比较以下几种常见的方法:Maximum Mean Discrepancy (MMD),Correlation Alignment (CORAL),Central Moment Discrepancy (CMD),Maximum Density Divergence (MDD),和 Wasserstein Distance。
1. Maximum Mean Discrepancy (MMD)
定义和特点:
MMD是通过比较两个分布的样本均值的差异来衡量它们之间的距离。具体地,它通过特征空间中的核函数来度量分布之间的差异,通常使用正定核如高斯核。优点:
- 简单直观,易于实现和计算。
- 在一些实验中表现良好,特别是当分布差异较为显著时效果较好。
缺点:
- 对于高维和复杂的数据分布,可能会出现较高的误差。
- 对于较小的样本量可能表现不稳定。
适用条件:
- 适合用于比较较为简单的数据分布和特征空间。
- 在计算资源有限的情况下表现较为出色。
代码
MMD 是通过核方法来度量两个分布之间的距离,这里以高斯核为例实现 MMD 的计算:
import numpy as np def gaussian_kernel(x, y, sigma=1.0): return np.exp(-np.linalg.norm(x - y)**2 / (2 * (sigma ** 2))) def mmd(X, Y, kernel=gaussian_kernel): m = len(X) n = len(Y) K_xx = np.zeros((m, m)) K_yy = np.zeros((n, n)) K_xy = np.zeros((m, n)) for i in range(m): for j in range(m): K_xx[i, j] = kernel(X[i], X[j]) for i in range(n): for j in range(n): K_yy[i, j] = kernel(Y[i], Y[j]) for i in range(m): for j in range(n): K_xy[i, j] = kernel(X[i], Y[j]) return np.mean(K_xx) + np.mean(K_yy) - 2 * np.mean(K_xy) # Example usage: X = np.random.randn(100, 2) # Sample from distribution X Y = np.random.randn(100, 2) # Sample from distribution Y distance_mmd = mmd(X, Y) print(f"MMD distance between X and Y: {distance_mmd}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2. Correlation Alignment (CORAL)
定义和特点:
CORAL通过最小化两个分布之间的协方差矩阵的差异来进行域自适应。它试图通过特征之间的协方差来对齐两个域的特征分布。优点:
- 考虑了特征之间的相关性,能够更加准确地度量分布的差异。
- 对于特征之间存在较强关联的数据集有较好的适应性。
缺点:
- 受限于协方差矩阵的计算,当特征空间较大时可能计算代价较高。
- 只考虑了二阶统计量,可能忽略了高阶的分布差异。
适用条件:
- 适合于特征之间具有较强相关性的数据集。
- 对于计算资源充足的情况下,可以有效地对齐分布。
代码
CORAL 通过最小化协方差矩阵的差异来进行域自适应:
from sklearn.covariance import LedoitWolf def coral(X, Y): cov_X = LedoitWolf().fit(X).covariance_ cov_Y = LedoitWolf().fit(Y).covariance_ return np.linalg.norm(cov_X - cov_Y) # Example usage: X = np.random.randn(100, 2) # Sample from distribution X Y = np.random.randn(100, 2) # Sample from distribution Y distance_coral = coral(X, Y) print(f"CORAL distance between X and Y: {distance_coral}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3. Central Moment Discrepancy (CMD)
定义和特点:
CMD通过比较高阶中心矩来度量两个分布之间的差异。它不仅考虑了均值和方差,还考虑了数据分布的更高阶统计信息。优点:
- 能够更全面地捕捉数据分布的差异,尤其是对于非高斯分布和高阶统计信息的敏感性较好。
缺点:
- 需要计算和比较高阶统计量,计算复杂度可能较高。
- 对于样本量较少时,估计高阶统计量的稳定性可能较差。
适用条件:
- 适合用于捕捉高阶统计信息对分布差异影响显著的情况。
- 当数据分布复杂且不服从正态分布时表现较为突出。
代码
CMD 通过比较高阶中心矩来度量两个分布之间的差异,这里演示计算方差和偏度的差异:
from scipy.stats import moment def cmd(X, Y): var_X = np.var(X) var_Y = np.var(Y) skew_X = moment(X, moment=3) skew_Y = moment(Y, moment=3) return np.abs(var_X - var_Y) + np.abs(skew_X - skew_Y) # Example usage: X = np.random.randn(100) # Sample from distribution X Y = np.random.randn(100) # Sample from distribution Y distance_cmd = cmd(X, Y) print(f"CMD distance between X and Y: {distance_cmd}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
4. Maximum Density Divergence (MDD)
定义和特点:
MDD通过比较两个分布的密度函数的差异来度量它们之间的距离。通常使用KL散度来作为分布差异的度量标准。优点:
- 直接基于密度函数比较,能够较为准确地捕捉分布之间的差异。
- 在分布有明显差异时效果较好。
缺点:
- 对于高维和复杂分布的密度估计可能存在困难。
- KL散度可能会受到样本稀疏性的影响。
适用条件:
- 适合用于直接比较密度函数的场景。
- 当能够准确估计密度函数时表现较为优越。
代码
MDD 通过比较两个分布的密度函数的差异来度量它们之间的距离,这里演示使用KL散度的计算:
from scipy.stats import entropy from sklearn.neighbors import KernelDensity def mdd(X, Y): kde_X = KernelDensity(bandwidth=0.5).fit(X[:, np.newaxis]) kde_Y = KernelDensity(bandwidth=0.5).fit(Y[:, np.newaxis]) log_dens_X = kde_X.score_samples(X[:, np.newaxis]) log_dens_Y = kde_Y.score_samples(Y[:, np.newaxis]) return entropy(np.exp(log_dens_X), np.exp(log_dens_Y)) # Example usage: X = np.random.randn(100) # Sample from distribution X Y = np.random.randn(100) # Sample from distribution Y distance_mdd = mdd(X, Y) print(f"MDD distance between X and Y: {distance_mdd}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
5. Wasserstein Distance
定义和特点:
Wasserstein距离(也称为地面距离或者EMD)是通过最小化将一个分布转换成另一个分布所需的最小平均运输成本来度量两个分布之间的距离。优点:
- 能够处理复杂的分布和高维数据。
- 在图像生成和分布匹配等任务中表现出色。
缺点:
- 计算复杂度较高,特别是在高维空间和大样本量下。
- 对于非凸优化问题的稳定性需要仔细考虑。
适用条件:
- 适合用于高维和复杂分布的比较。
- 对于需要精确地度量分布差异和转换成本的应用场景。
代码
Wasserstein 距离通过优化问题来计算两个分布之间的最小平均运输成本:
from scipy.stats import wasserstein_distance # Example usage: X = np.random.randn(100) # Sample from distribution X Y = np.random.randn(100) # Sample from distribution Y distance_wasserstein = wasserstein_distance(X, Y) print(f"Wasserstein distance between X and Y: {distance_wasserstein}")
1
2
3
4
5
6
7
8
9