You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算直方图交集百分比结果超1的原因及解决方法

问题原因与修正方案

为什么结果会大于1?

你混淆了直方图的频率和密度计算逻辑,导致分子分母的维度不匹配:

  • 用weights=(np.ones_like(d)/len(d))时,plt.hist返回的n是每个bin的频率(所有bin的频率总和为1)。
  • 你计算直方图总面积时用了sum(np.diff(bins)*n),这是每个bin的「频率×宽度」之和,结果等于数据范围的总长度(比如数据范围是0到0.5,这个值就是0.5)。
  • 但你计算重叠面积时直接对np.minimum(n1,n2)求和,得到的是频率的总和(两个数据集相同时为1)。
  • 当数据范围总长度小于0.5时,分母n1_area+n2_area就会小于1,分子是1,最终结果自然大于1。

修正代码

核心是让分子分母的计算逻辑统一:都基于直方图矩形的面积(高度×宽度)。有两种常用方案:

方案1:使用密度直方图(推荐)

直接用density=True参数获取密度值,此时每个直方图的总面积固定为1,计算更直观:

import numpy as np
import matplotlib.pyplot as plt

rng = (min(dataset1.min(), dataset2.min()), max(dataset1.max(), dataset2.max()))
# 绘制密度直方图,返回的n是每个bin的密度值
n1, bins1, _ = plt.hist(dataset1, color=color1, alpha=0.75, bins=7, density=True, range=rng)
n2, bins2, _ = plt.hist(dataset2, color=color2, alpha=0.75, bins=7, density=True, range=rng)

bin_widths = np.diff(bins1)
# 交集面积:每个bin取最小密度 × bin宽度,求和
overlap_area = np.sum(np.minimum(n1, n2) * bin_widths)
# 两个直方图总面积各为1,总和是2
total_area = 1 + 1
# 转成百分比
overlap_percentage = overlap_area / total_area * 100

方案2:基于原权重逻辑修正

如果你坚持用权重方式,只需给重叠面积的计算加上bin宽度的乘积:

import numpy as np
import matplotlib.pyplot as plt

rng = (min(dataset1.min(), dataset2.min()), max(dataset1.max(), dataset2.max()))
n1, bins1, _ = plt.hist(dataset1, color=color1, alpha=0.75, bins=7, weights=(np.ones_like(dataset1)/len(dataset1)), range=rng)
n2, bins2, _ = plt.hist(dataset2, color=color2, alpha=0.75, bins=7, weights=(np.ones_like(dataset2)/len(dataset2)), range=rng)

bin_widths = np.diff(bins1)
# 计算每个直方图的总面积(频率×宽度之和)
n1_area = np.sum(n1 * bin_widths)
n2_area = np.sum(n2 * bin_widths)
# 计算交集面积(最小频率×宽度之和)
overlap_area = np.sum(np.minimum(n1, n2) * bin_widths)
# 计算百分比
overlap_percentage = overlap_area / (n1_area + n2_area) * 100

当两个数据集完全相同时,两种方案都会得到50%的结果,符合预期。

内容的提问来源于stack exchange,提问作者Tessa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 19:19:52