[mlpack-svn] r17105 - mlpack/trunk/src/mlpack/methods/linear_regression

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Sat Aug 23 17:43:17 EDT 2014


Author: michaelfox99
Date: Sat Aug 23 17:43:16 2014
New Revision: 17105

Log:
intercept no longer penalized and can be turned off, observation weighs supported


Modified:
   mlpack/trunk/src/mlpack/methods/linear_regression/linear_regression.cpp

Modified: mlpack/trunk/src/mlpack/methods/linear_regression/linear_regression.cpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/linear_regression/linear_regression.cpp	(original)
+++ mlpack/trunk/src/mlpack/methods/linear_regression/linear_regression.cpp	Sat Aug 23 17:43:16 2014
@@ -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 @@
   //           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 @@
   // 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 @@
 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 @@
   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;



More information about the mlpack-svn mailing list