All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.sandia.cognition.learning.data.feature.LinearRegressionCoefficientExtractor Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
/*
 * File:                LinearRegressionBuffer.java
 * Authors:             Justin Basilico
 * Company:             Sandia National Laboratories
 * Project:             Cognitive Foundry
 *
 * Copyright March 23, 2006, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 */

package gov.sandia.cognition.learning.data.feature;

import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.evaluator.AbstractStatefulEvaluator;
import gov.sandia.cognition.collection.FiniteCapacityBuffer;
import gov.sandia.cognition.math.RingAccumulator;

/**
 * Takes a sampled sequence of equal-dimension vectors as input and computes 
 * the linear regression coefficients for each dimension in the vectors. In
 * other words, it compute the best-fit equation:
 * 
* y_i = m*x_i + b, *
* where "m" and "b" are the slope and offset for that dimension in the buffer. * For each "i" vector dimension in the regression buffer. Thus, if one puts * vectors of dimension "n" into the buffer, at each timestep, one will get * one vector of slopes (m) and one vector of offsets (b), each of dimension n. * The output of the evaluate() method is a Matrix with first column of slopes, * and the next column of offsets. * * @author Justin Basilico * @since 1.0 */ @CodeReview( reviewer="Kevin R. Dixon", date="2006-07-17", changesNeeded=false, comments={ "Encapsulated members, added a comment to virtually every method and member.", "Added comment about the regression equation.", "No additional changes needed." } ) public class LinearRegressionCoefficientExtractor extends AbstractStatefulEvaluator> { /** * Default maximum buffer size, {@value}. */ public static final int DEFAULT_MAX_BUFFER_SIZE = 20; /** * maximum number of vectors to hold in the buffer */ private int maxBufferSize; /** * Default constructor. */ public LinearRegressionCoefficientExtractor() { this( DEFAULT_MAX_BUFFER_SIZE ); } /** * Creates new instance of LinearRegressionEvaluator * * @param maxBufferSize * maximum number of vectors to hold in the buffer */ public LinearRegressionCoefficientExtractor( int maxBufferSize ) { super(); this.setMaxBufferSize( maxBufferSize ); } @Override public LinearRegressionCoefficientExtractor clone() { LinearRegressionCoefficientExtractor clone = (LinearRegressionCoefficientExtractor) super.clone(); if( this.getState() != null ) { clone.setState( this.getState().clone() ); } return clone; } public FiniteCapacityBuffer createDefaultState() { return new FiniteCapacityBuffer( this.getMaxBufferSize() ); } public Vector evaluate( Vector input ) { int M = input.getDimensionality(); this.getState().addLast( input ); // This is the mean of the arithmetic series from 0..(num-1): // 1->0; // 2->0.5; // 3->1; // 4->0+1+2+3->1.5; // 5->0+1+2+3+4->2; // Thus, meanx == (num-1) / 2.0; int num = this.getState().size(); Vector ms; Vector bs; RingAccumulator sumy = new RingAccumulator( this.getState() ); Vector meany = sumy.getMean(); if( num > 1 ) { double meanx = -(num - 1) / 2.0; double sxx = 0.0; RingAccumulator sumxy = new RingAccumulator(); int x = -num + 1; for (Vector y : this.getState()) { double dx = x - meanx; sxx += dx * dx; sumxy.accumulate( y.minus( meany ).scale( dx ) ); x++; } ms = sumxy.scaleSum( 1.0/sxx ); bs = meany.minus( ms.scale(meanx) ); } else { ms = VectorFactory.getDefault().createVector(M); bs = meany; } return bs.stack(ms); } /** * Getter for maxBufferSize * @return * Maximum Buffer size */ public int getMaxBufferSize() { return this.maxBufferSize; } /** * Setter for maxBufferSize * @param maxBufferSize * Maximum buffer size, must be >= 2 */ public void setMaxBufferSize( int maxBufferSize ) { if (maxBufferSize < 2) { throw new IllegalArgumentException( "Must have at least 2 samples to fit two polynomials!!" ); } this.maxBufferSize = maxBufferSize; this.setState(null); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy