Cleaned esvd routine, added subfunc scale
This commit is contained in:
parent
d055a1f882
commit
168384f266
|
@ -7,7 +7,7 @@ import math
|
||||||
from scipy.linalg import svd,inv
|
from scipy.linalg import svd,inv
|
||||||
from scipy import dot,empty,eye,newaxis,zeros,sqrt,diag,\
|
from scipy import dot,empty,eye,newaxis,zeros,sqrt,diag,\
|
||||||
apply_along_axis,mean,ones,randn,empty_like,outer,r_,c_,\
|
apply_along_axis,mean,ones,randn,empty_like,outer,r_,c_,\
|
||||||
rand,sum,cumsum,matrix, expand_dims,minimum,where
|
rand,sum,cumsum,matrix, expand_dims,minimum,where,arange
|
||||||
has_sym=True
|
has_sym=True
|
||||||
try:
|
try:
|
||||||
from symeig import symeig
|
from symeig import symeig
|
||||||
|
@ -67,12 +67,12 @@ def pca(a, aopt,scale='scores',mode='normal',center_axis=0):
|
||||||
if center_axis>=0:
|
if center_axis>=0:
|
||||||
a = a - expand_dims(a.mean(center_axis), center_axis)
|
a = a - expand_dims(a.mean(center_axis), center_axis)
|
||||||
if m>(n+100) or n>(m+100):
|
if m>(n+100) or n>(m+100):
|
||||||
u, e, v = esvd(a, amax=None) # fixme:amax option need to work with expl.var
|
u, s, v = esvd(a, amax=None) # fixme:amax option need to work with expl.var
|
||||||
s = sqrt(e)
|
print s[:10]
|
||||||
else:
|
else:
|
||||||
u, s, vt = svd(a, 0)
|
u, s, vt = svd(a, 0)
|
||||||
v = vt.T
|
v = vt.T
|
||||||
e = s**2
|
e = s**2
|
||||||
tol = 1e-10
|
tol = 1e-10
|
||||||
eff_rank = sum(s>s[0]*tol)
|
eff_rank = sum(s>s[0]*tol)
|
||||||
aopt = minimum(aopt, eff_rank)
|
aopt = minimum(aopt, eff_rank)
|
||||||
|
@ -189,7 +189,7 @@ def pcr(a, b, aopt, scale='scores',mode='normal',center_axis=0):
|
||||||
dat.update({'Q':Q, 'F':F, 'expvary':expvary})
|
dat.update({'Q':Q, 'F':F, 'expvary':expvary})
|
||||||
return dat
|
return dat
|
||||||
|
|
||||||
def pls(a, b, aopt=2, scale='scores', mode='normal', center_axis=0, ab=None):
|
def pls(a, b, aopt=2, scale='scores', mode='normal', center_axis=-1, ab=None):
|
||||||
"""Partial Least Squares Regression.
|
"""Partial Least Squares Regression.
|
||||||
|
|
||||||
Performs PLS on given matrix and returns results in a dictionary.
|
Performs PLS on given matrix and returns results in a dictionary.
|
||||||
|
@ -696,34 +696,38 @@ def esvd(data, amax=None):
|
||||||
if m>=n:
|
if m>=n:
|
||||||
kernel = dot(data.T, data)
|
kernel = dot(data.T, data)
|
||||||
if has_sym:
|
if has_sym:
|
||||||
if not amax:
|
if amax==None:
|
||||||
amax = n-1
|
amax = n
|
||||||
pcrange = [n-amax, n]
|
pcrange = None
|
||||||
|
else:
|
||||||
|
pcrange = [n-amax, n]
|
||||||
|
print "symm>n"
|
||||||
s, v = symeig(kernel, range=pcrange, overwrite=True)
|
s, v = symeig(kernel, range=pcrange, overwrite=True)
|
||||||
s = s[::-1]
|
s = s[::-1]
|
||||||
v = v[:,arange(n, -1, -1)]
|
v = v[:,::-1]
|
||||||
else:
|
else:
|
||||||
u, s, vt = svd(kernel)
|
u, s, vt = svd(kernel)
|
||||||
v = vt.T
|
v = vt.T
|
||||||
u = dot(data, v)
|
s = sqrt(s)
|
||||||
for i in xrange(amax):
|
u = dot(data, v)/s
|
||||||
s[i] = vnorm(u[:,i])
|
|
||||||
u[:,i] = u[:,i]/s[i]
|
|
||||||
else:
|
else:
|
||||||
kernel = dot(data, data.T)
|
kernel = dot(data, data.T)
|
||||||
if has_sym:
|
if has_sym:
|
||||||
if not amax:
|
if amax==None:
|
||||||
amax = m-1
|
amax = m
|
||||||
pcrange = [m-amax, m]
|
pcrange = None
|
||||||
|
else:
|
||||||
|
pcrange = [m-amax, m]
|
||||||
|
print "sym (m<n)"
|
||||||
s, u = symeig(kernel, range=pcrange, overwrite=True)
|
s, u = symeig(kernel, range=pcrange, overwrite=True)
|
||||||
|
s = s[::-1]
|
||||||
|
u = u[:,::-1]
|
||||||
else:
|
else:
|
||||||
u, s, vt = svd(kernel)
|
u, s, vt = svd(kernel)
|
||||||
v = dot(u.T, data)
|
s = sqrt(s)
|
||||||
for i in xrange(amax):
|
v = dot(data.T, u)/s
|
||||||
s[i] = vnorm(v[i,:])
|
print s[:2]
|
||||||
v[i,:] = v[i,:]/s[i]
|
return u, s, v
|
||||||
|
|
||||||
return u, s, v.T
|
|
||||||
|
|
||||||
def vnorm(x):
|
def vnorm(x):
|
||||||
# assume column arrays (or vectors)
|
# assume column arrays (or vectors)
|
||||||
|
@ -744,3 +748,16 @@ def center(a, axis):
|
||||||
raise IOError("input error: axis must be in [-1,0,1,2]")
|
raise IOError("input error: axis must be in [-1,0,1,2]")
|
||||||
|
|
||||||
return a - mn, mn
|
return a - mn, mn
|
||||||
|
|
||||||
|
def scale(a, axis):
|
||||||
|
if axis==-1:
|
||||||
|
sc = zeros((a.shape[1],))
|
||||||
|
elif axis==0:
|
||||||
|
sc = a.std(0)
|
||||||
|
elif axis==1:
|
||||||
|
sc = a.std(1)[:,newaxis]
|
||||||
|
else:
|
||||||
|
raise IOError("input error: axis must be in [-1,0,1]")
|
||||||
|
|
||||||
|
return a - sc, sc
|
||||||
|
|
||||||
|
|
Reference in New Issue