[go: up one dir, main page]

File: logitFunction.cpp

package info (click to toggle)
seer 1.1.2-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,616 kB
  • ctags: 342
  • sloc: cpp: 2,853; perl: 503; python: 122; makefile: 85
file content (76 lines) | stat: -rw-r--r-- 2,826 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * File: logitFunction.cpp
 *
 * Likelihood, gradient and initialisation of logit function
 * Functor, based on mlpack: www.mlpack.org
 */

#include "linkFunction.hpp"

/**
 * Evaluate the logistic regression objective function given the estimated
 * parameters.
 */
double LogitLikelihood::operator()(const column_vector& parameters_in)
   const
{
   // Convert from dlib column matrix to armadillo column matrix
   arma::vec parameters = dlib_to_arma(parameters_in);

   // The objective function is the log-likelihood function (w is the parameters
   // vector for the model; y is the responses; x is the predictors; sig() is the
   // sigmoid function):
   //   f(w) = sum(y log(sig(w'x)) + (1 - y) log(sig(1 - w'x))).
   // We want to minimize this function.  L2-regularization is just lambda
   // multiplied by the squared l2-norm of the parameters then divided by two.

   // For the regularization, we ignore the first term, which is the intercept
   // term.
   const double regularization = 0.5 * lambda *
       arma::dot(parameters.col(0).subvec(1, parameters.n_elem - 1),
                 parameters.col(0).subvec(1, parameters.n_elem - 1));

   // Calculate vectors of sigmoids.  The intercept term is parameters(0, 0) and
   // does not need to be multiplied by any of the predictors.
   const arma::vec exponents = parameters(0) + predictors *
       parameters.col(0).subvec(1, parameters.n_elem - 1);
   const arma::vec sigmoid = 1.0 / (1.0 + arma::exp(-exponents));

   // Assemble full objective function.  Often the objective function and the
   // regularization as given are divided by the number of features, but this
   // doesn't actually affect the optimization result, so we'll just ignore those
   // terms for computational efficiency.
   double result = 0.0;
   for (size_t i = 0; i < responses.n_elem; ++i)
   {
     if (responses[i] == 1)
       result += log(sigmoid[i]);
     else
       result += log(1.0 - sigmoid[i]);
   }

   return result - regularization;
}

// Evaluate the gradient of the logistic regression objective function.
column_vector LogitLikelihoodGradient::operator()(const column_vector& parameters_in)
   const
{
   // Convert from dlib column matrix to armadillo column matrix
   arma::vec parameters = dlib_to_arma(parameters_in);
   arma::vec gradient(parameters.n_elem);

   // Regularization term.
   arma::mat regularization;
   regularization = lambda * parameters.col(0).subvec(1, parameters.n_elem - 1);

   const arma::vec sigmoids = 1 / (1 + arma::exp(-parameters(0, 0)
       - predictors * parameters.col(0).subvec(1, parameters.n_elem - 1)));

   gradient[0] = arma::accu(responses - sigmoids);
   gradient.col(0).subvec(1, parameters.n_elem - 1) = predictors.t() * (responses -
       sigmoids) - regularization;

   return arma_to_dlib(gradient);
}