[go: up one dir, main page]

File: logitFunction.cpp

package info (click to toggle)
seer 1.1.4-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,644 kB
  • sloc: cpp: 2,944; perl: 596; python: 122; makefile: 87
file content (77 lines) | stat: -rw-r--r-- 2,556 bytes parent folder | download | duplicates (5)
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
77
/*
 * 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. With thanks to mlpack http://mlpack.org/;
 * http://mlpack.org/papers/mlpack2013.pdf
 */
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.
   double regularization = 0;
   if (parameters.n_elem > 1 && lambda > 0)
   {
      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
   const arma::vec exponents = predictors * parameters;
   const arma::vec sigmoid = 1.0 / (1.0 + arma::exp(-exponents));

   // Assemble full objective function.
   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(parameters.n_elem,1,arma::fill::zeros);
   if (parameters.n_elem > 1 && lambda > 0)
   {
      regularization.col(0).subvec(1, parameters.n_elem - 1) =
         lambda * parameters.col(0).subvec(1, parameters.n_elem - 1);
   }

   const arma::vec sigmoids = 1 / (1 + arma::exp(- predictors * parameters));

   gradient = predictors.t() * (responses - sigmoids) - regularization;

   return arma_to_dlib(gradient);
}