import scipy.linalg
import utils
import time
import numpy
import copy
from readout import *
from lsqnonneg import lsqnonneg
class LinearRegression(Readout):
''' Linear Regression based on LMS'''
def __init__(self, range=(-1,1), addBias=True):
super(LinearRegression, self).__init__()
self.time = -1
self.range = range
self.addBias = addBias
def train(self, trainSet_X, trainSet_Y):
'''train linear regression'''
t0 = time.time()
# onvert to array
# if type(trainSet_X) is not type('array'):
trainSet_X = numpy.array(trainSet_X)
nDim = trainSet_X.shape[1]
nSamples = len(trainSet_Y)
if nSamples != trainSet_X.shape[0]:
s = 'Number of training samples (%d) '\
'is different from number of target values (%d)!\n' % (trainSet_X.shape[0], nSamples)
raise ReadoutException(s)
# 3. Find least squares solutions
if self.addBias:
trainSet_X = numpy.concatenate((trainSet_X, numpy.ones((trainSet_X.shape[0], 1))), 1)
#print "executing the qr function"
(Q, R)=scipy.linalg.qr(trainSet_X, overwrite_a=1)
# now we solve the regression problems
#print "executing the regression lstsquare algorithm"
self.W = scipy.linalg.lstsq(R, numpy.dot(Q.T, trainSet_Y))[0]
self.trained=True
self.time = time.time() - t0
def apply(self, X):
if not self.trained:
raise ReadoutException('readout is not trained!')
X = numpy.array(X)
if self.addBias:
X = numpy.concatenate((X, numpy.ones((X.shape[0], 1))), 1)
return utils.flatten(numpy.dot(X, self.W).tolist())
def analyse(self, set_X, set_Y):
''' Analyse a trained linear classifier(s) on data
Return values
err - classification error
mse - mean squared error (not very meaningful)
cc - correlation coefficient bewteen target and classifier output
score - error measurement which takes into account the confusion matrix
CM - the confusion matrix: CM(i,j) is the number of examples
classified as class i while beeing actually class j.
mi - mutual information between
target and classifier output (calculated from CM).
hx - entropy of target values
hy - entropy of classifier output'''
if not self.trained:
raise ReadoutException('readout is not trained!')
set_X = numpy.array(set_X)
set_Y = copy.copy(set_Y)
undef = numpy.where(numpy.isnan(set_Y))[0]
# might be replaced by take()
for ind in undef:
set_X[ind,:] = []
set_Y[ind] = []
set_Y = numpy.asarray(set_Y)
if numpy.prod(set_Y.shape) == 0:
return (nan, nan, nan, nan, [], nan, nan, nan)
# apply the classifier
O = numpy.array(self.apply(set_X))
scale=abs(numpy.diff(self.range))
d = (O-set_Y)
# mae=([abs(x) for x in d]).mean() # mean classification error
mae = abs(d).mean() # mean classification error
mse = (d**2/scale**2).mean() # mean squared error: not very meaningful
cc=corr_coeff(O, set_Y) # correlatio coefficient
CM=confusion_matrix(O, set_Y, numpy.array([-1,1])) # confusion matrx
score=CM[0,1]/(1+CM[0,0]+CM[1,0]/(1+CM[1,1])) # error score: takes into account false and positive negatives
(mi,hx,hy,hxy)=mi_from_count(CM) # calculate mutual information and entropies between target and classifier output
kappa =numpy.nan
if cc is numpy.nan:
print "Encountered nan for correlation coefficient"
print "target output", O
print "test output", set_Y
return (mae,mse,cc,score,CM,mi,hx,hy, kappa)
class LinearNonNegRegression(LinearRegression):
''' Linear Non Negative Regression based on LMS'''
def __init__(self, range=(-1,1), addBias=True, addNegBias=False, lsq_iter = 3):
super(LinearNonNegRegression, self).__init__(range=range, addBias=addBias)
self.time = -1
self.addNegBias = addNegBias
self.usefull_dims=None
self.lsq_iter = lsq_iter
def train(self, trainSet_X, trainSet_Y):
'''train linear non negative regression'''
t0 = time.time()
trainSet_X = numpy.array(trainSet_X)
sx = abs(trainSet_X).sum(0)
sx_w=numpy.where(sx>0)[0]
if len(sx_w) > 0:
self.usefull_dims=sx_w
trainSet_X=trainSet_X[:, self.usefull_dims]
else:
self.usefull_dims=None
nDim = trainSet_X.shape[1]
nSamples = len(trainSet_Y)
if nSamples != trainSet_X.shape[0]:
s = 'Number of training samples (%d) '\
'is different from number of target values (%d)!\n' % (trainSet_X.shape[0], nSamples)
raise ReadoutException(s)
if self.addBias:
trainSet_X = numpy.concatenate((trainSet_X, numpy.ones((trainSet_X.shape[0], 1))), 1)
if self.addNegBias:
trainSet_X = numpy.concatenate((trainSet_X, -1*numpy.ones((trainSet_X.shape[0], 1))), 1)
# now we solve the regression problems
[self.W, resnorm, residual] = lsqnonneg(trainSet_X, trainSet_Y, itmax_factor = self.lsq_iter)
self.trained=True
self.time = time.time() - t0
def apply(self, X):
if not self.trained:
raise ReadoutException('readout is not trained!')
X = numpy.array(X)
if self.usefull_dims is not None:
X=X[:, self.usefull_dims]
if self.addBias:
X = numpy.concatenate((X, numpy.ones((X.shape[0], 1))), 1)
if self.addNegBias:
X = numpy.concatenate((X, -1*numpy.ones((X.shape[0], 1))), 1)
return utils.flatten(numpy.dot(X, self.W).tolist())
if __name__=='__main__':
trainSet_X = [[1,2,3],[1,3,3],[2,4,3],[1,1,3],[4,4,5]]
trainSet_Y = [0,1,1,0,1]
trainSet_X = [[1,2,3,2,2],[1,3,3,4,5],[1,4,3,4,5],[2,3,2,1,1],[1,2,3,1,1]]
trainSet_Y = [0,1,2,0,2]
trainSet_X = [[1],[2],[5],[6],[10]]
trainSet_Y = [3, 5, 11, 13, 21]
#testSet_X = [[1,2,4,3,1],[2,4,2,1,2],[1,3,3,3,1]]
testSet_X = [[4],[3],[15]]
testSet_Y = [9,7,3]
trainSet_X0 = [[1,0,0],[2,0,0],[5,0,0],[6,0,0],[10,0,0]]
testSet_X0 = [[4,0,0],[3,0,0],[15,0,0]]
print 'Linear Regression:'
lin_reg = LinearRegression()
lin_reg.train(trainSet_X, trainSet_Y)
testY = lin_reg.apply(testSet_X)
print "training time: ", lin_reg.time
print "W:", lin_reg.W
(mae,mse,cc,score,CM,mi,hx,hy,kappa) = lin_reg.analyse(testSet_X, testSet_Y)
print lin_reg.analyse(testSet_X, testSet_Y)
print 'Linear Non Negative Regression:'
lin_reg = LinearNonNegRegression()
lin_reg.train(trainSet_X, trainSet_Y)
testY = lin_reg.apply(testSet_X)
print "training time: ", lin_reg.time
print "W:", lin_reg.W
(mae,mse,cc,score,CM,mi,hx,hy,kappa) = lin_reg.analyse(testSet_X, testSet_Y)
print lin_reg.analyse(testSet_X, testSet_Y)
print 'Linear Non Negative Regression (neg Bias):'
lin_reg = LinearNonNegRegression(addNegBias=True)
lin_reg.train(trainSet_X, trainSet_Y)
testY = lin_reg.apply(testSet_X)
print "training time: ", lin_reg.time
print "W:", lin_reg.W
(mae,mse,cc,score,CM,mi,hx,hy,kappa) = lin_reg.analyse(testSet_X, testSet_Y)
print lin_reg.analyse(testSet_X, testSet_Y)
print '\nlearning with zero value dimensions:'
lin_reg0 = LinearNonNegRegression(addNegBias=True)
lin_reg0.train(trainSet_X0, trainSet_Y)
testY0 = lin_reg0.apply(testSet_X0)
print "training time: ", lin_reg0.time
print "W:", lin_reg0.W
(mae,mse,cc,score,CM,mi,hx,hy,kappa) = lin_reg0.analyse(testSet_X0, testSet_Y)
print lin_reg0.analyse(testSet_X0, testSet_Y)