[mlpack] 48/58: intercept no longer penalized and can be turned off, observation weighs supported
Barak A. Pearlmutter
barak+git at cs.nuim.ie
Tue Sep 9 13:19:42 UTC 2014
This is an automated email from the git hooks/post-receive script.
bap pushed a commit to branch svn-trunk
in repository mlpack.
commit 1f56b82114a284f79bdaff83e56a0672dd5e133a
Author: michaelfox99 <michaelfox99 at 9d5b8971-822b-0410-80eb-d18c1038ef23>
Date: Sat Aug 23 21:43:16 2014 +0000
intercept no longer penalized and can be turned off, observation weighs supported
git-svn-id: http://svn.cc.gatech.edu/fastlab/mlpack/trunk@17105 9d5b8971-822b-0410-80eb-d18c1038ef23
---
.../linear_regression/linear_regression.cpp | 114 +++++++++++++--------
1 file changed, 70 insertions(+), 44 deletions(-)
diff --git a/src/mlpack/methods/linear_regression/linear_regression.cpp b/src/mlpack/methods/linear_regression/linear_regression.cpp
index 78cac92..f8b050e 100644
--- a/src/mlpack/methods/linear_regression/linear_regression.cpp
+++ b/src/mlpack/methods/linear_regression/linear_regression.cpp
@@ -1,6 +1,7 @@
/**
* @file linear_regression.cpp
* @author James Cline
+ * @author Michael Fox
*
* Implementation of simple linear regression.
*/
@@ -8,11 +9,15 @@
using namespace mlpack;
using namespace mlpack::regression;
-
+
LinearRegression::LinearRegression(const arma::mat& predictors,
- const arma::colvec& responses,
- const double lambda) :
- lambda(lambda)
+ const arma::vec& responses,
+ const double lambda,
+ const bool intercept,
+ const arma::vec& weights
+ ) :
+ lambda(lambda),
+ intercept(intercept)
{
/*
* We want to calculate the a_i coefficients of:
@@ -25,25 +30,31 @@ LinearRegression::LinearRegression(const arma::mat& predictors,
// that is, columns are actually rows (see: column major order).
const size_t nCols = predictors.n_cols;
- // Here we add the row of ones to the predictors.
- arma::mat p;
- if (lambda == 0.0)
- {
- p.set_size(predictors.n_rows + 1, nCols);
- p.submat(1, 0, p.n_rows - 1, nCols - 1) = predictors;
- p.row(0).fill(1);
- }
- else
+ arma::mat p = predictors;
+ arma::vec r = responses;
+ // Here we add the row of ones to the predictors.
+ // The intercept is not penalized. Add an "all ones" row to design and set
+ // intercept = false to get a penalized intercept
+ if(intercept)
+ {
+ p.insert_rows(0, arma::ones<arma::mat>(1,nCols));
+ }
+
+ if(weights.n_elem > 0)
+ {
+ p = p * diagmat(sqrt(weights));
+ r = sqrt(weights) % responses;
+ }
+
+ if (lambda != 0.0)
{
// Add the identity matrix to the predictors (this is equivalent to ridge
// regression). See http://math.stackexchange.com/questions/299481/ for
// more information.
- p.set_size(predictors.n_rows + 1, nCols + predictors.n_rows + 1);
- p.submat(1, 0, p.n_rows - 1, nCols - 1) = predictors;
- p.row(0).subvec(0, nCols - 1).fill(1);
- p.submat(0, nCols, p.n_rows - 1, nCols + predictors.n_rows) =
- lambda * arma::eye<arma::mat>(predictors.n_rows + 1,
- predictors.n_rows + 1);
+ p.insert_cols(nCols, predictors.n_rows);
+ p.submat(p.n_rows - predictors.n_rows, nCols, p.n_rows - 1, nCols +
+ predictors.n_rows - 1) = sqrt(lambda) * arma::eye<arma::mat>(predictors.n_rows,
+ predictors.n_rows);
}
// We compute the QR decomposition of the predictors.
@@ -57,15 +68,12 @@ LinearRegression::LinearRegression(const arma::mat& predictors,
// If lambda > 0, then we must add a bunch of empty responses.
if (lambda == 0.0)
{
- arma::solve(parameters, R, arma::trans(Q) * responses);
+ arma::solve(parameters, R, arma::trans(Q) * r);
}
else
{
// Copy responses into larger vector.
- arma::vec r(nCols + predictors.n_rows + 1);
- r.subvec(0, nCols - 1) = responses;
- r.subvec(nCols, nCols + predictors.n_rows).fill(0);
-
+ r.insert_rows(nCols,p.n_cols - nCols);
arma::solve(parameters, R, arma::trans(Q) * r);
}
}
@@ -84,15 +92,22 @@ LinearRegression::LinearRegression(const LinearRegression& linearRegression) :
void LinearRegression::Predict(const arma::mat& points, arma::vec& predictions)
const
{
- // We want to be sure we have the correct number of dimensions in the dataset.
- Log::Assert(points.n_rows == parameters.n_rows - 1);
-
- // Get the predictions, but this ignores the intercept value (parameters[0]).
- predictions = arma::trans(arma::trans(
- parameters.subvec(1, parameters.n_elem - 1)) * points);
-
- // Now add the intercept.
- predictions += parameters(0);
+ if (intercept)
+ {
+ // We want to be sure we have the correct number of dimensions in the dataset.
+ Log::Assert(points.n_rows == parameters.n_rows-1);
+ // Get the predictions, but this ignores the intercept value (parameters[0]).
+ predictions = arma::trans(arma::trans(parameters.subvec(1, parameters.n_elem - 1)) * points);
+ // Now add the intercept.
+ predictions += parameters(0);
+ }
+ else
+ {
+ // We want to be sure we have the correct number of dimensions in the dataset.
+ Log::Assert(points.n_rows == parameters.n_rows);
+ predictions = arma::trans(arma::trans(parameters) * points);
+ }
+
}
//! Compute the L2 squared error on the given predictors and responses.
@@ -103,19 +118,30 @@ double LinearRegression::ComputeError(const arma::mat& predictors,
const size_t nCols = predictors.n_cols;
const size_t nRows = predictors.n_rows;
- // Ensure that we have the correct number of dimensions in the dataset.
- if (nRows != parameters.n_rows - 1)
- {
- Log::Fatal << "The test data must have the same number of columns as the "
- "training file." << std::endl;
- }
-
// Calculate the differences between actual responses and predicted responses.
// We must also add the intercept (parameters(0)) to the predictions.
- arma::vec temp = responses - arma::trans(
- (arma::trans(parameters.subvec(1, parameters.n_elem - 1)) * predictors) +
- parameters(0));
-
+ arma::vec temp;
+ if (intercept)
+ {
+ // Ensure that we have the correct number of dimensions in the dataset.
+ if (nRows != parameters.n_rows - 1)
+ {
+ Log::Fatal << "The test data must have the same number of columns as the "
+ "training file." << std::endl;
+ }
+ temp = responses - arma::trans( (arma::trans(parameters.subvec(1,
+ parameters.n_elem - 1)) * predictors) + parameters(0));
+ }
+ else
+ {
+ // Ensure that we have the correct number of dimensions in the dataset.
+ if (nRows != parameters.n_rows)
+ {
+ Log::Fatal << "The test data must have the same number of columns as the "
+ "training file." << std::endl;
+ }
+ temp = responses - arma::trans((arma::trans(parameters) * predictors));
+ }
const double cost = arma::dot(temp, temp) / nCols;
return cost;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mlpack.git
More information about the debian-science-commits
mailing list