lolamontes69

welcome_to_the_nmf.py for Ch10 Programming Collective Intell

Sep 4th, 2013
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.63 KB | None | 0 0
  1. """ I added this version of NMF that is about 15/20 times faster and in my opinion more accurate in the results it gives - lolamontes69
  2. # NMF by alternative non-negative least squares using projected gradients
  3. # Author: Chih-Jen Lin, National Taiwan University
  4. # Python/numpy translation: Anthony Di Franco
  5. # Adapted for the Chapter 10 Programming Collective Intelligence by lolamontes69  *see end for usage
  6. """
  7. import random as random
  8. from numpy import *
  9. from numpy.linalg import norm
  10. from time import time
  11. from sys import stdout
  12.  
  13. def factorize(v1, pc, maxiter):
  14.     ic, fc = shape(v1)
  15.     temp1=v1.tolist()
  16.     v=array(temp1)
  17.  
  18.     w = array([[random.random() for j in range(pc)] for i in range(ic)])
  19.     h = array([[random.random() for i in range(fc)] for i in range(pc)])
  20.  
  21.     wo,ho = nmf(v, w, h, 0.00000001, 900, maxiter)
  22.  
  23.     temp2=wo.tolist()
  24.     wo1=matrix(temp2)
  25.     temp3=ho.tolist()
  26.     ho1=matrix(temp3)
  27.  
  28.     return wo1, ho1
  29.  
  30. def nmf(V,Winit,Hinit,tol,timelimit,maxiter):
  31.     """
  32.    (W,H) = nmf(V,Winit,Hinit,tol,timelimit,maxiter)
  33.    W,H: output solution
  34.    Winit,Hinit: initial solution
  35.    tol: tolerance for a relative stopping condition
  36.    timelimit, maxiter: limit of time and iterations
  37.    """
  38.  
  39.     W = Winit; H = Hinit; initt = time();
  40.  
  41.     gradW = dot(W, dot(H, H.T)) - dot(V, H.T)
  42.     gradH = dot(dot(W.T, W), H) - dot(W.T, V)
  43.     initgrad = norm(r_[gradW, gradH.T])
  44.     print 'Init gradient norm %f' % initgrad
  45.     tolW = max(0.001,tol)*initgrad
  46.     tolH = tolW
  47.  
  48.     for iter in xrange(1,maxiter):
  49.         # stopping condition
  50.         projnorm = norm(r_[gradW[logical_or(gradW<0, W>0)],
  51.                                  gradH[logical_or(gradH<0, H>0)]])
  52.         if projnorm < tol*initgrad or time() - initt > timelimit: break
  53.  
  54.         (W, gradW, iterW) = nlssubprob(V.T,H.T,W.T,tolW,1000)
  55.         W = W.T
  56.         gradW = gradW.T
  57.  
  58.         if iterW==1: tolW = 0.1 * tolW
  59.  
  60.         (H,gradH,iterH) = nlssubprob(V,W,H,tolH,1000)
  61.         if iterH==1: tolH = 0.1 * tolH
  62.  
  63.         if iter % 10 == 0: stdout.write('.')
  64.  
  65.     print '\nIter = %d Final proj-grad norm %f' % (iter, projnorm)
  66.     return (W,H)
  67.  
  68. def nlssubprob(V,W,Hinit,tol,maxiter):
  69.     """
  70.    H, grad: output solution and gradient
  71.    iter: #iterations used
  72.    V, W: constant matrices
  73.    Hinit: initial solution
  74.    tol: stopping tolerance
  75.    maxiter: limit of iterations
  76.    """
  77.  
  78.     H = Hinit
  79.     WtV = dot(W.T, V)
  80.     WtW = dot(W.T, W)
  81.  
  82.     alpha = 1; beta = 0.1;
  83.     for iter in xrange(1, maxiter):  
  84.         grad = dot(WtW, H) - WtV
  85.         projgrad = norm(grad[logical_or(grad < 0, H >0)])
  86.         if projgrad < tol: break
  87.  
  88.         # search step size
  89.         for inner_iter in xrange(1,20):
  90.             Hn = H - alpha*grad
  91.             Hn = where(Hn > 0, Hn, 0)
  92.             d = Hn-H
  93.             gradd = sum(grad * d)
  94.             dQd = sum(dot(WtW,d) * d)
  95.             suff_decr = 0.99*gradd + 0.5*dQd < 0;
  96.             if inner_iter == 1:
  97.                 decr_alpha = not suff_decr; Hp = H;
  98.             if decr_alpha:
  99.                 if suff_decr:
  100.                     H = Hn; break;
  101.                 else:
  102.                     alpha = alpha * beta;
  103.             else:
  104.                 if not suff_decr or (Hp == Hn).all():
  105.                     H = Hp; break;
  106.                 else:
  107.                     alpha = alpha/beta; Hp = Hn;
  108.  
  109.         if iter == maxiter:
  110.             print 'Max iter in nlssubprob'
  111.     return (H, grad, iter)
  112.  
  113. """
  114. *************
  115. Example Usage
  116. *************
  117. import newsfeatures as newsfeatures
  118. import welcome_to_the_nmf as new_nmf
  119. from numpy import *
  120.  
  121. allw,artw,artt=newsfeatures.getarticlewords()
  122. wordmatrix,wordvec=newsfeatures.makematrix(allw,artw)
  123. v=matrix(wordmatrix)
  124. weights,feat=new_nmf.factorize(v,pc=20,maxiter=5000)
  125. topp,pn=newsfeatures.showfeatures(weights,feat,artt,wordvec,out='todays_features.txt')
  126. newsfeatures.showarticles(artt,topp,pn,out='todays_articles.txt')
  127. -------------------------------------------------------------------------------
  128. *******************************************
  129. Variables in line 20: have fun with them :)
  130. *******************************************
  131. wo,ho = alt_nmf.nmf(v, w, h, tol, timelimit, iter)
  132.  
  133.    v is the matrix converted to an array
  134.    w and h are the two randomly generated factors of v converted to arrays
  135.    tol is the degree of error allowed before stopping
  136.    timelimit is the time allowed before stopping
  137.    iter the iterations to perform before stopping
  138.  
  139. The usage of factorize() is the same as using factorize in Chapter 10 but
  140. about 15/20 times faster and it appears more accurate too :D
  141. Note: can be optimized further
  142.  
  143. """
Advertisement
Add Comment
Please, Sign In to add comment