emwnenmf_old_10-03.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import numpy as np
  2. import time
  3. def emwnenmf(data,G,F,r,Tmax):
  4. MinIter = 10
  5. tol = 1e-5
  6. em_iter_max = round(Tmax/0.05)+1 #
  7. T = np.empty(shape=(em_iter_max+1))
  8. T.fill(np.nan)
  9. RMSE = np.empty(shape=(2,em_iter_max+1))
  10. RMSE.fill(np.nan)
  11. ITER_MAX=100 # maximum inner iteration number (Default)
  12. ITER_MIN=15 # minimum inner iteration number (Default)
  13. np.put(F,data.idxOF,data.sparsePhi_F)
  14. np.put(G,data.idxOG,data.sparsePhi_G)
  15. Xcomp = data.X + np.multiply(data.nW,np.dot(G,F))
  16. FXt = np.dot(F,Xcomp.T)
  17. FFt = np.dot(F,F.T)
  18. GtX = np.dot(G.T,Xcomp)
  19. GtG = np.dot(G.T,G)
  20. GradG = np.dot(G,FFt)-FXt.T
  21. GradF = np.dot(GtG,F)-GtX
  22. init_delta = stop_rule(np.hstack((G.T,F)),np.hstack((GradG.T,GradF)))
  23. tolF = max(tol,1e-3)*init_delta
  24. tolG = tolF # Stopping tolerance
  25. # Iterative updating
  26. G = G.T
  27. k = 0
  28. RMSE[:,k] = np.linalg.norm(F[:,0:-1]-data.F[:,0:-1],2,axis=1)/np.sqrt(F.shape[1]-1)
  29. T[k] = 0
  30. t = time.time()
  31. # Main loop
  32. while time.time()-t <= Tmax+0.05:
  33. # Estimation step
  34. Xcomp = data.X + np.multiply(data.nW,np.dot(G.T,F))
  35. # Compress left and right
  36. L,R = RSI_compression(Xcomp,r)
  37. X_L = np.dot(L,Xcomp)
  38. X_R = np.dot(Xcomp,R)
  39. # Maximisation step
  40. # Optimize F with fixed G
  41. F,iterF,_ = NNLS(F,GtG,GtX,ITER_MIN,ITER_MAX,tolF)
  42. np.put(F,data.idxOF,data.sparsePhi_F)
  43. # print(F[:,0:5])
  44. if iterF<=ITER_MIN:
  45. tolF = tolF/10
  46. print('Tweaked F tolerance to '+str(tolF))
  47. F_comp = np.dot(F,R)
  48. FFt = np.dot(F_comp,F_comp.T)
  49. FXt = np.dot(F_comp,X_R.T)
  50. # Optimize G with fixed F
  51. G,iterG,GradG = NNLS(G,FFt,FXt,ITER_MIN,ITER_MAX,tolG)
  52. np.put(G.T,data.idxOG,data.sparsePhi_G)
  53. if iterG<=ITER_MIN:
  54. tolG = tolG/10
  55. print('Tweaked G tolerance to '+str(tolG))
  56. G_comp = np.dot(G,L.T)
  57. GtG = np.dot(G_comp,G_comp.T)
  58. GtX = np.dot(G_comp,X_L)
  59. GradF = np.dot(GtG,F) - GtX
  60. # Stopping condition
  61. # delta = stop_rule(np.hstack((G,F)),np.hstack((GradG,GradF)))
  62. # if (delta<=tol*init_delta and k>=MinIter):
  63. # print('break before Tmax')
  64. # break
  65. if time.time()-t - k*0.05 >= 0.05:
  66. k = k+1
  67. RMSE[:,k] = np.linalg.norm(F[:,0:-1]-data.F[:,0:-1],2,axis=1)/np.sqrt(F.shape[1]-1)
  68. T[k] = time.time()-t
  69. if k%100==0:
  70. print(str(k)+' '+str(RMSE[0,k])+' '+str(RMSE[1,k])+' '+str(nmf_norm_fro(Xcomp,G.T,F)))
  71. # return {'G' : G.T, 'F' : F, 'RMSE' : RMSE, 'T': T, 'RMSEb' : RMSEb}
  72. return {'G' : G.T, 'F' : F, 'RMSE' : RMSE, 'T': T}
  73. def stop_rule(X,GradX):
  74. # Stopping Criterions
  75. pGrad = GradX[np.any(np.dstack((X>0,GradX<0)),2)]
  76. return np.linalg.norm(pGrad,2)
  77. def NNLS(Z,GtG,GtX,iterMin,iterMax,tol):
  78. L = np.linalg.norm(GtG,2) # Lipschitz constant
  79. H = Z # Initialization
  80. Grad = np.dot(GtG,Z)-GtX #Gradient
  81. alpha1 = 1
  82. for iter in range(1,iterMax+1):
  83. H0 = H
  84. H = np.maximum(Z-Grad/L,0) # Calculate squence 'Y'
  85. alpha2 = 0.5*(1+np.sqrt(1+4*alpha1**2))
  86. Z = H + ((alpha1-1)/alpha2)*(H-H0)
  87. alpha1 = alpha2
  88. Grad=np.dot(GtG,Z)-GtX
  89. # Stopping criteria
  90. if iter>=iterMin:
  91. # Lin's stopping criteria
  92. pgn = stop_rule(Z,Grad)
  93. if pgn <= tol:
  94. break
  95. return H,iter,Grad
  96. def nmf_norm_fro(X,G,F,*args):
  97. W = args
  98. if len(W)==0:
  99. f = np.square(np.linalg.norm(X-np.dot(G,F),'fro'))/np.square(np.linalg.norm(X,'fro'))
  100. else:
  101. W=W[0]
  102. f = np.square(np.linalg.norm(X-np.multiply(W,np.dot(G,F)),'fro'))/np.square(np.linalg.norm(X,'fro'))
  103. return f
  104. def RSI_compression(X,r):
  105. compressionLevel = 20
  106. m,n = X.shape
  107. l = min(n,max(compressionLevel,r+10))
  108. OmegaL = np.random.randn(n,l)
  109. Y = np.dot(X,OmegaL)
  110. for _ in range(4):
  111. Y = np.linalg.qr(Y,mode='reduced')[0]
  112. S = np.dot(X.T,Y)
  113. Z = np.linalg.qr(S,mode='reduced')[0]
  114. Y = np.dot(X,Z)
  115. L = np.linalg.qr(Y,mode='reduced')[0].T
  116. OmegaR = np.random.randn(l,m)
  117. Y = np.dot(OmegaR,X)
  118. for _ in range(4):
  119. Y = np.linalg.qr(Y.T,mode='reduced')[0]
  120. S = np.dot(X,Y)
  121. Z = np.linalg.qr(S,mode='reduced')[0]
  122. Y = np.dot(Z.T,X)
  123. R = np.linalg.qr(Y.T,mode='reduced')[0]
  124. return L,R