如何计算二元KDE图中指定多边形区域的总概率?
解决方法
核心思路
KDE的本质是拟合出二维概率密度函数,要计算指定多边形区域内的累积概率,核心是对该区域内的密度函数做二重积分。可以借助scipy的工具结合KDE拟合结果实现。
具体实现步骤
- 用支持加权的KDE模型拟合数据,得到可调用的概率密度函数
- 定义多边形区域的判断规则,筛选出区域内的积分范围
- 通过数值积分计算区域内的概率总和
修改后的完整代码
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib.path import Path from matplotlib.patches import PathPatch from scipy.stats import gaussian_kde from scipy.integrate import dblquad def get_field_matrix(csv_name, coordinates): # 读取CSV数据(补充实际读取逻辑) df_heatmap = pd.read_csv(csv_name) # 提取坐标数组 xy = df_heatmap[['ActualX', 'ActualY']].values # 计算权重 weights = np.linalg.norm(df_heatmap.values, axis=1) ** 0.3 # 拟合加权KDE模型 kde_model = gaussian_kde(xy.T, weights=weights) # 保留原KDE绘图逻辑 sns.kdeplot(x='ActualX', y='ActualY', data=df_heatmap, cmap='viridis', fill=True, cbar=True, weights=weights) plt.xlabel('X-axis') plt.ylabel('Y-axis') plt.title('KDE-based Heatmap of X, Y Coordinates') # 绘制多边形 shape_path = Path(coordinates) shape_patch = PathPatch(shape_path, lw=2, edgecolor='red', facecolor='none') plt.gca().add_patch(shape_patch) # 判断点是否在多边形内的函数 def point_in_shape(x, y): return shape_path.contains_point((x, y)) # 获取数据的极值作为积分范围(可根据多边形范围缩小以提升速度) x_min, x_max = df_heatmap['ActualX'].min(), df_heatmap['ActualX'].max() y_min, y_max = df_heatmap['ActualY'].min(), df_heatmap['ActualY'].max() # 定义被积函数:仅在多边形内计算密度 def integrand(y, x): return kde_model.evaluate([x, y])[0] if point_in_shape(x, y) else 0.0 # 执行二重积分计算概率 total_prob, integral_error = dblquad(integrand, x_min, x_max, lambda x: y_min, lambda x: y_max) print("Summed Probability over the shape:", round(total_prob * 100, 2), "%") plt.gca().set_aspect('equal', adjustable='box') plt.show() return kde_model
关键细节说明
scipy.stats.gaussian_kde:支持加权数据拟合,和seaborn的kdeplot底层逻辑一致,提供evaluate方法直接计算任意点的密度值scipy.integrate.dblquad:二维数值积分工具,通过自定义被积函数限制积分区域- 优化方向:如果多边形范围远小于数据极值,可手动缩小积分上下限;复杂形状也可以用蒙特卡洛抽样法(生成大量随机点,统计落在多边形内的点的平均密度乘以区域面积)
内容的提问来源于stack exchange,提问作者cjmess01
相关产品推荐
相关产品推荐

