2017-04-20 44 views
0

我一直有問題與Matlab轉換爲Python。我在去年(工作)編寫的Matlab中有代碼,現在嘗試將函數轉換爲Python。其中5人工作,4人不工作。我真的陷入困境,並會喜歡一些幫助。 這一個是關於估計樸素貝葉斯概率。下面是在Matlab的功能:估計天真 - 貝葉斯概率函數

function [ p_x_y ] = estimate_p_x_y_NB(Xtrain,ytrain,a,b) 

% Function calculates probability distribution p(x|y), assuming that x is binary 
% and its elements are independent from each other 

% Xtrain - training dataset NxD 
% ytrain - training dataset class labels 1xN 
% p_x_y - binomial distribution estimators - element at position(m,d) 
% represents estimator p(x_d=1|y=m) MxD 
% N - number of elements in training dataset 
D = size(Xtrain,2); 
M = length(unique(ytrain)); 
p_x_y = zeros(M,D); 
for i=1:M 
    for j=1:D 
     numerator = sum((ytrain==i).*((Xtrain(:,j)==1))')+a-1; 
     denominator = sum(ytrain==i)+a+b-2; 
     p_x_y(i,j) = numerator/denominator; 
    end 
end 
end 

這是我翻譯的Python:

def estimate_p_x_y_nb(Xtrain, ytrain, a, b): 
    """ 
    :param Xtrain: training data NxD 
    :param ytrain: class labels for training data 1xN 
    :param a: parameter a of Beta distribution 
    :param b: parameter b of Beta distribution 
    :return: Function calculated probality p(x|y) assuming that x takes binary values and elements 
    x are independent from each other. Function returns matrix p_x_y that has size MxD. 
    """ 
    D = Xtrain.shape[1] 
    M = len(np.unique(ytrain)) 
    p_x_y = np.zeros((M, D)) 
    for i in range (M): 
     for j in range(D): 
      up = np.sum((ytrain == i+1).dot((Xtrain[:, j]==1)).conjugate().T) + a - 1 
      down = np.sum((ytrain == i+1) + a + b -2) 
      p_x_y[i,j] = up/down 
    return p_x_y 

回溯:

p_x_y[i,j] = up/down 
ValueError: setting an array element with a sequence. 

如果你可以看到功能的任何問題,我會非常高興有它指出。此外,我使用.dot而不是*中的up變量,因爲當它是*時,我得到了關於不準確維度的錯誤,但是使用這個錯誤,它似乎正在工作。謝謝。

+0

您是否嘗試過比較MATLAB代碼中的結果與Python在每行中獲得的結果以查看問題出在哪裏?它是縮小問題的簡單方法。或者提供[最小,完整和可驗證示例](http://stackoverflow.com/help/mcve)。 – DavidG

+0

用dot-protuct'dot'替換元素產品'。*'可能是錯誤的。 numpy中的元素明智的產品是'*'。 – kazemakase

+0

@kazemakase好嗎,所以你說它應該可能留*。 (在Python?)。但是當我這樣離開時,我會遇到「ValueError:尺寸不匹配」。我想這是因爲後來的轉置,但它在Matlab中工作:( – Swaglina

回答

3

我認爲在分配分母的語句中存在問題。你做出了一個錯誤的使用括號

down = np.sum((ytrain == i+1) + a + b -2)

的應該是

down = np.sum((ytrain == i+1)) + a + b -2 

此外,嘗試改變

up = np.sum((ytrain == i+1).dot((Xtrain[:, j]==1)).conjugate().T) + a - 1

up = np.sum((ytrain == i+1) * (Xtrain[:, j]==1)) + a - 1 

我希望作品。我沒有看到你的代碼有任何其他問題。

的變化之後,我使用的值

Xtrain = np.array([[1,2,3,4,5], [1,2,3,4,5]]) 
ytrain = np.array([1,2]) 
a = 1 
b = 1 

這給了輸出

array([[ 1., 0., 0., 0., 0.], 
     [ 1., 0., 0., 0., 0.]]) 

兩個MATLAB和Python。如果結果符合預期,您可以使用這些值進行檢查。

+0

謝謝,沒注意到!改變了它,但我的程序仍然錯誤上/下,不幸 – Swaglina

+0

我同意這個ammportal,當我將python代碼更改爲'down = np.sum((ytrain == i + 1))+ a + b -2 '我在python中得到了與matlab相同的答案。 – qbzenker

+0

@林K對我來說,這個改變後沒有錯誤。你確定你的代碼是正確的,並且沒有任何其他干擾它嗎?我編輯了我的答案,以顯示我得到的輸出。 – anyanwu