Lib updates
This commit is contained in:
+91
-19
@@ -12,11 +12,47 @@ from cx_utils import m_shape
|
||||
def w_pls_cv_val(X, Y, amax, n_blocks=None, algo='simpls'):
|
||||
"""Returns rmsep and aopt for pls tailored for wide X.
|
||||
|
||||
The root mean square error of cross validation is calculated
|
||||
based on random block cross-validation. With number of blocks equal to
|
||||
number of samples [default] gives leave-one-out cv.
|
||||
The pls model is based on the simpls algorithm for wide X.
|
||||
|
||||
comments:
|
||||
-- X, Y inputs need to be centered (fixme: check)
|
||||
:Parameters:
|
||||
X : ndarray
|
||||
column centered data matrix of size (samples x variables)
|
||||
Y : ndarray
|
||||
column centered response matrix of size (samples x responses)
|
||||
amax : scalar
|
||||
Maximum number of components
|
||||
n_blocks : scalar
|
||||
Number of blocks in cross validation
|
||||
|
||||
:Returns:
|
||||
rmsep : ndarray
|
||||
Root Mean Square Error of cross-validated Predictions
|
||||
aopt : scalar
|
||||
Guestimate of the optimal number of components
|
||||
|
||||
:SeeAlso:
|
||||
- pls_cv_val : Same output, not optimised for wide X
|
||||
- w_simpls : Simpls algorithm for wide X
|
||||
|
||||
Notes
|
||||
-----
|
||||
Based (cowardly translated) on m-files from the Chemoact toolbox
|
||||
X, Y inputs need to be centered (fixme: check)
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
>>> import numpy as n
|
||||
>>> X = n.array([[1., 2., 3.],[]])
|
||||
>>> Y = n.array([[1., 2., 3.],[]])
|
||||
>>> w_pls(X, Y, 1)
|
||||
[4,5,6], 1
|
||||
"""
|
||||
|
||||
k, l = m_shape(Y)
|
||||
PRESS = zeros((l, amax+1), dtype='f')
|
||||
if n_blocks==None:
|
||||
@@ -30,7 +66,7 @@ def w_pls_cv_val(X, Y, amax, n_blocks=None, algo='simpls'):
|
||||
if algo=='simpls':
|
||||
dat = w_simpls(Din, Yin, amax)
|
||||
Q, U, H = dat['Q'], dat['U'], dat['H']
|
||||
That = dot(Doi, dot(U, inv(triu(dot(H.T,U))) ))
|
||||
That = dot(Doi, dot(U, inv(triu(dot(H.T, U))) ))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -40,21 +76,13 @@ def w_pls_cv_val(X, Y, amax, n_blocks=None, algo='simpls'):
|
||||
E = Yout[:,j][:,newaxis] - TQ
|
||||
E = E + sum(E, 0)/Din.shape[0]
|
||||
PRESS[j,1:] = PRESS[j,1:] + sum(E**2, 0)
|
||||
#Yhat = Y - dot(That,Q.T)
|
||||
Yhat = Y - dot(That,Q.T)
|
||||
rmsep = sqrt(PRESS/Y.shape[0])
|
||||
aopt = find_aopt_from_sep(rmsep)
|
||||
return rmsep, aopt
|
||||
return rmsep, Yhat, aopt
|
||||
|
||||
def pls_val(X, Y, amax=2, n_blocks=10, algo='pls', metric=None):
|
||||
""" Validation results of pls model.
|
||||
|
||||
|
||||
|
||||
comments:
|
||||
-- X, Y inputs need to be centered (fixme: check)
|
||||
|
||||
|
||||
"""
|
||||
|
||||
k, l = m_shape(Y)
|
||||
PRESS = zeros((l, amax+1), dtype='<f8')
|
||||
EE = zeros((amax, k, l), dtype='<f8')
|
||||
@@ -79,7 +107,30 @@ def pls_val(X, Y, amax=2, n_blocks=10, algo='pls', metric=None):
|
||||
|
||||
rmsep = sqrt(PRESS/(k-1.))
|
||||
aopt = find_aopt_from_sep(rmsep)
|
||||
return rmsep, aopt
|
||||
return rmsep, Yhat, aopt
|
||||
|
||||
def lpls_val(X, Y, Z, a_max=2, nsets=None,alpha=.5):
|
||||
"""Performs crossvalidation to get generalisation error in lpls"""
|
||||
cv_iter = select_generators.pls_gen(X, Y, n_blocks=nsets,center=False,index_out=True)
|
||||
k, l = Y.shape
|
||||
Yhat = empty((a_max,k,l), 'd')
|
||||
for i, (xcal,xi,ycal,yi,ind) in enumerate(cv_iter):
|
||||
T, W, P, Q, U, L, K, B, b0, evx, evy, evz = nipals_lpls(xcal,ycal,Z,
|
||||
a_max=a_max,
|
||||
alpha=alpha,
|
||||
mean_ctr=[2,0,1],
|
||||
verbose=False)
|
||||
for a in range(a_max):
|
||||
Yhat[a,ind,:] = b0[a][0][0] + dot(xi, B[a])
|
||||
Yhat_class = zeros_like(Yhat)
|
||||
for a in range(a_max):
|
||||
for i in range(k):
|
||||
Yhat_class[a,i,argmax(Yhat[a,i,:])]=1.0
|
||||
class_err = 100*((Yhat_class+Y)==2).sum(1)/Y.sum(0).astype('d')
|
||||
sep = (Y - Yhat)**2
|
||||
rmsep = sqrt(sep.mean(1))
|
||||
aopt = find_aopt_from_sep(rmsep)
|
||||
return rmsep, Yhat, aopt
|
||||
|
||||
def pca_alter_val(a, amax, n_sets=10, method='diag'):
|
||||
"""Pca validation by altering elements in X.
|
||||
@@ -146,8 +197,7 @@ def pls_jkW(a, b, amax, n_blocks=None, algo='pls', use_pack=True, center=True, m
|
||||
if n_blocks == None:
|
||||
n_blocks = b.shape[0]
|
||||
|
||||
Wcv = empty((n_blocks, a.shape[1], amax), dtype='f')
|
||||
|
||||
Wcv = empty((n_blocks, a.shape[1], amax), dtype='d')
|
||||
if use_pack and metric==None:
|
||||
u, s, inflater = svd(a, full_matrices=0)
|
||||
a = u*s
|
||||
@@ -161,11 +211,10 @@ def pls_jkW(a, b, amax, n_blocks=None, algo='pls', use_pack=True, center=True, m
|
||||
dat = bridge(a_in, b_in, amax, 'loads', 'fast')
|
||||
|
||||
W = dat['W']
|
||||
|
||||
if use_pack and metric==None:
|
||||
W = dot(inflater.T, W)
|
||||
|
||||
Wcv[nn,:,:] = W
|
||||
Wcv[nn,:,:] = W[:,:,]
|
||||
|
||||
return Wcv
|
||||
|
||||
@@ -200,6 +249,29 @@ def pca_jkP(a, aopt, n_blocks=None, metric=None):
|
||||
return PP
|
||||
|
||||
|
||||
def lpls_jk(X, Y, Z, a_max, nsets=None, alpha=.5):
|
||||
cv_iter = select_generators.pls_gen(X, Y, n_blocks=nsets,center=False,index_out=False)
|
||||
m, n = X.shape
|
||||
k, l = Y.shape
|
||||
o, p = Z.shape
|
||||
if nsets==None:
|
||||
nsets = m
|
||||
WWx = empty((nsets, n, a_max), 'd')
|
||||
WWz = empty((nsets, o, a_max), 'd')
|
||||
#WWy = empty((nsets, l, a_max), 'd')
|
||||
for i, (xcal,xi,ycal,yi) in enumerate(cv_iter):
|
||||
T, W, P, Q, U, L, K, B, b0, evx, evy, evz = nipals_lpls(xcal,ycal,Z,
|
||||
a_max=a_max,
|
||||
alpha=alpha,
|
||||
mean_ctr=[2,0,1],
|
||||
scale='loads',
|
||||
verbose=False)
|
||||
WWx[i,:,:] = W
|
||||
WWz[i,:,:] = L
|
||||
#WWy[i,:,:] = Q
|
||||
|
||||
return WWx, WWz
|
||||
|
||||
def find_aopt_from_sep(sep, method='75perc'):
|
||||
"""Returns an estimate of optimal number of components from rmsecv.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user