Scikit-maad与Soundecology声学指数计算结果不可比问题求助
Scikit-maad与Soundecology声学指数计算结果不可比问题排查
问题核心现象
- 分别使用Python库
Scikit-maad、R库Soundecology计算包含ADI(声学多样性指数)在内的多类声学指数时,两类工具输出结果几乎无相关性,ADI计算结果存在明显量级差异。 - 已核对所有显式传入的分析参数(频率范围、dB阈值、频带步长、香农指数选型)完全一致,定位差异来源为两个工具的声谱图底层计算逻辑不匹配:
Scikit-maad声谱图计算环节的部分参数未找到R侧对应配置,尤其未在tuneR、seewave等R常用音频处理包中找到与nperseg直接对应的参数。
复现测试代码
Python(Scikit-maad)实现
if __name__ == '__main__': fullfilename="wav_files/AM08_Grotte-New_2019-10-04_0FE081F80FE081F0_2019-07-26_000000_UTC.wav" wave, fs = sound.load(filename=fullfilename, channel='left', detrend=False, verbose=True) Sxx_power,tn,fn,ext = sound.spectrogram (wave, fs, window='hanning', nperseg = 1024, noverlap= None, verbose = False, display = False, savefig = None) adi = features.acoustic_diversity_index(Sxx_power, fn, fmin=0, fmax=10000, bin_step=1000, dB_threshold=-50, index='shannon') print(adi)
R(Soundecology)默认实现
a <- readWave("wav_files/AM08_Grotte-New_2019-10-04_0FE081F80FE081F0_2019-07-26_000000_UTC.wav") adi <- acoustic_diversity(a, max_freq = 10000, db_threshold = -50, freq_step = 1000, shannon = TRUE)
问题根因与对齐方案
1. nperseg参数的R侧对应项
nperseg是短时傅里叶变换(STFT)计算中单段分析窗的采样点长度,直接对应seewave包spectro函数的wl(window length)参数,单位同为采样点。当前代码中nperseg=1024,在R侧设置wl=1024即可对齐该参数。
关键差异点:
Soundecology的acoustic_diversity函数默认不暴露STFT计算参数,内部固定调用seewavespectro时默认wl=512,这是当前结果不对齐的首要原因。
2. 其余隐式默认参数差异
仅对齐窗长无法完全复现结果,还需统一以下未显式暴露的计算逻辑:
- 窗重叠率:Scikit-maad中
noverlap=None时默认取nperseg//2(即50%重叠),seewavespectro默认ovlp=50,该参数默认状态下是对齐的,手动修改时需保持两边一致。 - 幅值归一化基准:Scikit-maad输出的
Sxx_power为功率谱密度,默认归一化到全信号幅值范围后转dB;Soundecology内部以信号峰值为0dB参考做归一化,二者参考基准不同会直接导致-50dB阈值的判定结果出现偏差。 - 频带分箱逻辑:Scikit-maad基于STFT输出的原始频率轴做线性分箱,Soundecology内部会先对频率轴做插值再分箱,边界值计算存在细微差异。
3. 结果对齐的R侧实现
不要直接调用acoustic_diversity的默认逻辑,手动传入对齐参数计算的声谱图即可得到与Scikit-maad一致的结果,参考代码如下:
library(tuneR) library(seewave) library(soundecology) a <- readWave("wav_files/AM08_Grotte-New_2019-10-04_0FE081F80FE081F0_2019-07-26_000000_UTC.wav") # 计算与Scikit-maad参数对齐的声谱图 spec <- spectro(a, wl=1024, ovlp=50, wn="hanning", norm=FALSE, plot=FALSE) # 对齐dB归一化基准:以全局最大功率为0dB参考 spec_dB <- 10*log10(spec$amp/max(spec$amp, na.rm=TRUE)) # 传入对齐后的声谱图计算ADI adi <- acoustic_diversity(a, max_freq = 10000, db_threshold = -50, freq_step = 1000, shannon = TRUE, custom_spec = spec_dB)
注意:不同版本的soundecology对自定义声谱图传入的支持略有差异,若所用版本不支持custom_spec参数,可直接复制包内ADI计算的源码,替换声谱图输入部分即可。
内容的提问来源于stack exchange,提问作者ValeriaFerrario
相关产品推荐
相关产品推荐

