Turi Create  4.0
logistic_regression_opt_interface.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_REGR_LOGISTIC_REGRESSION_OPT_INTERFACE_H_
7 #define TURI_REGR_LOGISTIC_REGRESSION_OPT_INTERFACE_H_
8 
9 // ML-Data Utils
10 #include <ml/ml_data/ml_data.hpp>
11 
12 // Toolkits
13 #include <toolkits/supervised_learning/standardization-inl.hpp>
14 #include <toolkits/supervised_learning/supervised_learning.hpp>
15 #include <toolkits/supervised_learning/logistic_regression.hpp>
16 
17 // Optimization Interface
18 #include <ml/optimization/optimization_interface.hpp>
19 
20 
21 namespace turi {
22 namespace supervised {
23 
24 /*
25  * Logistic Regression Solver
26  * *****************************************************************************
27  *
28  */
29 
30 
31  /**
32  * Solver interface for logistic regression.
33  *
34  * Let J denote the number of classes, K the number of features, and N the
35  * number of examples.
36  *
37  * coefs = [coef_1 ... coef_{J-1}] := (K * (J-1)) x 1 column vector
38  * where each
39  * coef_j for j = 1 .. J-1 is a K x 1 column vector representing coefficients
40  * for the class j.
41  *
42  */
45 
46  protected:
47 
48  ml_data data;
49  ml_data valid_data;
50  logistic_regression& smodel;
51 
52  // number of examples, features, and total variables
53  size_t examples = 0;
54  size_t classes = 2;
55  size_t features = 0;
56  size_t variables = 0;
57  size_t n_threads;
58 
59  std::map<size_t, float> class_weights = {{0,1.0}, {1, 1.0}};
60 
61  std::shared_ptr<l2_rescaling> scaler; /** <Scale features */
62  bool feature_rescaling = false; /** Feature rescaling */
63  bool is_dense = false; /** Is the data dense? */
64 
65  public:
66 
67  /**
68  * Default constructor
69  *
70  * \param[in] _data ML Data containing everything
71  *
72  * \note Default options are used when the interface is called from the
73  * logistic regression class.
74  */
76  const ml_data& _valid_data,
77  logistic_regression& _model);
78 
79  /**
80  * Default destructor
81  */
83 
84  /**
85  * Set feature scaling
86  */
88 
89 
90  /**
91  * Transform the final solution back to the original scale.
92  *
93  * \param[in,out] coefs Solution vector
94  */
95  void rescale_solution(DenseVector& coefs);
96 
97  /**
98  * Set the number of threads
99  *
100  * \param[in] _n_threads Number of threads
101  */
102  void set_threads(size_t _n_threads);
103 
104  /**
105  * Set the class weights (as a flex_dict which is already validated)
106  *
107  * \param[in] class_weights Validated flex_dict
108  * Key : Index of the class in the target_metadata
109  * Value : Weights on the class
110  */
111  void set_class_weights(const flexible_type& class_weights);
112 
113  /**
114  * Get the number of examples for the model
115  *
116  * \returns Number of examples
117  */
118  size_t num_examples() const;
119 
120  /**
121  * Get the number of validation-set examples for the model
122  *
123  * \returns Number of examples
124  */
125  size_t num_validation_examples() const;
126 
127  /**
128  * Get the number of variables in the model
129  *
130  * \returns Number of variables
131  */
132  size_t num_variables() const;
133 
134  /**
135  * Get the number of classes in the model
136  *
137  * \returns Number of classes
138  */
139  size_t num_classes() const;
140 
141 
142  /**
143  * Get strings needed to print the header for the progress table.
144  *
145  * \param[in] a vector of strings to print at the beginning of the header.
146  */
147  std::vector<std::pair<std::string, size_t>>
148  get_status_header(const std::vector<std::string>& stat_names);
149 
150  /**
151  * Get strings needed to print a row of the progress table.
152  *
153  * \param[in] a vector of model coefficients.
154  * \param[in] a vector of stats to print at the beginning of each row
155  */
156  std::vector<std::string> get_status(const DenseVector& coefs,
157  const std::vector<std::string>& stats);
158 
159  double get_validation_accuracy();
160  double get_training_accuracy();
161 
162  /**
163  * Compute first order statistics at the given point. (Gradient & Function value)
164  *
165  * \param[in] point Point at which we are computing the stats.
166  * \param[out] gradient Dense gradient
167  * \param[out] function_value Function value
168  * \param[in] mbStart Minibatch start index
169  * \param[in] mbSize Minibatch size (-1 implies all)
170  *
171  */
172  void compute_first_order_statistics(const DenseVector &point, DenseVector&
173  gradient, double & function_value, const size_t mbStart = 0, const size_t
174  mbSize = -1);
175 
176  /**
177  * Compute second order statistics at the given point. (Gradient & Function value)
178  *
179  * \param[in] point Point at which we are computing the stats.
180  * \param[out] hessian Hessian (Dense)
181  * \param[out] gradient Dense gradient
182  * \param[out] function_value Function value
183  *
184  */
185  void compute_second_order_statistics(const DenseVector &point, DenseMatrix&
186  hessian, DenseVector& gradient, double & function_value);
187 
188  /**
189  * Compute first order statistics at the given point with respect to the
190  * validation data. (Gradient & Function value)
191  *
192  * \param[in] point Point at which we are computing the stats.
193  * \param[out] gradient Dense gradient
194  * \param[out] function_value Function value
195  *
196  */
198  const DenseVector& point, DenseVector& gradient, double &function_value);
199 
200  private:
201 
202  void compute_first_order_statistics(const ml_data& data, const DenseVector
203  &point, DenseVector& gradient, double & function_value, const size_t
204  mbStart = 0, const size_t mbSize = -1);
205 };
206 
207 
208 } // supervised
209 } // turicreate
210 
211 #endif
logistic_regression_opt_interface(const ml_data &_data, const ml_data &_valid_data, logistic_regression &_model)
std::vector< std::string > get_status(const DenseVector &coefs, const std::vector< std::string > &stats)
void set_class_weights(const flexible_type &class_weights)
void compute_validation_first_order_statistics(const DenseVector &point, DenseVector &gradient, double &function_value)
void compute_first_order_statistics(const DenseVector &point, DenseVector &gradient, double &function_value, const size_t mbStart=0, const size_t mbSize=-1)
std::vector< std::pair< std::string, size_t > > get_status_header(const std::vector< std::string > &stat_names)
void compute_second_order_statistics(const DenseVector &point, DenseMatrix &hessian, DenseVector &gradient, double &function_value)