如何解决使用 scipy gaussian_kde 和 seaborn kdeplot 时的差异 KDE 渲染
就 documentation 而言,seaborn kdeplot 使用 scipy.stats.gaussian_kde 工作。
然而,尽管使用相同的 seaborn
大小,但在使用 gaussian_kde
和 bandwidth
绘图时我得到了两种不同的分布。
在上图中,左侧是数据直接馈入 gaussian_kde
时的分布。然而,正确的绘图是将数据输入 seaborn kdeplot
时的分布。
此外,给定边界的曲线下面积在这两种绘制分布的方式之间并不相似。
使用 gaussian_kde 的 auc : 47.7 和使用 via seaborn 的 auc : 49.5
我可以知道是什么导致了这种差异,有没有一种方法可以标准化输出,而不管使用何种方法(例如,seaborn
或 gaussian_kde
)
下面给出了重现上述 plot
和 auc
的代码。
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
time_window_order = ['272','268','264','260','256','252','248','244','240']
order_dict = {k: i for i,k in enumerate ( time_window_order )}
df = pd.DataFrame ( {'time_window': ['268','240','240'],'seq_no': ['a','a','b','b']} )
df ['centre_point'] = df ['time_window'].map ( order_dict )
filter_band = df ["seq_no"].isin ( ['a'] )
df = df [filter_band].reset_index ( drop=True )
auc_x_min,auc_x_max = 0,4
bandwith=0.5
########################
plt.subplots(1,2)
# make the first plot
plt.subplot(1,2,1)
kde0 = gaussian_kde ( df ['centre_point'],bw_method=bandwith )
xmin,xmax = -3,12
x_1 = np.linspace ( xmin,xmax,500 )
kde0_x = kde0 ( x_1 )
sel_region_x = x_1 [(x_1 > auc_x_min) * (x_1 < auc_x_max)]
sel_region_y = kde0_x [(x_1 > auc_x_min) * (x_1 < auc_x_max)]
auc_bond_1 = np.trapz ( sel_region_y,sel_region_x )
area_whole = np.trapz ( kde0_x,x_1 )
plt.plot ( x_1,kde0_x,color='b',label='KDE' )
plt.ylim(bottom=0)
plt.title(f'Direct gaussian_kde with bw {bandwith}')
plt.fill_between ( sel_region_x,sel_region_y,facecolor='none',edgecolor='r',hatch='xx',label='intersection' )
# make second plot
plt.subplot(1,2)
g = sns.kdeplot ( data=df,x="centre_point",bw_adjust=bandwith )
c = g.get_lines () [0].get_data ()
x_val = c [0]
kde0_x = c [1]
idx = (x_val> auc_x_min) * (x_val < auc_x_max)
sel_region_x = x_val [idx]
sel_region_y = kde0_x [idx]
auc_bond_2 = np.trapz ( sel_region_y,sel_region_x )
g.fill_between ( sel_region_x,hatch='xx' )
plt.title(f'Via Seaborn with bw {bandwith}')
plt.tight_layout()
plt.show()
# show much the area differ between these two plotting
print ( f'auc using gaussian_kde : {auc_bond_1 * 100:.1f} and auc using via seaborn : {auc_bond_2 * 100:.1f}' )
x=1
编辑
kde0 = gaussian_kde ( df ['centre_point'],bw_method='scott' )
g = sns.kdeplot ( data=df,bw_adjust=1 ) # Seaborn by default use the scott method to determine the bw size
返回
从视觉上看,两个图看起来完全相同。
然而,图之间的auc
仍然返回两个不同的值
auc 使用 gaussian_kde : 45.1 和 auc 使用 via seaborn : 44.6
解决方法
你是这样调用 scipy 的:
kde0 = gaussian_kde ( df ['centre_point'],bw_method=bandwith )
像这样的seaborn
g = sns.kdeplot ( data=df,x="centre_point",bw_adjust=bandwith )
但是 kdeplot docs 告诉我们 bw_adjust
是一个
乘法缩放使用 bw_method 选择的值的因子。增加将使曲线更平滑。请参阅注释。
而 kdeplot 也有一个 bw_method
参数,它是一个
确定要使用的平滑带宽的方法;传递给 scipy.stats.gaussian_kde。
因此,如果您想将两个库的结果等同起来,您需要确保使用了正确的参数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。