[mlpack-svn] r12980 - mlpack/trunk/src/mlpack/methods/lars
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Sat Jun 9 12:13:10 EDT 2012
Author: rcurtin
Date: 2012-06-09 12:13:09 -0400 (Sat, 09 Jun 2012)
New Revision: 12980
Modified:
mlpack/trunk/src/mlpack/methods/lars/lars.cpp
mlpack/trunk/src/mlpack/methods/lars/lars.hpp
mlpack/trunk/src/mlpack/methods/lars/lars_main.cpp
Log:
Modify LARS API to accept non-transposed matrices. This is easier on the
user...
Modified: mlpack/trunk/src/mlpack/methods/lars/lars.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/lars/lars.cpp 2012-06-09 05:19:30 UTC (rev 12979)
+++ mlpack/trunk/src/mlpack/methods/lars/lars.cpp 2012-06-09 16:13:09 UTC (rev 12980)
@@ -36,33 +36,51 @@
tolerance(tolerance)
{ /* Nothing left to do */ }
-void LARS::DoLARS(const arma::mat& matX, const arma::vec& y)
+void LARS::DoLARS(const arma::mat& matX,
+ const arma::vec& y,
+ const bool rowMajor)
{
+ // This matrix may end up holding the transpose -- if necessary.
+ arma::mat dataTrans;
+ // dataRef is row-major.
+ const arma::mat& dataRef = (rowMajor ? matX : dataTrans);
+ if (!rowMajor)
+ dataTrans = trans(matX);
+
// Compute X' * y.
- arma::vec vecXTy = trans(matX) * y;
+ arma::vec vecXTy = trans(dataRef) * y;
- // Set up active set variables.
+ // Set up active set variables. In the beginning, the active set has size 0
+ // (all dimensions are inactive).
nActive = 0;
activeSet = std::vector<arma::uword>(0);
- isActive = std::vector<bool>(matX.n_cols);
+ isActive = std::vector<bool>(dataRef.n_cols);
fill(isActive.begin(), isActive.end(), false);
// Initialize yHat and beta.
- arma::vec beta = arma::zeros(matX.n_cols);
- arma::vec yHat = arma::zeros(matX.n_rows);
- arma::vec yHatDirection = arma::vec(matX.n_rows);
+ arma::vec beta = arma::zeros(dataRef.n_cols);
+ arma::vec yHat = arma::zeros(dataRef.n_rows);
+ arma::vec yHatDirection = arma::vec(dataRef.n_rows);
bool lassocond = false;
+ // Compute the initial maximum correlation among all dimensions.
arma::vec corr = vecXTy;
- arma::vec absCorr = abs(corr);
- arma::uword changeInd;
- double maxCorr = absCorr.max(changeInd); // change_ind gets set here
+ double maxCorr = 0;
+ size_t changeInd = 0;
+ for (size_t i = 0; i < vecXTy.n_elem; ++i)
+ {
+ if (fabs(corr(i)) > maxCorr)
+ {
+ maxCorr = fabs(corr(i));
+ changeInd = i;
+ }
+ }
betaPath.push_back(beta);
lambdaPath.push_back(maxCorr);
- // don't even start!
+ // If the maximum correlation is too small, there is no reason to continue.
if (maxCorr < lambda1)
{
lambdaPath[0] = lambda1;
@@ -74,27 +92,23 @@
if (matGram.n_elem == 0)
{
// In this case, matGram should reference matGramInternal.
- matGramInternal = trans(matX) * matX;
+ matGramInternal = trans(dataRef) * dataRef;
if (elasticNet && !useCholesky)
- matGramInternal += lambda2 * arma::eye(matX.n_cols, matX.n_cols);
+ matGramInternal += lambda2 * arma::eye(dataRef.n_cols, dataRef.n_cols);
}
// Main loop.
- while ((nActive < matX.n_cols) && (maxCorr > tolerance))
+ while ((nActive < dataRef.n_cols) && (maxCorr > tolerance))
{
- // explicit computation of max correlation, among inactive indices
- changeInd = -1;
+ // Compute the maximum correlation among inactive dimensions.
maxCorr = 0;
- for (arma::uword i = 0; i < matX.n_cols; i++)
+ for (size_t i = 0; i < dataRef.n_cols; i++)
{
- if (!isActive[i])
+ if ((!isActive[i]) && (fabs(corr(i)) > maxCorr))
{
- if (fabs(corr(i)) > maxCorr)
- {
- maxCorr = fabs(corr(i));
- changeInd = i;
- }
+ maxCorr = fabs(corr(i));
+ changeInd = i;
}
}
@@ -110,7 +124,7 @@
// newGramCol[i] = dot(matX.col(activeSet[i]), matX.col(changeInd));
// }
// This is equivalent to the above 5 lines.
- arma::vec newGramCol = matGram.elem(changeInd * matX.n_cols +
+ arma::vec newGramCol = matGram.elem(changeInd * dataRef.n_cols +
arma::conv_to<arma::uvec>::from(activeSet));
//CholeskyInsert(matX.col(changeInd), newGramCol);
@@ -166,20 +180,20 @@
}
// compute "equiangular" direction in output space
- ComputeYHatDirection(matX, betaDirection, yHatDirection);
+ ComputeYHatDirection(dataRef, betaDirection, yHatDirection);
double gamma = maxCorr / normalization;
// if not all variables are active
- if (nActive < matX.n_cols)
+ if (nActive < dataRef.n_cols)
{
// compute correlations with direction
- for (arma::uword ind = 0; ind < matX.n_cols; ind++)
+ for (arma::uword ind = 0; ind < dataRef.n_cols; ind++)
{
if (isActive[ind])
continue;
- double dirCorr = dot(matX.col(ind), yHatDirection);
+ double dirCorr = dot(dataRef.col(ind), yHatDirection);
double val1 = (maxCorr - corr(ind)) / (normalization - dirCorr);
double val2 = (maxCorr + corr(ind)) / (normalization + dirCorr);
if ((val1 > 0) && (val1 < gamma))
@@ -251,7 +265,7 @@
Deactivate(changeInd);
}
- corr = vecXTy - trans(matX) * yHat;
+ corr = vecXTy - trans(dataRef) * yHat;
if (elasticNet)
corr -= lambda2 * beta;
@@ -259,7 +273,7 @@
for (arma::uword i = 0; i < nActive; i++)
curLambda += fabs(corr(activeSet[i]));
- curLambda /= ((double)nActive);
+ curLambda /= ((double) nActive);
lambdaPath.push_back(curLambda);
Modified: mlpack/trunk/src/mlpack/methods/lars/lars.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/lars/lars.hpp 2012-06-09 05:19:30 UTC (rev 12979)
+++ mlpack/trunk/src/mlpack/methods/lars/lars.hpp 2012-06-09 16:13:09 UTC (rev 12980)
@@ -117,13 +117,21 @@
const double tolerance = 1e-16);
/**
- * Run LARS.
+ * Run LARS. The input matrix (like all MLPACK matrices) should be
+ * column-major -- each column is an observation and each row is a dimension.
+ * However, because LARS is more efficient on a row-major matrix, this method
+ * will (internally) transpose the matrix. If this transposition is not
+ * necessary (i.e., you want to pass in a row-major matrix), pass 'true' for
+ * the rowmajor parameter.
*
- * @param matX Input data into the algorithm - a matrix where each row is a
- * point and each column is a dimension
- * @param y A vector of targets
+ * @param matX Column-major input data (or row-major input data if rowMajor =
+ * true).
+ * @param y A vector of targets.
+ * @param rowMajor Set to true if matX is row-major.
*/
- void DoLARS(const arma::mat& matX, const arma::vec& y);
+ void DoLARS(const arma::mat& matX,
+ const arma::vec& y,
+ const bool rowMajor = false);
/*
* Load the solution vector, which is the last vector from the solution path
Modified: mlpack/trunk/src/mlpack/methods/lars/lars_main.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/lars/lars_main.cpp 2012-06-09 05:19:30 UTC (rev 12979)
+++ mlpack/trunk/src/mlpack/methods/lars/lars_main.cpp 2012-06-09 16:13:09 UTC (rev 12980)
@@ -77,7 +77,7 @@
// Do LARS.
LARS lars(useCholesky, lambda1, lambda2);
- lars.DoLARS(trans(matX), matY.unsafe_col(0));
+ lars.DoLARS(matX, matY.unsafe_col(0));
// Get and save solution.
vec beta;
More information about the mlpack-svn
mailing list