如何获取两个sns.distplot的重叠面积?量化归一化分布差异
我来帮你搞定这个问题——既要算出两个KDE曲线的重叠面积,又要找个除了均值差之外的指标来量化分布差异,对吧?下面分两部分给你详细说明:
计算两个KDE曲线的重叠面积
Seaborn的distplot里的KDE是基于Scipy的gaussian_kde实现的,我们可以手动拟合KDE模型,然后通过积分计算重叠区域的面积。具体步骤如下:
- 分别拟合两个数据集的KDE模型
- 生成覆盖两个数据范围的密集x轴网格
- 计算每个x点对应的两个密度值
- 对每个x点取两个密度的最小值,再积分这个最小值曲线得到重叠面积
示例代码:
import matplotlib.pyplot as plt import numpy as np import seaborn as sns from scipy.stats import gaussian_kde from scipy.integrate import trapezoid # 生成示例数据 x1 = np.random.normal(size=2000) x2 = np.random.normal(size=1000) + 1 # 拟合KDE模型 kde1 = gaussian_kde(x1) kde2 = gaussian_kde(x2) # 生成统一的x轴范围(足够密集保证精度) x_min = min(x1.min(), x2.min()) x_max = max(x1.max(), x2.max()) x_grid = np.linspace(x_min, x_max, 1000) # 计算每个x点的密度值 pdf1 = kde1(x_grid) pdf2 = kde2(x_grid) # 提取重叠部分的密度值 overlap_pdf = np.minimum(pdf1, pdf2) # 积分得到重叠面积 overlap_area = trapezoid(overlap_pdf, x_grid) print(f"两个分布的KDE重叠面积:{overlap_area:.4f}") # 可视化验证 sns.distplot(x1, hist=False, kde=True, color="r", kde_kws={"label": "x1"}) sns.distplot(x2, hist=False, kde=True, color="b", kde_kws={"label": "x2"}) plt.fill_between(x_grid, overlap_pdf, color='gray', alpha=0.5, label=f"Overlap Area: {overlap_area:.4f}") plt.legend() plt.show()
重叠面积的范围是0到1,值越接近1说明两个分布越相似,越接近0则差异越大。
除均值差外的分布差异度量
如果两个分布均值相同但形状差异大(比如一个正态、一个偏态),可以用这些非均值依赖的指标量化差异:
Kolmogorov-Smirnov检验(KS检验):衡量两个CDF曲线的最大垂直距离,范围0-1,值越大差异越显著。它是无参数检验,不依赖分布类型。
代码示例:from scipy.stats import ks_2samp ks_stat, p_value = ks_2samp(x1, x2) print(f"KS检验统计量:{ks_stat:.4f},p值:{p_value:.4f}")说明:KS统计量越接近1,分布差异越大;p值小于0.05时,可拒绝“两个分布完全相同”的原假设。
Wasserstein距离(地球移动距离):衡量将一个分布转换为另一个所需的最小“工作量”,同时考虑位置和形状差异,对非正态分布友好。
代码示例:from scipy.stats import wasserstein_distance wasserstein_dist = wasserstein_distance(x1, x2) print(f"Wasserstein距离:{wasserstein_dist:.4f}")说明:值越大表示两个分布的整体差异越大,比KS检验更能捕捉方差、偏度这类形状差异。
KL散度(Kullback-Leibler Divergence):衡量两个分布的信息差异,但它是不对称的(KL(P||Q)≠KL(Q||P)),使用时需注意方向。
代码示例:# 计算KL散度:KL(x1分布 || x2分布) kl_div = trapezoid(pdf1 * np.log(pdf1 / pdf2), x_grid) print(f"KL散度(x1||x2):{kl_div:.4f}")说明:值越大表示从x2分布到x1分布的信息损失越大,若要对称衡量差异,可计算双向散度的平均值。
内容的提问来源于stack exchange,提问作者lordy
相关产品推荐
相关产品推荐

