2014-10-06 43 views
5

我有一組N觀測值在一個二維空間中以(x[i], y[i]), i=0..N分佈。每個點在兩個座標(e_x[i], e_y[i], i=0..N)中都有相關的錯誤,並且還有一個與其相關的權重(w[i], i=0..N)。創建直方圖時記錄錯誤

我想生成這些N點的2D直方圖,佔比不僅爲權重,但也爲錯誤,這將導致每個點是傳播可能在許多垃圾箱如果誤差值大足夠的(假設標準Gaussian distribution爲錯誤,儘管也許可以考慮其他分佈)。

我看到numpy.histogram2d有一個weights參數,所以這是照顧。問題是如何解釋每個觀察點的錯誤。

有沒有讓我這樣做的功能?我願意接受numpyscipy的任何內容。

+0

什麼這些錯誤值代表什麼?這些標準偏差沿着主軸? – 2014-11-19 10:09:52

+0

@Dabrion恰好。 – Gabriel 2014-11-19 11:48:24

+0

好吧,那組參數構成了一個多變量GMM,給定權重(\ pi_i),樣本作爲平均值(\ mu_i)和協方差矩陣(\ Sigma_i)由[[e_x [i] ** 2,0] [ 0,E_Y [I] ** 2]]。與您假設的標準正態情況(對應於所有e_x和e_y等於1.0)不同,您可以使用協方差矩陣,其中對角線可以具有不同的值。這對應於主軸沿主軸的橢圓,而不是圓。這有助於你向前邁進嗎? – 2014-11-19 18:35:24

回答

1

建立在user1415946的評論,你可以假設每個點代表bi-variate normal distribution[[e_x[i]**2,0][0,e_y[i]**2]]給出的協方差矩陣。但是,由此產生的分佈不是一個正態分佈 - 在運行該示例之後,您會看到直方圖根本不像高斯分佈,而是其中的一組分佈。

要從這組分佈中創建直方圖,我看到的一種方法是使用numpy.random.multivariate_normal從每個點中生成隨機樣本。使用一些人造數據查看下面的示例代碼。

import numpy as np 
from mpl_toolkits.mplot3d import Axes3D 
import matplotlib.pyplot as plt 


# This is a function I like to use for plotting histograms 
def plotHistogram3d(hist, xedges, yedges): 
    fig = plt.figure() 
    ax = fig.add_subplot(111, projection='3d') 
    hist = hist.transpose() 
    # Transposing is done so that bar3d x and y match hist shape correctly 
    dx = np.mean(np.diff(xedges)) 
    dy = np.mean(np.diff(yedges)) 

    # Computing the number of elements 
    elements = (len(xedges) - 1) * (len(yedges) - 1) 
    # Generating mesh grids. 
    xpos, ypos = np.meshgrid(xedges[:-1]+dx/2.0, yedges[:-1]+dy/2.0) 

    # Vectorizing matrices 
    xpos = xpos.flatten() 
    ypos = ypos.flatten() 
    zpos = np.zeros(elements) 
    dx = dx * np.ones_like(zpos) * 0.5 # 0.5 factor to give room between bars. 
# Use 1.0 if you want all bars 'glued' to each other 
    dy = dy * np.ones_like(zpos) * 0.5 
    dz = hist.flatten() 

    ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b') 
    ax.set_xlabel('x') 
    ax.set_ylabel('y') 
    ax.set_zlabel('Count') 
    return 

""" 
INPUT DATA 
""" 
#     x y ex ey w 
data = np.array([[1, 2, 1, 1, 1], 
       [3, 0, 1, 1, 2], 
       [0, 1, 2, 1, 5], 
       [7, 7, 1, 3, 1]]) 

""" 
Generate samples 
""" 
# Sample size (100 samples will be generated for each data point) 
SAMPLE_SIZE = 100 
# I want to fill in a table with columns [x, y, w]. Each data point generates SAMPLE_SIZE 
# samples, so we have SAMPLE_SIZE * (number of data points) generated points 
points = np.zeros((SAMPLE_SIZE * data.shape[0], 3)) # Initializing this matrix 

for i, element in enumerate(data): # For each row in the data set 
    meanVector = element[:2] 
    covarianceMatrix = np.diag(element[2:4]**2) # Diagonal matrix with elements equal to error^2 
    # For columns 0 and 1, add generated x and y samples 
    points[SAMPLE_SIZE*i:SAMPLE_SIZE*(i+1), :2] = \ 
     np.random.multivariate_normal(meanVector, covarianceMatrix, SAMPLE_SIZE) 
    # For column 2, simply copy original weight 
    points[SAMPLE_SIZE*i:SAMPLE_SIZE*(i+1), 2] = element[4] # weights 

hist, xedges, yedges = np.histogram2d(points[:, 0], points[:, 1], weights=points[:, 2]) 
plotHistogram3d(hist, xedges, yedges) 
plt.show() 

結果下面的曲線:

enter image description here

+0

Gabriel,您能否添加一些註釋來描述您的示例中每行代碼的作用?另外,你正在運行哪個版本的'matplotlib'?我有版本1.3.1並試圖運行你的例子給了我一個'ValueError:Unknown projection'3d'';這很奇怪,因爲這裏給出的例子http://stackoverflow.com/q/3810865/1391441沒有問題。 – Gabriel 2014-11-29 23:18:36

+1

我使用與您的版本相同的版本,但在回答之前我錯誤地刪除了導入行。這一個應該工作。謝謝 – 2014-11-30 02:24:23