Darwin  1.10(beta)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
drwnLinearRegressor.h
Go to the documentation of this file.
1 /******************************************************************************
2 ** DARWIN: A FRAMEWORK FOR MACHINE LEARNING RESEARCH AND DEVELOPMENT
3 ** Distributed under the terms of the BSD license (see the LICENSE file)
4 ** Copyright (c) 2007-2015, Stephen Gould
5 ** All rights reserved.
6 **
7 ******************************************************************************
8 ** FILENAME: drwnLinearRegressor.h
9 ** AUTHOR(S): Stephen Gould <stephen.gould@anu.edu.au>
10 **
11 *****************************************************************************/
12 
13 #pragma once
14 
15 #include <cstdlib>
16 #include <vector>
17 
18 #include "drwnBase.h"
19 #include "drwnFeatureMaps.h"
20 #include "drwnRegression.h"
21 #include "drwnOptimizer.h"
22 
23 using namespace std;
24 
26 
27 // drwnLinearRegressorBase --------------------------------------------------
29 
31  public:
32  static double HUBER_BETA;
33  static double REG_STRENGTH;
34  static int MAX_ITERATIONS;
35 
36  protected:
37  VectorXd _theta;
38  int _penalty;
39  double _beta;
41  double _lambda;
42 
43  // cached data for parameter estimation
44  // \todo change to drwnDataset when ownership flag is implemented
45  const vector<vector<double> > *_features;
46  const vector<double> *_targets;
47  const vector<double> *_weights;
48 
49  public:
53  drwnLinearRegressorBase(unsigned n);
57 
58  // access functions
59  virtual const char *type() const { return "drwnLinearRegressor"; }
60 
61  // i/o
62  virtual bool save(drwnXMLNode& xml) const;
63  virtual bool load(drwnXMLNode& xml);
64 
65  // training
67  virtual double train(const drwnRegressionDataset& dataset);
68 
69  // evaluation (regression)
70  virtual double getRegression(const vector<double>& features) const = 0;
71 
72  protected:
73  // drwnOptimizer interface
74  double objective(const double *x) const;
75  void gradient(const double *x, double *df) const;
76  virtual double objectiveAndGradient(const double *x, double *df) const = 0;
77 };
78 
79 // drwnTLinearRegressor -----------------------------------------------------
106 
107 template<class FeatureMap = drwnBiasFeatureMap>
109  public:
113  drwnTLinearRegressor(unsigned n) :
114  drwnLinearRegressorBase(n) { initialize(n); }
117  drwnLinearRegressorBase(c) { /* do nothing */ }
118 
119  ~drwnTLinearRegressor() { /* do nothing */ }
120 
121  // access
123  return new drwnTLinearRegressor<FeatureMap>(*this);
124  }
125 
126  // initialization
127  virtual void initialize(unsigned n);
128 
129  // evaluation (regression)
130  virtual double getRegression(const vector<double>& features) const;
131 
132  protected:
133  virtual double objectiveAndGradient(const double *x, double *df) const;
134 };
135 
136 // drwnLinearRegressor ------------------------------------------------------
140 
142 
143 // drwnTLinearRegressor implementation --------------------------------------
144 
145 template<class FeatureMap>
147 {
149  const FeatureMap phi(_nFeatures);
150  _theta = VectorXd::Zero(phi.numParameters());
151 }
152 
153 template<class FeatureMap>
154 double drwnTLinearRegressor<FeatureMap>::getRegression(const vector<double>& features) const
155 {
156  DRWN_ASSERT(features.size() == (unsigned)_nFeatures);
157 
159  vector<double> t(_theta.rows());
160  Eigen::Map<VectorXd>(&t[0], t.size()) = _theta;
161 
162  const FeatureMap phi(_nFeatures);
163  return phi.dot(t, features);
164 }
165 
166 template<class FeatureMap>
167 double drwnTLinearRegressor<FeatureMap>::objectiveAndGradient(const double *x, double *df) const
168 {
169  // compute gradient and objective
170  double obj = 0.0;
171 
172  const unsigned m = _targets->size();
173  const FeatureMap phi(_nFeatures);
174  const vector<double> vx(x, x + _n);
175  vector<double> vdf(_n, 0.0);
176 
177  if (_penalty == 0) {
178  // L2 penalty
179  for (unsigned i = 0; i < m; i++) {
180  double predicted = phi.dot(vx, (*_features)[i]);
181  double dist = predicted - (*_targets)[i];
182  double wdist = (_weights == NULL) ? dist : dist * (*_weights)[i];
183  obj += dist * wdist;
184  phi.mac(vdf, (*_features)[i], wdist);
185  }
186 
187  obj *= 0.5;
188  } else {
189  // huber penalty
190  double dh;
191  for (unsigned i = 0; i < m; i++) {
192  double predicted = phi.dot(vx, (*_features)[i]);
193  double u = predicted - (*_targets)[i];
194  if (_weights == NULL) {
195  obj += drwn::huberFunctionAndDerivative(u, &dh, _beta);
196  } else {
197  obj += (*_weights)[i] * drwn::huberFunctionAndDerivative(u, &dh, _beta);
198  dh *= (*_weights)[i];
199  }
200  phi.mac(vdf, (*_features)[i], dh);
201  }
202  }
203 
204  memcpy((void *)df, (void *)&vdf[0], _n * sizeof(double));
205  if (m == 0.0) return 0.0;
206 
207  obj /= (double)m;
208  Eigen::Map<VectorXd>(df, _n) /= (double)m;
209 
210  // regularization
211  switch (_regularizer) {
212  case 0: // sum-of-squares
213  {
214  double weightNorm = 0.0;
215  for (unsigned i = 0; i < _n; i++) {
216  weightNorm += x[i] * x[i];
217  df[i] += _lambda * x[i];
218  }
219 
220  obj += 0.5 * _lambda * weightNorm;
221  }
222  break;
223 
224  case 1: // huber
225  {
226  double dh;
227  for (unsigned i = 0; i < _n; i++) {
228  obj += _lambda * drwn::huberFunctionAndDerivative(x[i], &dh, 1.0e-3);
229  df[i] += _lambda * dh;
230  }
231  }
232  break;
233 
234  default:
235  DRWN_LOG_ERROR("unsupported regularizer " << _regularizer);
236  }
237 
238  return obj;
239 }
virtual double train(const drwnRegressionDataset &dataset)=0
estimate the regression parameters a drwnRegressionDataset
int _penalty
regression penalty option
Definition: drwnLinearRegressor.h:38
Implements the interface for a generic machine learning regression, e.g. see drwnLinearRegressor.
Definition: drwnRegression.h:27
double _beta
huber penalty threshold
Definition: drwnLinearRegressor.h:39
Common functionality for drwnLinearRegressor.
Definition: drwnLinearRegressor.h:30
static int MAX_ITERATIONS
maximum training iterations
Definition: drwnLinearRegressor.h:34
drwnTLinearRegressor(const drwnTLinearRegressor< FeatureMap > &c)
copy constructor
Definition: drwnLinearRegressor.h:116
drwnTLinearRegressor(unsigned n)
construct a linear regressor for data of dimension n
Definition: drwnLinearRegressor.h:113
virtual void initialize(unsigned n)
initialize the regressor to accept data of dimensionality n
Definition: drwnRegression.cpp:47
static double HUBER_BETA
beta parameter for huber penalty
Definition: drwnLinearRegressor.h:32
virtual double objectiveAndGradient(const double *x, double *df) const
returns value of objective function and populates gradient df at point x
Definition: drwnLinearRegressor.h:167
virtual drwnTLinearRegressor< FeatureMap > * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnLinearRegressor.h:122
VectorXd _theta
regression weights
Definition: drwnLinearRegressor.h:37
virtual double getRegression(const vector< double > &features) const
return the estimated value for a given feature vector
Definition: drwnLinearRegressor.h:154
static double REG_STRENGTH
regularization strength
Definition: drwnLinearRegressor.h:33
Interface for solving large-scale unconstrained optimization problems using L-BFGS.
Definition: drwnOptimizer.h:68
int _regularizer
regularization option
Definition: drwnLinearRegressor.h:40
virtual void initialize(unsigned n)
initialize the regressor to accept data of dimensionality n
Definition: drwnLinearRegressor.h:146
Implements a cacheable dataset containing feature vectors, labels and optional weights.
Definition: drwnDataset.h:43
drwnTLinearRegressor()
default constructor
Definition: drwnLinearRegressor.h:111
virtual const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnLinearRegressor.h:59
double _lambda
regularization strength
Definition: drwnLinearRegressor.h:41
Implements linear regression optimization templated on a drwnFeatureMap.
Definition: drwnLinearRegressor.h:108
drwnTLinearRegressor drwnLinearRegressor
Conveinience type declaration for linear regression with default feature mapping. ...
Definition: drwnLinearRegressor.h:141