2010-11-08 58 views
7

我試圖使用the scipy.stats.gaussian_kde class來平滑掉一些用緯度和經度信息收集的離散數據,所以它在最後顯示爲與等高線圖有些類似,高密度是高峯,低密度是低谷。使用帶有二維數據的scipy.stats.gaussian_kde

我很難將二維數據集放入gaussian_kde類。我打得四處弄清楚它是如何工作的1個維數據,所以我想沿着線的2維會是這樣:

from scipy import stats 
from numpy import array 
data = array([[1.1, 1.1], 
       [1.2, 1.2], 
       [1.3, 1.3]]) 
kde = stats.gaussian_kde(data) 
kde.evaluate([1,2,3],[1,2,3]) 

這是說,我在[1.1, 1.1], [1.2, 1.2], [1.3, 1.3]有3點。我想要使​​用從1到3的寬度爲1的x和y軸進行核密度估計。

在創建gaussian_kde,它不斷給我這個錯誤:

raise LinAlgError("singular matrix") 
numpy.linalg.linalg.LinAlgError: singular matrix 

展望的gaussian_kde的源代碼,我意識到,我在想是什麼意思數據集的方式是怎麼樣完全不同的維度是計算的,但我找不到任何示例代碼顯示多維數據如何與模塊一起工作。有人可以幫助我用一些示例方法使用gaussian_kde與多維數據?

+0

嘗試使用不是全部在一行中的數據。我不確定它是否會失敗,或者如果它是一個錯誤。 – endolith 2011-06-20 02:35:15

回答

4

我想你是用內插或者內核迴歸來混合內核密度估計的。如果您有更大的點數樣本,KDE會估算點數的分佈。

我不確定你想要哪個插值,但是scipy.interpolate中的splines或rbf會更合適。

如果您想要一維內核迴歸,那麼您可以在具有多個不同內核的scikits.statsmodels中找到一個版本。

更新:這裏有一個例子(如果這是你想要的)

>>> data = 2 + 2*np.random.randn(2, 100) 
>>> kde = stats.gaussian_kde(data) 
>>> kde.evaluate(np.array([[1,2,3],[1,2,3]])) 
array([ 0.02573917, 0.02470436, 0.03084282]) 

gaussian_kde在列行變量和觀察,統計信息,因此扭轉方向從平常的。在你的例子中,所有三個點都在一條線上,因此它具有完美的相關性。也就是我猜,奇異矩陣的原因。

調整陣列方向和增加噪音小,示例工作,但看起來還是很集中,比如你沒有任何附近的採樣點(3,3):

>>> data = np.array([[1.1, 1.1], 
       [1.2, 1.2], 
       [1.3, 1.3]]).T 
>>> data = data + 0.01*np.random.randn(2,3) 
>>> kde = stats.gaussian_kde(data) 
>>> kde.evaluate(np.array([[1,2,3],[1,2,3]])) 
array([ 7.70204299e+000, 1.96813149e-044, 1.45796523e-251]) 
+0

我不是統計學家,但是我對KDE和內核迴歸以及噴氣機提到的「等值線圖」的閱讀讓我覺得KDE就是這個意思。 – endolith 2011-05-25 14:40:02

5

This example似乎是你在找什麼:

import numpy as np 
import scipy.stats as stats 
from matplotlib.pyplot import imshow 

# Create some dummy data 
rvs = np.append(stats.norm.rvs(loc=2,scale=1,size=(2000,1)), 
       stats.norm.rvs(loc=0,scale=3,size=(2000,1)), 
       axis=1) 

kde = stats.kde.gaussian_kde(rvs.T) 

# Regular grid to evaluate kde upon 
x_flat = np.r_[rvs[:,0].min():rvs[:,0].max():128j] 
y_flat = np.r_[rvs[:,1].min():rvs[:,1].max():128j] 
x,y = np.meshgrid(x_flat,y_flat) 
grid_coords = np.append(x.reshape(-1,1),y.reshape(-1,1),axis=1) 

z = kde(grid_coords.T) 
z = z.reshape(128,128) 

imshow(z,aspect=x_flat.ptp()/y_flat.ptp()) 

enter image description here

軸需要修復,效果顯着。

你也可以做數據的散點圖與

scatter(rvs[:,0],rvs[:,1]) 

enter image description here

+0

https://gist.github.com/1035069和http://flic.kr/p/9V6onm例如 – endolith 2011-06-20 16:44:28

+0

當你說,軸需要修復時,你是什麼意思?因爲我對數據做了同樣的處理,出於某種原因,它會在數據的最小值和最大值之間給出一些額外的過剩 – ThePredator 2014-06-13 22:48:20

+0

@Srivatsan:我想我只是想說它應該有一個更加正方形的寬高比 – endolith 2014-06-14 01:25:42

0

張貼在頂部的答案對我來說沒有工作的例子。我不得不稍微調整它,它現在有效:

import numpy as np 
import scipy.stats as stats 
from matplotlib import pyplot as plt 

# Create some dummy data 
rvs = np.append(stats.norm.rvs(loc=2,scale=1,size=(2000,1)), 
       stats.norm.rvs(loc=0,scale=3,size=(2000,1)), 
       axis=1) 

kde = stats.kde.gaussian_kde(rvs.T) 

# Regular grid to evaluate kde upon 
x_flat = np.r_[rvs[:,0].min():rvs[:,0].max():128j] 
y_flat = np.r_[rvs[:,1].min():rvs[:,1].max():128j] 
x,y = np.meshgrid(x_flat,y_flat) 
grid_coords = np.append(x.reshape(-1,1),y.reshape(-1,1),axis=1) 

z = kde(grid_coords.T) 
z = z.reshape(128,128) 

plt.imshow(z,aspect=x_flat.ptp()/y_flat.ptp()) 
plt.show()