2011-12-28 49 views
0

我有一個從http://www.albertauyeung.com/mf.php的Python代碼,但我不知道任何有關Python編程來改進和更改此代碼。不管怎麼樣,我開始用C++重新編寫它,但是我的結果是如此不同。 的Python代碼:Python與C++。不同的結果

import numpy 

def matrix_factorisation(R, P, Q, K, steps=5000, alpha=0.0002, beta=0.02): 
Q = Q.T 
for step in xrange(steps): 
    for i in xrange(len(R)): 
     for j in xrange(len(R[i])): 
      if R[i][j] > 0: 
       eij = R[i][j] - numpy.dot(P[i,:],Q[:,j]) 
       for k in xrange(K): 
        P[i][k] = P[i][k] + alpha * (2 * eij * Q[k][j] - beta * P[i][k]) 
        Q[k][j] = Q[k][j] + alpha * (2 * eij * P[i][k] - beta * Q[k][j]) 
    eR = numpy.dot(P,Q) 
    e = 0 
    for i in xrange(len(R)): 
     for j in xrange(len(R[i])): 
      if R[i][j] > 0: 
       e = e + pow(R[i][j] - numpy.dot(P[i,:],Q[:,j]), 2) 
       for k in xrange(K): 
        e = e + (beta/2) * (pow(P[i][k],2) + pow(Q[k][j],2)) 
    if e < 0.001: 
     break 
return P, Q.T 

if __name__ == "__main__": 
R = [ 
[5,3,0,1], 
[4,0,0,1], 
[1,1,0,5], 
[1,0,0,4], 
[0,1,5,4], 
] 

R = numpy.array(R) 

N = len(R) 
M = len(R[0]) 
K = 2 

P = numpy.random.rand(N,K) 
Q = numpy.random.rand(M,K) 

nP, nQ = matrix_factorisation(R, P, Q, K) 
nR = numpy.dot(nP, nQ.T) 

====================================== =========================================== 和C++代碼:

int main(int argc, char *argv[]) 
{ 
QCoreApplication a(argc, argv); 

//=============preliminary================= 
long double R[5][4]={5,3,0,1, 
       4,0,0,1, 
       1,1,0,5, 
       1,0,0,4, 
       0,1,5,4},newR[5][4]={0}; 
int n=5, m=4,k=2; 
long double Q[2][4],P[5][2]; 

for (int i=0;i<k;i++){ 
    for (int j=0;j<n;j++){ 
     P[j][i]=random2(0,1); 
    } 
    for(int l=0;l<m;l++){ 
     Q[i][l]=random2(0,1); 
    } 
} 



// ============= MatrixFactorization(R,P,Q,k)======================= 
long double eij=0,sigmaPQ=0; 
long double e; 
long double alpha=0.0002, beta=0.02; 
int t; 
for(long step=0;step <5000;step++){ 
    t=step; 
    for (int i=0;i<n;i++){ 
     for(int j=0;j<m;j++){ 
      if(R[i][j]>0){ 
       sigmaPQ=0; 
       for (int z=0;z<k;z++){ 
        sigmaPQ += P[i][z]*Q[z][j]; 
       } 
       eij=R[i][j]-sigmaPQ; 

       for (int z=0;z<k;z++){ 
        P[i][z] += alpha*(2*eij*Q[z][j]-beta*P[i][z]); 
        Q[z][j] += alpha*(2*eij*P[i][z]-beta*Q[z][j]); 
       } 
      } 
     } 
    } 
    e=0; 
    for (int i=0;i<n;i++){ 
     for(int j=0;j<m;j++){ 
      if(R[i][j]>0){ 
       sigmaPQ=0; 
       for (int z=0;z<k;z++){ 
        sigmaPQ += P[i][z]*Q[z][j]; 
       }     
       for (int z=0;z<k;z++){ 
        e+=(beta/2)*(qPow(P[i][z],2)+qPow(Q[z][j],2));       
       } 
       e=qSqrt(e); 
      }     
     } 
    }  
    if(e<0.001) 
     break; 

}  
//=========== calculate approximate R ============= 
long double temp; 
for (int i=0;i<n;i++){ 
    for(int j=0;j<m;j++){ 
     temp=0; 
     for(int z=0;z<k;z++){ 
      temp+=P[i][z]*Q[z][j]; 
     } 
     newR[i][j]=temp; 
    } 
} 
} 

Python代碼是正確答案。 我該怎麼做,修復這個C++代碼?

+2

首先你確定在C++中的numpy.random和random2會返回相同的結果嗎?我不這麼認爲...... – 2011-12-28 11:27:19

+0

Tnx,random2是我寫的一個函數。問題不是隨機數。如果我們用一個常量值初始化P和Q,Python將再次正常工作。 – dare 2011-12-28 12:47:31

+4

投票結束:通過使用調試器可以解決(或至少確定)此問題。 – 2011-12-28 13:29:09

回答

0

將其分解成步驟並檢查每個步驟的輸出。 print和printf是你的朋友。 :) 或者學習足夠的Python來創建一個可以轉換爲C++的僞代碼版本。

通常情況下,當調試大代碼段時,我只監視進程中每個邏輯步驟的數據。通過在關鍵位置插入打印語句,Python變得很容易。

相關問題