В Python 3.7 у меня есть этот массив с формой = (2, 34900). Эти массивы представляют собой список координат, где индекс 0 представляет ось X, а индекс 1 представляет ось y.

Когда я использую seaborn.kde_plot () для визуализации распределения этих данных, я могу получить результат примерно через 5-15 секунд при работе на i5 7-го поколения.

Но когда я пытаюсь запустить следующий кусок кода:

#Find the kernel for 
k = scipy.stats.kde.gaussian_kde(data, bw_method=.3)
#Define the grid
xi, yi = np.mgrid[0:1:2000*1j, 0:1:2000*1j]
#apply the function
zi = k(np.vstack([xi.flatten(), yi.flatten()]))

Который находит гауссово ядро для этих данных и применяет его к сетке, которую я определил, это занимает намного больше времени. Я не смог запустить полный массив, но при работе со срезом размером 140, это занимает около 40 секунд.

Срез размером 140 имеет действительно интересный результат, который я смог визуализировать с помощью plt.pcolormesh().

Мой вопрос в том, что мне здесь не хватает. Если я правильно понял, что происходит, я использую scipy.stats.kde.gaussian_kde(), чтобы создать оценку функции, определенной данными. Затем я применяю функцию к двумерному пространству и в результате получаю ее Z-компонент. Затем я строю Z-компонент. Но как этот процесс может отличаться от seaborn.kde_plot(), что делает код намного дольше.

Реализация Scipy просто проходит через каждую точку, делая это:

for i in range(self.n):
    diff = self.dataset[:, i, newaxis] - points
    tdiff = dot(self.inv_cov, diff)
    energy = sum(diff*tdiff,axis=0) / 2.0
    result = result + exp(-energy)
5
Victor 14 Мар 2018 в 00:17

2 ответа

Лучший ответ

Кажется, что Seaborn просто берет образец моих данных. Поскольку размер меньше, он может закончить его в небольшом количестве. С другой стороны, SciPy использует каждую точку в своей обработке. Таким образом, это занимает больше времени с размером набора данных, который я использую.

-2
Victor 21 Апр 2018 в 15:11

У Seaborn есть два способа вычисления двумерного kde. Если доступно, он использует statsmodels, если нет, то возвращается к scipy.

Код scipy похож на то, что показано в вопросе. Он использует scipy.stats.gaussian_kde. В коде statsmodels используется

Если мы рассчитаем эти две функции,

# statsmodels
%timeit f(x,y)  # 1 loop, best of 3: 16.4 s per loop
# scipy
%timeit g(x,y)  # 1 loop, best of 3: 8.67 s per loop

Scipy, следовательно, в два раза быстрее statsmodels (по умолчанию для морского побережья). Причина, по которой код в вопросе занимает так много времени, заключается в том, что вместо сетки размера 100 используется сетка размера 2000.

Видя эти результаты, можно было бы соблазниться использовать scipy вместо statsmodels. К сожалению, это не позволяет выбрать, какой использовать. Следовательно, необходимо вручную установить соответствующий флаг.

import seaborn.distributions as sd
sd._has_statsmodels = False
# plot kdeplot with scipy.stats.kde.gaussian_kde
sns.kdeplot(x,y)
8
ImportanceOfBeingErnest 13 Мар 2018 в 22:31