[mlpack-svn] r16053 - mlpack/trunk/src/mlpack/methods/logistic_regression
fastlab-svn at coffeetalk-1.cc.gatech.edu
fastlab-svn at coffeetalk-1.cc.gatech.edu
Thu Nov 21 10:40:40 EST 2013
Author: rcurtin
Date: Thu Nov 21 10:40:40 2013
New Revision: 16053
Log:
Refactor LogisticRegression class. LearnModel() can be private, and we can
const-ize a lot of the parameters and functions. Also restore functionality to
Predict(), ComputeError(), and ComputeAccuracy(). This does not ever make a
copy of the predictors matrix and doesn't add a column for the intercept, which
is faster.
Modified:
mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression.hpp
mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression_impl.hpp
Modified: mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression.hpp (original)
+++ mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression.hpp Thu Nov 21 10:40:40 2013
@@ -62,18 +62,49 @@
//! Modify the lambda value for L2-regularization.
double& Lambda() { return errorFunction().Lambda(); }
- double LearnModel();
-
- //predict functions
- void Predict(arma::mat& predictors,
+ /**
+ * Predict the responses to a given set of predictors. The responses will be
+ * either 0 or 1. Optionally, specify the decision boundary; logistic
+ * regression returns a value between 0 and 1. If the value is greater than
+ * the decision boundary, the response is taken to be 1; otherwise, it is 0.
+ * By default the decision boundary is 0.5.
+ *
+ * @param predictors Input predictors.
+ * @param responses Vector to put output predictions of responses into.
+ * @param decisionBoundary Decision boundary (default 0.5).
+ */
+ void Predict(const arma::mat& predictors,
arma::vec& responses,
- const double decisionBoundary = 0.5);
+ const double decisionBoundary = 0.5) const;
- double ComputeAccuracy(arma::mat& predictors,
+ /**
+ * Compute the accuracy of the model on the given predictors and responses,
+ * optionally using the given decision boundary. The responses should be
+ * either 0 or 1. Logistic regression returns a value between 0 and 1. If
+ * the value is greater than the decision boundary, the response is taken to
+ * be 1; otherwise, it is 0. By default, the decision boundary is 0.5.
+ *
+ * The accuracy is returned as a percentage, between 0 and 100.
+ *
+ * @param predictors Input predictors.
+ * @param responses Vector of responses.
+ * @param decisionBoundary Decision boundary (default 0.5).
+ * @return Percentage of responses that are predicted correctly.
+ */
+ double ComputeAccuracy(const arma::mat& predictors,
const arma::vec& responses,
- const double decisionBoundary = 0.5);
+ const double decisionBoundary = 0.5) const;
- double ComputeError(arma::mat& predictors, const arma::vec& responses);
+ /**
+ * Compute the error of the model. This returns the negative objective
+ * function of the logistic regression log-likelihood function. For the model
+ * to be optimal, the negative log-likelihood function should be minimized.
+ *
+ * @param predictors Input predictors.
+ * @param responses Vector of responses.
+ */
+ double ComputeError(const arma::mat& predictors,
+ const arma::vec& responses) const;
private:
//! Matrix of predictor points (X).
@@ -87,6 +118,12 @@
LogisticRegressionFunction errorFunction;
//! Instantiated optimizer.
OptimizerType<LogisticRegressionFunction> optimizer;
+
+ /**
+ * Learn the model by optimizing the logistic regression objective function.
+ * Returns the objective function evaluated when the parameters are optimized.
+ */
+ double LearnModel();
};
}; // namespace regression
Modified: mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression_impl.hpp
==============================================================================
--- mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression_impl.hpp (original)
+++ mlpack/trunk/src/mlpack/methods/logistic_regression/logistic_regression_impl.hpp Thu Nov 21 10:40:40 2013
@@ -21,10 +21,12 @@
const double lambda) :
predictors(predictors),
responses(responses),
+ parameters(arma::zeros<arma::vec>(predictors.n_rows + 1)),
errorFunction(LogisticRegressionFunction(predictors, responses, lambda)),
optimizer(OptimizerType<LogisticRegressionFunction>(errorFunction))
{
- parameters.zeros(predictors.n_rows + 1);
+ // Train the model.
+ LearnModel();
}
template<template<typename> class OptimizerType>
@@ -35,74 +37,66 @@
const double lambda) :
predictors(predictors),
responses(responses),
+ parameters(arma::zeros<arma::vec>(predictors.n_rows + 1)),
errorFunction(LogisticRegressionFunction(predictors, responses)),
optimizer(OptimizerType<LogisticRegressionFunction>(errorFunction))
{
- parameters.zeros(predictors.n_rows + 1);
+ // Train the model.
+ LearnModel();
}
template <template<typename> class OptimizerType>
-double LogisticRegression<OptimizerType>::LearnModel()
-{
- Timer::Start("logistic_regression_optimization");
- const double out = optimizer.Optimize(parameters);
- Timer::Stop("logistic_regression_optimization");
-
- return out;
+void LogisticRegression<OptimizerType>::Predict(const arma::mat& predictors,
+ arma::vec& responses,
+ const double decisionBoundary)
+ const
+{
+ // Calculate sigmoid function for each point. The (1.0 - decisionBoundary)
+ // term correctly sets an offset so that floor() returns 0 or 1 correctly.
+ responses = arma::floor((1.0 / (1.0 + arma::exp(-parameters(0)
+ - predictors.t() * parameters.subvec(1, parameters.n_elem - 1))))
+ + (1.0 - decisionBoundary));
}
template <template<typename> class OptimizerType>
double LogisticRegression<OptimizerType>::ComputeError(
- arma::mat& predictors,
- const arma::vec& responses)
+ const arma::mat& predictors,
+ const arma::vec& responses) const
{
- // Here we add the row of ones to the predictors.
- arma::rowvec ones;
- ones.ones(predictors.n_cols);
- predictors.insert_rows(0, ones);
-
-// double out = errorFunction.Evaluate(predictors, responses, parameters);
+ // Construct a new error function.
+ LogisticRegressionFunction newErrorFunction(predictors, responses,
+ errorFunction.Lambda());
- predictors.shed_row(0);
-
-// return out;
- return 0.0;
+ return newErrorFunction.Evaluate(parameters);
}
template <template<typename> class OptimizerType>
double LogisticRegression<OptimizerType>::ComputeAccuracy(
- arma::mat& predictors,
+ const arma::mat& predictors,
const arma::vec& responses,
- const double decisionBoundary)
+ const double decisionBoundary) const
{
+ // Predict responses using the current model.
arma::vec tempResponses;
Predict(predictors, tempResponses, decisionBoundary);
- int count = 0;
- for (size_t i = 0; i < responses.n_rows; i++)
- if (responses(i, 0) == tempResponses(i, 0))
+
+ // Count the number of responses that were correct.
+ size_t count = 0;
+ for (size_t i = 0; i < responses.n_elem; i++)
+ if (responses(i) == tempResponses(i))
count++;
return (double) (count * 100) / responses.n_rows;
}
template <template<typename> class OptimizerType>
-void LogisticRegression<OptimizerType>::Predict(
- arma::mat& predictors,
- arma::vec& responses,
- const double decisionBoundary)
-{
- //add rows of ones to predictors
- arma::rowvec ones;
- ones.ones(predictors.n_cols);
- predictors.insert_rows(0, ones);
-
-// responses = arma::floor(
-// errorFunction.getSigmoid(arma::trans(predictors) * parameters) -
-// decisionBoundary * arma::ones<arma::vec>(predictors.n_cols, 1)) +
-// arma::ones<arma::vec>(predictors.n_cols);
+double LogisticRegression<OptimizerType>::LearnModel()
+{
+ Timer::Start("logistic_regression_optimization");
+ const double out = optimizer.Optimize(parameters);
+ Timer::Stop("logistic_regression_optimization");
- //shed the added rows
- predictors.shed_row(0);
+ return out;
}
}; // namespace regression
More information about the mlpack-svn
mailing list