def __init__(self, x, g, elastic=1.0, penalty=0.0, weightInitFunc=pinit.lecun, optimFunc=optim.scg, **kwargs): x = np.asarray(x) g = np.asarray(g) self.dtype = np.result_type(x.dtype, g.dtype) if g.ndim > 1: self.flattenOut = False else: self.flattenOut = True self.elastic = elastic self.penalty = penalty Regression.__init__(self, util.colmat(x).shape[1], util.colmat(g).shape[1]) optim.Optable.__init__(self) self.weights = weightInitFunc( (self.nIn + 1, self.nOut)).astype(self.dtype, copy=False) if optimFunc is not None: self.train(x, g, optimFunc, **kwargs)
def __init__(self, x, g, penalty=0.0, pseudoInv=True): Regression.__init__(self, util.colmat(x).shape[1], util.colmat(g).shape[1]) self.dtype = np.result_type(x.dtype, g.dtype) self.penalty = penalty self.pseudoInv = pseudoInv self.train(x, g)
def draw(self, freqs, powers, chanNames=None, colors = ('black', 'red', 'violet', 'blue', 'green', 'orange'), wxYield=False): if chanNames is None: chanNames = (None,) * powers.shape[0] colors = util.cycle(colors, powers.shape[1]) powers = util.colmat(powers) # cap so we don't break wxplt.PlotGraphics with inf # Note: we need to use finfo.max/10.0 since # wxplt.PlotGraphics does some log10 processing # before figuring tick marks finfo = np.finfo(powers.dtype) powers[powers < finfo.eps] = finfo.eps powers[powers > (finfo.max/10.0)] = (finfo.max/10.0) if wxYield: wx.Yield() lines = [wxplt.PolyLine(list(zip(freqs,p)), legend=chan, colour=col, width=2) for p,col,chan in zip(powers.T, colors, chanNames)] #lines += [wxplt.PolyLine(( (60.0,np.min(powers)), (60.0,np.max(powers)) ), legend='60Hz', colour='black', width=1)] if wxYield: wx.Yield() graphics = wxplt.PlotGraphics(lines, title=self.title, xLabel=self.xLabel, yLabel=self.yLabel) self.canvas.Draw(graphics, xAxis=(freqs[0], freqs[-1]), yAxis=(np.min(powers), np.max(powers)))
def __init__(self, classData, shrinkage=0): """Construct a new Linear Discriminant Analysis (LDA) classifier. Args: classData: Training data. This is a numpy array or list of numpy arrays with shape (nCls,nObs[,nIn]). If the dimensions index is missing the data is assumed to be one-dimensional. shrinkage: This parameter regularizes LDA by shrinking the average covariance matrix toward its average eigenvalue: covariance = (1-shrinkage)*covariance + shrinkage*averageEigenvalue*identity Behavior is undefined if shrinkage is outside [0,1]. This parameter has no effect if average is 0. Returns: A trained LDA classifier. """ Classifier.__init__(self, util.colmat(classData[0]).shape[1], len(classData)) self.dtype = np.result_type(*[cls.dtype for cls in classData]) self.shrinkage = shrinkage self.train(classData)
def __init__(self, classData, average=0.0, shrinkage=0.0): """Construct a new Quadratic Discriminant Analysis (QDA) classifier. Args: classData: Training data. This is a numpy array or list of numpy arrays with shape (nCls,nObs[,nIn]). If the dimensions index is missing the data is assumed to be one-dimensional. average: This parameter regularizes QDA by mixing the class covariance matrices with the average covariance matrix. A value of zero is pure QDA while a value of one reduces to LDA. shrinkage: This parameter regularizes QDA by shrinking each covariance matrix toward the average eigenvalue of the average covariance matrix. Returns: A trained QDA classifier. """ Classifier.__init__(self, util.colmat(classData[0]).shape[1], len(classData)) self.dtype = np.result_type(*[cls.dtype for cls in classData]) # average regularization parameter self.average = average # shrinkage regularization parameter self.shrinkage = shrinkage self.train(classData)
def discrim(self, x): """Compute discriminant values. Args: x: Input data. A numpy array with shape (nObs[,nIn]). Returns: Numpy array with shape (nObs,nCls) containing the discriminant values. Notes: These values are the log of the evaluated discriminant functions with terms cancelled on both sides. If you want probabilities, try the prob method instead. """ x = util.colmat(x) # number of observations nObs = x.shape[0] # (nObs,nCls) dv = np.zeros((nObs,self.nCls), dtype=self.dtype) # could probably vectorize this? XXX - idfah for i in range(self.nCls): zm = x - self.means[i] dv[:,i] = np.sum(zm.dot(self.invCovs[i]) * zm, axis=1) dv *= -0.5 dv += self.intercepts # (nObs,nCls) return dv
def __init__(self, s, sampRate=1.0, **kwargs): s = util.colmat(s) transform = CWT(sampRate=sampRate, **kwargs) freqs, powers, phases = transform.apply(s) SpectrogramBase.__init__(self, freqs, powers, phases, sampRate)
def train(self, x): x = util.colmat(x) nObs = x.shape[0] grid = np.meshgrid(range(self.latticeSize[0]), range(self.latticeSize[1])) grid = np.array(grid).T if self.callback is not None: self.callback(0, self.weights, self.learningRate, self.radius) for iteration in range(1, self.maxIter+1): curObs = x[np.random.randint(0, nObs)] curLearningRate = self.learningRate + self.learningRateDecay * iteration curRadius = self.radius + self.radiusDecay * iteration BMUIndex = self.getBMUIndices(curObs[None,...]) neighborHood = self.neighborFunc(grid, BMUIndex, curRadius) self.weights += curLearningRate * \ neighborHood[...,None] * (curObs[None,None,:] - self.weights) if self.verbose: print('%d %.3f %.3f' % (iteration, curLearningRate, curRadius)) if self.callback is not None: self.callback(iteration, self.weights, curLearningRate, curRadius)
def prep(self, s): s = self.lagize(util.colmat(s)) if self.demean: return s - self.means else: return s
def __init__(self, fileNames, dataKey='data', sampRate=('key','freq'), chanNames=('key','channels'), markers=('arg',None), start=('arg',0.0), transpose=False, deviceName=('arg',None), *args, **kwargs): firstMat = spio.loadmat(fileNames[0]) firstSeg = util.colmat(firstMat[dataKey]) if transpose: firstSeg = firstSeg.T firstShape = firstSeg.shape def keyOrArg(spec): koa = spec[0] val = spec[1] if koa == 'key': return firstMat[val] elif koa == 'arg': return val else: raise RuntimeError('Invalid spec %s.' % spec) sampRate = int(keyOrArg(sampRate)) chanNames = [str(chanName[0]) for chanName in keyOrArg(chanNames)[0][0]] markers = keyOrArg(markers) start = float(keyOrArg(start)) deviceName = str(keyOrArg(deviceName)) data = [] for fileName in fileNames: mat = spio.loadmat(fileName) seg = util.colmat(mat[dataKey]) if transpose: seg = seg.T if seg.shape != firstShape: raise RuntimeError('Shape of first segment %s %s does not not match shape of segment %s %s.' % (str(fileNames[0]), str(firstShape), str(fileName), str(seg.shape))) data.append(seg) data = np.asarray(data) SegmentedEEG.__init__(self, data=data, sampRate=sampRate, chanNames=chanNames, markers=markers, start=start, *args, **kwargs)
def beforeRun(self): self.t = np.arange(0.0, self.pollSize / float(self.sampRate), 1.0 / self.sampRate) self.t = util.colmat(self.t) self.shift = self.pollSize / float(self.sampRate) self.pollDelay = -1.0 self.lastPollTime = -1.0
def draw(self, data, time=None, scale=None, chanNames=None, colors=('black', 'red', 'violet', 'blue', 'green', 'orange'), #colors=('black', 'blue', 'green', 'red', 'turquoise', 'blue violet', 'maroon', 'orange'), wxYield=False): data = util.colmat(data) nObs, nChan = data.shape if time is None: time = np.arange(nObs) else: time = np.linspace(0, time, nObs) colsep = util.colsep(data, scale=scale) scale = colsep[1] yMin = scale * (-nChan + 0.5) yMax = scale * 0.5 data = data - colsep #time = time.repeat(data.shape[1]).reshape(data.shape) #comb = np.array((time,data)).swapaxes(1,2).swapaxes(0,1) if chanNames is None: chanNames = (None,) * nObs self.canvas.setChanNames(chanNames, scale) colors = util.cycle(colors, nChan) if wxYield: wx.Yield() # so many ways to slice this XXX - idfah #lines = [wxplt.PolyLine(pts.T, legend=chan, colour=col, width=2) # for pts,col,chan in zip(comb, colors, chanNames)] #lines = [wxplt.PolyLine(zip(time,d), legend=chan, colour=col, width=2) # for d,col,chan in zip(data.T, colors, chanNames)] #lines = [wxplt.PolyLine(np.vstack((time,d)).T, legend=chan, colour=col, width=2) # for d,col,chan in zip(data.T, colors, chanNames)] #t = _time.time() lines = [] for i in range(nChan): lines.append(wxplt.PolyLine(np.vstack((time,data[:,i])).T, legend=chanNames[i], colour=colors[i], width=2)) #print("time making lines: ", _time.time()-t) #t = _time.time() graphics = wxplt.PlotGraphics(lines, title=self.title, xLabel=self.xLabel, yLabel=self.yLabel) #print("time making PlotGraphics: ", _time.time()-t) if wxYield: wx.Yield() #t = _time.time() self.canvas.Draw(graphics, xAxis=(np.min(time),np.max(time)), yAxis=(yMin,yMax))
def vectorFromList(classData, combined=False): x = np.vstack([util.colmat(cls) for cls in classData]) vector = np.repeat(np.arange(len(classData), dtype=x.dtype), [np.asarray(cls).shape[0] for cls in classData]) if combined: return np.hstack((x, vector[:, None])) else: return x, vector
def __init__(self, x, g, nModels=10, obsFrac=0.5, replacement=True, dimFrac=None, regClass=RidgeRegression, *args, **kwargs): Regression.__init__(self, util.colmat(x).shape[1], util.colmat(g).shape[1]) self.nModels = nModels self.obsFrac = obsFrac self.replacement = replacement self.dimFrac = dimFrac self.train(x, g, regClass, *args, **kwargs)
def commonAverageReference(s, m1=False): s = util.colmat(s) if m1: nDim = s.shape[1] colSum = s.sum(axis=1) s -= np.hstack([(colSum-s[:,i])[:,None] for i in range(nDim)])/(nDim-1) return s else: s -= s.mean(axis=1)[:,None] return s
def movingAverage(s, width=2, kernelFunc=windows.boxcar, **kwargs): s = util.colmat(s) kernel = kernelFunc(width, **kwargs) kernel /= kernel.sum() kernel = kernel.astype(s.dtype, copy=False) return np.apply_along_axis(np.convolve, axis=0, arr=s, v=kernel, mode='same')
def __init__(self, s, lags=0, demean=True): s = util.colmat(s) self.dtype = s.dtype self.nDim = s.shape[1] self.lags = lags self.demean = demean self.means = self.lagize(s).mean(axis=0) self.nComp = len(self.means) self.w = np.eye(self.nComp, dtype=self.dtype) self.wInv = np.eye(self.nComp, dtype=self.dtype)
def gradient(self, x, g, returnError=True): x = np.asarray(x) g = np.asarray(g) if self.flattenOut: g = g.ravel() # packed views of the hidden and visible gradient matrices views = util.packedViews(self.layerDims, dtype=self.dtype) pg = views[0] hgs = views[1:-1] vg = views[-1] # forward pass z1 = util.bias(x) z1s = [z1] zPrimes = [] for hw, phi in zip(self.hws, self.transFunc): h = z1.dot(hw) z1 = util.bias(phi(h)) z1s.append(z1) zPrime = phi(h, 1) zPrimes.append(zPrime) y = z1.dot(self.vw) if self.flattenOut: y = y.ravel() # error components e = util.colmat(y - g) delta = np.sign(e) / e.size # visible layer gradient vg[...] = z1.T.dot(delta) vg += self.penaltyGradient(-1) # backward pass for hidden layers w = self.vw for l in range(self.nHLayers - 1, -1, -1): delta = delta.dot(w[:-1, :].T) * zPrimes[l] hgs[l][...] = z1s[l].T.dot(delta) hgs[l] += self.penaltyGradient(l) w = self.hws[l] if returnError: error = np.mean(np.abs(e)) + self.penaltyError() return error, pg else: return pg
def sharpen(s, radius=0.3, mix=1.0, dist=None): s = util.colmat(s) if dist is None: dist = np.arange(s.shape[1])+1.0 dist = np.abs(dist[None,:]-dist[:,None]) #dist = np.insert(spsig.triang(s.shape[1]-1, sym=False), 0, 0.0) #dist = np.vstack([np.roll(dist, i) for i in range(dist.size)]) kernel = util.gaussian(dist.T, radius=radius) kernel /= kernel.sum(axis=0) return (1.0-mix)*s + mix*(s - s.dot(kernel))
def probs(self, x): """Compute class probabilities. Args: x: Input data. A numpy array with shape (nObs[,nIn]). Returns: Numpy array with shape (nObs, nIn) containing the probability values. """ x = util.colmat(x) v = x.dot(self.weights[:-1]) + self.weights[-1] return util.softmax(v)
def upsample(s, factor): if s.ndim > 1: flattenOut = False else: flattenOut = True s = util.colmat(s) sup = s.repeat(factor).reshape((-1, s.shape[1]), order='F') if flattenOut: sup = sup.ravel() return sup
def meanSeparate(s, recover=False): s = util.colmat(s) if recover: mean = s[:,-1].copy() s[:,-1] = -s[:,:-1].sum(axis=1) return s + mean[:,None] else: mean = s.mean(axis=1) s -= mean[:,None] s[:,-1] = mean return s
def __init__(self, classData, k=1, distMetric='euclidean', **kwargs): Classifier.__init__(self, util.colmat(classData[0]).shape[1], len(classData)) self.k = k minObs = min([len(cls) for cls in classData]) if self.k > minObs: raise RuntimeError('k=%d exceeds the number of examples in ' + 'smallest training class %d.' % (k, minObs)) if callable(distMetric): self.distFunc = lambda x1, x2: distMetric(x1, x2, **kwargs) else: self.distFunc = lambda x1, x2: spdist.cdist(x1, x2, metric=distMetric) self.train(classData)
def indicatorsFromList(classData, conf=1.0, combined=False): x = np.vstack([util.colmat(cls) for cls in classData]) vector = np.repeat(np.arange(len(classData), dtype=x.dtype), [np.asarray(cls).shape[0] for cls in classData]) nCls = len(classData) labels = np.arange(nCls, dtype=x.dtype) indicators = np.ones((len(vector), nCls), dtype=x.dtype) indicators = ((indicators * vector[:, None]) == (indicators * labels)) offset = (1.0 - conf) / (nCls - 1) indicators = indicators * (conf - offset) + offset indicators = indicators.astype(x.dtype, copy=False) if combined: return np.hstack((x, indicators)) else: return x, indicators
def __init__(self, classData, nModels=10, obsFrac=0.5, replacement=True, dimFrac=None, clsClass=LogisticRegression, *args, **kwargs): Classifier.__init__(self, util.colmat(classData[0]).shape[1], len(classData)) self.nModels = nModels self.obsFrac = obsFrac self.replacement = replacement self.dimFrac = dimFrac self.train(classData, clsClass, *args, **kwargs)
def discrim(self, x): """Compute discriminant values. Args: x: Input data. A numpy array with shape (nObs[,nIn]). Returns: Numpy array with shape (nObs,nCls) containing the discriminant values. Notes: These values are the log of the evaluated discriminant functions with terms cancelled on both sides. If you want probabilities, try the prob method instead. """ x = util.colmat(x) # discriminant values # (nObs,nCls) = (nObs,ndim) x (ndim,nCls) + (nObs,nCls) dv = x.dot(self.weights) + self.intercepts.reshape((1,-1)) return dv
def __init__(self, classData, weightInitFunc=pinit.runif, optimFunc=optim.scg, **kwargs): """Create a new logistic regression classifier. Args: classData: Training data. This is a numpy array or list of numpy arrays with shape (nCls, nObs[,nIn]). If the dimensions index is missing the data is assumed to be one-dimensional. weightInitFunc: Function to initialize the model weights. The default function is the runif function in the paraminit module. See the paraminit module for more candidates. optimFunc: Function used to optimize the model weights. See ml.optim for some candidate optimization functions. kwargs: Additional arguments passed to optimFunc. Returns: A new, trained logistic regression classifier. """ Classifier.__init__(self, util.colmat(classData[0]).shape[1], len(classData)) optim.Optable.__init__(self) self.dtype = np.result_type(*[cls.dtype for cls in classData]) self.weights = weightInitFunc( (self.nIn + 1, self.nCls)).astype(self.dtype, copy=False) self.train(classData, optimFunc, **kwargs)
def gradient(self, x, g, returnError=True): x = np.asarray(x) g = np.asarray(g) if self.flattenOut: g = g.ravel() x1 = util.bias(x) y = x1 @ self.weights if self.flattenOut: y = y.ravel() e = util.colmat(y - g) delta = 2.0 * e / e.size penMask = np.ones_like(self.weights) penMask[-1, :] = 0.0 grad = (x1.T @ delta + self.elastic * 2.0 * self.penalty * penMask * self.weights / self.weights.size + (1.0 - self.elastic) * self.penalty * penMask * np.sign(self.weights) / self.weights.size) gf = grad.ravel() if returnError: wf = self.weights[:-1, :].ravel() error = ( np.mean(e**2) + self.elastic * self.penalty * (wf @ wf) / wf.size + # L2-norm penalty (1.0 - self.elastic) * self.penalty * np.mean(np.abs(wf)) ) # L1-norm penalty return error, gf else: return gf
def sharpenOld(s, kernelFunc, dist=None, scale=None, normalize=False, m1=False, **kwargs): s = util.colmat(s) if dist is None: dist = np.arange(s.shape[1])+1.0 dist = np.abs(dist[None,:]-dist[:,None]) #dist = np.insert(spsig.triang(s.shape[1]-1, sym=False), 0, 0.0) #dist = np.vstack([np.roll(dist, i) for i in range(dist.size)]) if scale is None: # minimum off-diagonal distance scale = np.min(dist[np.asarray(1.0-np.eye(dist.shape[0]), dtype=np.bool)]) kernel = kernelFunc(dist.T/scale, **kwargs) if m1: np.fill_diagonal(kernel, 0.0) if normalize: kernel = kernel/np.abs(kernel.sum(axis=0)) return s - s.dot(kernel)
def __init__(self, s, sampRate=1.0, span=0.1, overlap=0.5, windowFunc=windows.hanning, pad=False): s = util.colmat(s) nObs, nChan = s.shape wObs = int(span * sampRate) # check span parameter if wObs > nObs: raise RuntimeError('Span of %.2f exceedes length of input %.2f.' % (span, nObs / float(sampRate))) if wObs < 7: raise RuntimeError('Span of %.2f is too small.' % span) if pad: # find next largest power of two # padding to this improves FFT speed nPad = util.nextpow2(wObs) else: nPad = wObs # split into overlapping window wins = util.slidingWindow(s, span=wObs, stride=wObs - int(overlap * wObs)) if windowFunc is not None: # multiply by window function cWin = windowFunc(wObs).reshape(1, wObs, 1) wins = wins * cWin # scaling denominator scaleDenom = float(sampRate) * np.sum(np.abs(cWin))**2 else: scaleDenom = float(sampRate) * wObs**2 # discrete fourier transform dft = np.fft.fft(wins, nPad, axis=1) # first half of dft dft = dft[:, :int(np.ceil(nPad / 2.0)), :] # scale to power/Hz powers = 2.0 * (np.abs(dft)**2) / scaleDenom # phase angles phases = np.angle(dft) # find frequencies freqs = np.linspace(0, sampRate / 2.0, powers.shape[1]) # omit DC and nyquist components freqs = freqs[1:-1] powers = powers[:, 1:-1] phases = phases[:, 1:-1] SpectrogramBase.__init__(self, freqs, powers, phases, sampRate)