-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug] optimal_kernel_bandwidth yields extremely large kernel widths #461
Comments
Thank you for reporting this and your effort to contribute to elephant. I have extended your minimal example to illustrate the issue in connection with import pickle
import quantities as pq
import elephant
import matplotlib.pyplot as plt
# Load example spiketrains
high_firing_rate_st, low_firing_rate_st = pickle.load(
open('spiketrain_examples.pkl', 'rb'))
# firing rates
print(high_firing_rate_st.annotations)
print(low_firing_rate_st.annotations)
# Look at kernel bandwidth estimation
# spiketrain = high_firing_rate_st
spiketrain = low_firing_rate_st
spiketimes = spiketrain.times.rescale(pq.s).magnitude
# Choose example spiketrain
kernel_bandwidth = elephant.statistics.optimal_kernel_bandwidth(spiketimes)
print(f'The optimal kernel bandwidth for the full length spiketrain was '
f'estimated to be {kernel_bandwidth["optw"]} s')
# Time slice the spiketrain to a 5 s duration
time_sliced_st = spiketrain.time_slice(t_start=1*pq.s, t_stop=6*pq.s)
spiketimes_sliced = time_sliced_st.times.rescale(pq.s).magnitude
kernel_bandwidth_sliced = elephant.statistics.optimal_kernel_bandwidth(
spiketimes_sliced)
print(f'The optimal kernel bandwidth for the full length spiketrain was '
f'estimated to be {kernel_bandwidth_sliced["optw"]} s')
# Look at instantaneous rate
def plot_rate(inst_rate):
plt.plot(inst_rate.times.simplified.magnitude,
inst_rate.magnitude, color='orange',
label='instantaneous rate')
plt.legend()
plt.title(f"{inst_rate.annotations['kernel']['type']}: "
f"sigma={inst_rate.annotations['kernel']['sigma']}, "
f"sampling_period={int(sampling_period.item())} ms")
fig = plt.gcf()
fig.set_size_inches(18.5, 10.5)
plt.show()
sampling_period = 10 * pq.ms
# use kernel "auto"
rate_auto = elephant.statistics.instantaneous_rate(
spiketrain,
sampling_period=sampling_period,
kernel="auto")
# plot result
plot_rate(rate_auto) # calculate rate using kernel bandwidth based on time slice
kernel = elephant.kernels.GaussianKernel(
sigma=kernel_bandwidth_sliced["optw"] * pq.s)
rate_slice = elephant.statistics.instantaneous_rate(
spiketrain,
sampling_period=sampling_period,
kernel=kernel)
# plot result
plot_rate(rate_slice) The two figures above show the difference for large and small kernel bandwidths. possible solutions
I guess further steps should be discussed in connection to PR #462, thanks again for contributing this. |
Hi Moritz, thanks for having a look at it so quickly! Just to clarify a few points:
Having said that, I agree that we can move the discussion to PR #462 . |
Describe the bug
The estimation of the instantaneous_rate with
kernel="auto"
of a very long spiketrain (~650 s) yielded a very smooth and flat rate. It was tracked down to the estimation of the optimal_kernel_bandwidth (the width of the Gaussian kernel, fixed for the whole duration), which yielded a bandwidth of ~22 s for spiketrain with a rather low firing rate.After some investigation, it was noticed that the optimal bandwidth strongly depends on the duration of the spiketrain. One reason for this might be the hard-coded number of bins (1000) here:
elephant/elephant/statistics.py
Lines 1576 to 1597 in 67dd3f3
Although, the option to give an array of
times
on which the optimization of the kernel is performed exists, it is not very accessible. (See original publication Shimazaki, H. & Shinomoto, S. Kernel bandwidth optimization in spike rate estimation. J Comput Neurosci 29, 171–182 (2010). for details)Further notice: The implemented optimal_kernel_bandwidth estimates one fixed kernel bandwidth for the given spiketrain and is not adaptive over time! The originating code https://github.com/cooperlab/AdaptiveKDE also implements the adaptive case and could be included into elephant.
To Reproduce
elephant.statistics.optimal_kernel_bandwidth(spiketimes)
A minimal example is provided in the attached files:
issue_optimal_kernel_bandwidth.zip
Expected behavior
The order of magnitude should be reasonable and if this is exceeded a warning should be raise.
Environment
conda
,pip
, source): conda/pipneo
python package version: 0.10.2elephant
python package version: 0.10.0The text was updated successfully, but these errors were encountered: