Author: luc
Date: Wed May 21 05:13:27 2008
New Revision: 658645
URL: http://svn.apache.org/viewvc?rev=658645&view=rev
Log:
added error handling for multiple linear-regression
added documentation for multiple linear-regression
JIRA: MATH-203
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegression.java
Wed May 21 05:13:27 2008
@@ -38,7 +38,7 @@
*
* @param y the [n,1] array representing the y sample
*/
- protected void addYSampleData(double[] y){
+ protected void addYSampleData(double[] y) {
this.Y = new RealMatrixImpl(y);
}
@@ -47,22 +47,64 @@
*
* @param x the [n,k] array representing the x sample
*/
- protected void addXSampleData(double[][] x){
+ protected void addXSampleData(double[][] x) {
this.X = new RealMatrixImpl(x);
}
/**
+ * Validates sample data.
+ *
+ * @param x the [n,k] array representing the x sample
+ * @param y the [n,1] array representing the y sample
+ * @throws IllegalArgumentException if the x and y array data are not
+ * compatible for the regression
+ */
+ protected void validateSampleData(double[][] x, double[] y) {
+ if (x == null) {
+ throw new IllegalArgumentException("The regressors matrix x cannot
be null.");
+ }
+ if (y == null) {
+ throw new IllegalArgumentException("The regressand vector y cannot
be null.");
+ }
+ if (x.length != y.length) {
+ throw new IllegalArgumentException(
+ "The regressors matrix x columns must have the same length
of the regressand vector y");
+ }
+ }
+
+ /**
+ * Validates sample data.
+ *
+ * @param x the [n,k] array representing the x sample
+ * @param covariance the [n,n] array representing the covariance matrix
+ * @throws IllegalArgumentException if the x sample data or covariance
+ * matrix are not compatible for the regression
+ */
+ protected void validateCovarianceData(double[][] x, double[][] covariance)
{
+ if (covariance == null) {
+ throw new IllegalArgumentException("Covariance matrix cannot be
null.");
+ }
+ if (x.length != covariance.length) {
+ throw new IllegalArgumentException(
+ "The regressors matrix x columns must have the same length
of the covariance matrix columns");
+ }
+ if (covariance.length > 0 && covariance.length !=
covariance[0].length) {
+ throw new IllegalArgumentException("The covariance matrix must be
square");
+ }
+ }
+
+ /**
* [EMAIL PROTECTED]
*/
- public double[] estimateRegressionParameters(){
+ public double[] estimateRegressionParameters() {
RealMatrix b = calculateBeta();
return b.getColumn(0);
- }
-
+ }
+
/**
* [EMAIL PROTECTED]
*/
- public double[] estimateResiduals(){
+ public double[] estimateResiduals() {
RealMatrix b = calculateBeta();
RealMatrix e = Y.subtract(X.multiply(b));
return e.getColumn(0);
@@ -81,36 +123,42 @@
public double estimateRegressandVariance() {
return calculateYVariance();
}
-
+
/**
* Calculates the beta of multiple linear regression in matrix notation.
+ *
* @return beta
*/
- protected abstract RealMatrix calculateBeta();
-
+ protected abstract RealMatrix calculateBeta();
+
/**
- * Calculates the beta variance of multiple linear regression in matrix
notation.
+ * Calculates the beta variance of multiple linear regression in matrix
+ * notation.
+ *
* @return beta variance
*/
protected abstract RealMatrix calculateBetaVariance();
-
+
/**
* Calculates the Y variance of multiple linear regression.
+ *
* @return Y variance
*/
protected abstract double calculateYVariance();
/**
- * Calculates the residuals of multiple linear regression in matrix
notation.
+ * Calculates the residuals of multiple linear regression in matrix
+ * notation.
+ *
* <pre>
- * u = y - X*b
+ * u = y - X * b
* </pre>
*
- * @return The residuals [n,1] matrix
+ * @return The residuals [n,1] matrix
*/
protected RealMatrix calculateResiduals() {
RealMatrix b = calculateBeta();
return Y.subtract(X.multiply(b));
}
-
+
}
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.java
Wed May 21 05:13:27 2008
@@ -48,8 +48,10 @@
* [EMAIL PROTECTED]
*/
public void addData(double[] y, double[][] x, double[][] covariance) {
+ validateSampleData(x, y);
addYSampleData(y);
addXSampleData(x);
+ validateCovarianceData(x, covariance);
addCovarianceData(covariance);
}
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/MultipleLinearRegression.java
Wed May 21 05:13:27 2008
@@ -37,8 +37,9 @@
*
* @param y the [n,1] array representing the y sample
* @param x the [n,k] array representing x sample
- * @param covariance the [n,n] array representing the covariance matrix or
<code>null</code> if not appropriate for the
+ * @param covariance the [n,n] array representing the covariance matrix or
<code>null</code> if not required for the
* specific implementation
+ * @throws IllegalArgumentException if required data arrays are
<code>null</code> or their dimensions are not appropriate
*/
void addData(double[] y, double[][] x, double[][] covariance);
@@ -62,7 +63,7 @@
* @return The [n,1] array representing the residuals
*/
double[] estimateResiduals();
-
+
/**
* Returns the variance of the regressand, ie Var(y).
*
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.java
Wed May 21 05:13:27 2008
@@ -44,6 +44,7 @@
* [EMAIL PROTECTED]
*/
public void addData(double[] y, double[][] x, double[][] covariance) {
+ validateSampleData(x, y);
addYSampleData(y);
addXSampleData(x);
}
Modified: commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml
(original)
+++ commons/proper/math/branches/MATH_2_0/src/site/xdoc/userguide/stat.xml Wed
May 21 05:13:27 2008
@@ -398,7 +398,101 @@
</dl>
</p>
</subsection>
- <subsection name="1.5 Statistical tests" href="tests">
+ <subsection name="1.5 Multiple linear regression" href="regression">
+ <p>
+ <a
href="../apidocs/org/apache/commons/math/stat/regression/MultipleLinearRegression.html">
+ org.apache.commons.math.stat.regression.MultipleLinearRegression</a>
+ provides ordinary least squares regression with a generic multiple
variable linear model, which
+ in matrix notation can be expressed as:
+ </p>
+ <p>
+ <code> y=X*b+u </code>
+ </p>
+ <p>
+ where y is an <code>n-vector</code> <b>regressand</b>, X is a
<code>[n,k]</code> matrix whose <code>k</code> columns are called
+ <b>regressors</b>, b is <code>k-vector</code> of <b>regression
parameters</b> and <code>u</code> is an <code>n-vector</code>
+ of <b>error terms</b> or <b>residuals</b>. The notation is quite
standard in literature,
+ cf eg <a href="http://www.econ.queensu.ca/ETM">Davidson and
MacKinnon, Econometrics Theory and Methods, 2004</a>.
+ </p>
+ <p>
+ Two implementations are provided: <a
href="../apidocs/org/apache/commons/math/stat/regression/OLSMultipleLinearRegression.html">
+
org.apache.commons.math.stat.regression.OLSMultipleLinearRegression</a> and
+ <a
href="../apidocs/org/apache/commons/math/stat/regression/GLSMultipleLinearRegression.html">
+
org.apache.commons.math.stat.regression.GLSMultipleLinearRegression</a>
+ </p>
+ <p>
+ Observations (x,y and covariance data matrices) can be added to the
model via the <code>addData(double[] y, double[][] x, double[][]
covariance)</code> method.
+ The observations are stored in memory until the next time the
addData method is invoked.
+ </p>
+ <p>
+ <strong>Usage Notes</strong>: <ul>
+ <li> Data is validated when invoking the <code>addData(double[] y,
double[][] x, double[][] covariance)</code> method and
+ <code>IllegalArgumentException</code> is thrown when inappropriate.
+ </li>
+ <li> Only the GLS regressions require the covariance matrix, so in
the OLS regression it is ignored and can be safely
+ inputted as <code>null</code>.</li>
+ </ul>
+ </p>
+ <p>
+ Here are some examples.
+ <dl>
+ <dt>OLS regression</dt>
+ <br></br>
+ <dd>Instantiate an OLS regression object and load dataset
+ <source>
+MultipleLinearRegression regression = new OLSMultipleLinearRegression();
+double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0};
+double[] x = new double[6][];
+x[0] = new double[]{1.0, 0, 0, 0, 0, 0};
+x[1] = new double[]{1.0, 2.0, 0, 0, 0, 0};
+x[2] = new double[]{1.0, 0, 3.0, 0, 0, 0};
+x[3] = new double[]{1.0, 0, 0, 4.0, 0, 0};
+x[4] = new double[]{1.0, 0, 0, 0, 5.0, 0};
+x[5] = new double[]{1.0, 0, 0, 0, 0, 6.0};
+regression.addData(y, x, null); // we don't need covariance
+ </source>
+ </dd>
+ <dd>Estimate of regression values honours the
<code>MultipleLinearRegression</code> interface:
+ <source>
+double[] beta = regression.estimateRegressionParameters();
+
+double[] residuals = regression.estimateResiduals();
+
+double[][] parametersVariance =
regression.estimateRegressionParametersVariance();
+
+double regressandVariance = regression.estimateRegressandVariance();
+ </source>
+ </dd>
+ <dt>GLS regression</dt>
+ <br></br>
+ <dd>Instantiate an GLS regression object and load dataset
+ <source>
+MultipleLinearRegression regression = new GLSMultipleLinearRegression();
+double[] y = new double[]{11.0, 12.0, 13.0, 14.0, 15.0, 16.0};
+double[] x = new double[6][];
+x[0] = new double[]{1.0, 0, 0, 0, 0, 0};
+x[1] = new double[]{1.0, 2.0, 0, 0, 0, 0};
+x[2] = new double[]{1.0, 0, 3.0, 0, 0, 0};
+x[3] = new double[]{1.0, 0, 0, 4.0, 0, 0};
+x[4] = new double[]{1.0, 0, 0, 0, 5.0, 0};
+x[5] = new double[]{1.0, 0, 0, 0, 0, 6.0};
+double[][] omega = new double[6][];
+omega[0] = new double[]{1.1, 0, 0, 0, 0, 0};
+omega[1] = new double[]{0, 2.2, 0, 0, 0, 0};
+omega[2] = new double[]{0, 0, 3.3, 0, 0, 0};
+omega[3] = new double[]{0, 0, 0, 4.4, 0, 0};
+omega[4] = new double[]{0, 0, 0, 0, 5.5, 0};
+omega[5] = new double[]{0, 0, 0, 0, 0, 6.6};
+regression.addData(y, x, omega); // we do need covariance
+ </source>
+ </dd>
+ <dd>Estimate of regression values honours the same
<code>MultipleLinearRegression</code> interface as
+ the OLS regression.
+ </dd>
+ </dl>
+ </p>
+ </subsection>
+ <subsection name="1.6 Statistical tests" href="tests">
<p>
The interfaces and implementations in the
<a href="../apidocs/org/apache/commons/math/stat/inference/">
Modified:
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/AbstractMultipleLinearRegressionTest.java
Wed May 21 05:13:27 2008
@@ -25,7 +25,7 @@
public abstract class AbstractMultipleLinearRegressionTest {
- private MultipleLinearRegression regression;
+ protected MultipleLinearRegression regression;
@Before
public void setUp(){
@@ -61,5 +61,23 @@
double variance = regression.estimateRegressandVariance();
assertTrue(variance > 0.0);
}
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddXSampleData() {
+ regression.addData(new double[]{}, null, null);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddNullYSampleData() {
+ regression.addData(null, new double[][]{}, null);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddSampleDataWithSizeMismatch() {
+ double[] y = new double[]{1.0, 2.0};
+ double[][] x = new double[1][];
+ x[0] = new double[]{1.0, 0};
+ regression.addData(y, x, null);
+ }
}
Modified:
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java?rev=658645&r1=658644&r2=658645&view=diff
==============================================================================
---
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
(original)
+++
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/stat/regression/GLSMultipleLinearRegressionTest.java
Wed May 21 05:13:27 2008
@@ -17,6 +17,7 @@
package org.apache.commons.math.stat.regression;
import org.junit.Before;
+import org.junit.Test;
public class GLSMultipleLinearRegressionTest extends
AbstractMultipleLinearRegressionTest {
@@ -44,6 +45,36 @@
super.setUp();
}
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddNullCovarianceData() {
+ regression.addData(new double[]{}, new double[][]{}, null);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddCovarianceDataWithSampleSizeMismatch() {
+ double[] y = new double[]{1.0, 2.0};
+ double[][] x = new double[2][];
+ x[0] = new double[]{1.0, 0};
+ x[1] = new double[]{0, 1.0};
+ double[][] omega = new double[1][];
+ omega[0] = new double[]{1.0, 0};
+ regression.addData(y, x, omega);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void cannotAddCovarianceDataThatIsNotSquare() {
+ double[] y = new double[]{1.0, 2.0};
+ double[][] x = new double[2][];
+ x[0] = new double[]{1.0, 0};
+ x[1] = new double[]{0, 1.0};
+ double[][] omega = new double[3][];
+ omega[0] = new double[]{1.0, 0};
+ omega[1] = new double[]{0, 1.0};
+ omega[2] = new double[]{0, 2.0};
+ regression.addData(y, x, omega);
+ }
+
protected MultipleLinearRegression createRegression() {
MultipleLinearRegression regression = new
GLSMultipleLinearRegression();
regression.addData(y, x, omega);
@@ -57,5 +88,5 @@
protected int getSampleSize() {
return y.length;
}
-
+
}