1 /*!
2  * Copyright 2015-2021 by Contributors
3  * \file learner.h
4  * \brief Learner interface that integrates objective, gbm and evaluation together.
5  *  This is the user facing XGBoost training module.
6  * \author Tianqi Chen
7  */
8 #ifndef XGBOOST_LEARNER_H_
9 #define XGBOOST_LEARNER_H_
10 
11 #include <dmlc/any.h>
12 #include <xgboost/base.h>
13 #include <xgboost/feature_map.h>
14 #include <xgboost/predictor.h>
15 #include <xgboost/generic_parameters.h>
16 #include <xgboost/host_device_vector.h>
17 #include <xgboost/model.h>
18 
19 #include <utility>
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 namespace xgboost {
26 
27 class Metric;
28 class GradientBooster;
29 class ObjFunction;
30 class DMatrix;
31 class Json;
32 
33 enum class PredictionType : std::uint8_t {  // NOLINT
34   kValue = 0,
35   kMargin = 1,
36   kContribution = 2,
37   kApproxContribution = 3,
38   kInteraction = 4,
39   kApproxInteraction = 5,
40   kLeaf = 6
41 };
42 
43 /*! \brief entry to to easily hold returning information */
44 struct XGBAPIThreadLocalEntry {
45   /*! \brief result holder for returning string */
46   std::string ret_str;
47   /*! \brief result holder for returning strings */
48   std::vector<std::string> ret_vec_str;
49   /*! \brief result holder for returning string pointers */
50   std::vector<const char *> ret_vec_charp;
51   /*! \brief returning float vector. */
52   std::vector<bst_float> ret_vec_float;
53   /*! \brief temp variable of gradient pairs. */
54   std::vector<GradientPair> tmp_gpair;
55   /*! \brief Temp variable for returning prediction result. */
56   PredictionCacheEntry prediction_entry;
57   /*! \brief Temp variable for returning prediction shape. */
58   std::vector<bst_ulong> prediction_shape;
59 };
60 
61 /*!
62  * \brief Learner class that does training and prediction.
63  *  This is the user facing module of xgboost training.
64  *  The Load/Save function corresponds to the model used in python/R.
65  *  \code
66  *
67  *  std::unique_ptr<Learner> learner(new Learner::Create(cache_mats));
68  *  learner.Configure(configs);
69  *
70  *  for (int iter = 0; iter < max_iter; ++iter) {
71  *    learner->UpdateOneIter(iter, train_mat);
72  *    LOG(INFO) << learner->EvalOneIter(iter, data_sets, data_names);
73  *  }
74  *
75  *  \endcode
76  */
77 class Learner : public Model, public Configurable, public dmlc::Serializable {
78  public:
79   /*! \brief virtual destructor */
80   ~Learner() override;
81   /*!
82    * \brief Configure Learner based on set parameters.
83    */
84   virtual void Configure() = 0;
85   /*!
86    * \brief update the model for one iteration
87    *  With the specified objective function.
88    * \param iter current iteration number
89    * \param train reference to the data matrix.
90    */
91   virtual void UpdateOneIter(int iter, std::shared_ptr<DMatrix> train) = 0;
92   /*!
93    * \brief Do customized gradient boosting with in_gpair.
94    *  in_gair can be mutated after this call.
95    * \param iter current iteration number
96    * \param train reference to the data matrix.
97    * \param in_gpair The input gradient statistics.
98    */
99   virtual void BoostOneIter(int iter,
100                             std::shared_ptr<DMatrix> train,
101                             HostDeviceVector<GradientPair>* in_gpair) = 0;
102   /*!
103    * \brief evaluate the model for specific iteration using the configured metrics.
104    * \param iter iteration number
105    * \param data_sets datasets to be evaluated.
106    * \param data_names name of each dataset
107    * \return a string corresponding to the evaluation result
108    */
109   virtual std::string EvalOneIter(int iter,
110                                   const std::vector<std::shared_ptr<DMatrix>>& data_sets,
111                                   const std::vector<std::string>& data_names) = 0;
112   /*!
113    * \brief get prediction given the model.
114    * \param data input data
115    * \param output_margin whether to only predict margin value instead of transformed prediction
116    * \param out_preds output vector that stores the prediction
117    * \param layer_begin Beginning of boosted tree layer used for prediction.
118    * \param layer_end   End of booster layer. 0 means do not limit trees.
119    * \param training Whether the prediction result is used for training
120    * \param pred_leaf whether to only predict the leaf index of each tree in a boosted tree predictor
121    * \param pred_contribs whether to only predict the feature contributions
122    * \param approx_contribs whether to approximate the feature contributions for speed
123    * \param pred_interactions whether to compute the feature pair contributions
124    */
125   virtual void Predict(std::shared_ptr<DMatrix> data,
126                        bool output_margin,
127                        HostDeviceVector<bst_float> *out_preds,
128                        unsigned layer_begin,
129                        unsigned layer_end,
130                        bool training = false,
131                        bool pred_leaf = false,
132                        bool pred_contribs = false,
133                        bool approx_contribs = false,
134                        bool pred_interactions = false) = 0;
135 
136   /*!
137    * \brief Inplace prediction.
138    *
139    * \param          x           A type erased data adapter.
140    * \param          p_m         An optional Proxy DMatrix object storing meta info like
141    *                             base margin.  Can be nullptr.
142    * \param          type        Prediction type.
143    * \param          missing     Missing value in the data.
144    * \param [in,out] out_preds   Pointer to output prediction vector.
145    * \param          layer_begin Beginning of boosted tree layer used for prediction.
146    * \param          layer_end   End of booster layer. 0 means do not limit trees.
147    */
148   virtual void InplacePredict(dmlc::any const &x,
149                               std::shared_ptr<DMatrix> p_m,
150                               PredictionType type,
151                               float missing,
152                               HostDeviceVector<bst_float> **out_preds,
153                               uint32_t layer_begin, uint32_t layer_end) = 0;
154 
155   /*!
156    * \brief Calculate feature score.  See doc in C API for outputs.
157    */
158   virtual void CalcFeatureScore(std::string const& importance_type,
159                                 common::Span<int32_t const> trees,
160                                 std::vector<bst_feature_t>* features,
161                                 std::vector<float>* scores) = 0;
162 
163   /*
164    * \brief Get number of boosted rounds from gradient booster.
165    */
166   virtual int32_t BoostedRounds() const = 0;
167   virtual uint32_t Groups() const = 0;
168 
169   void LoadModel(Json const& in) override = 0;
170   void SaveModel(Json* out) const override = 0;
171 
172   virtual void LoadModel(dmlc::Stream* fi) = 0;
173   virtual void SaveModel(dmlc::Stream* fo) const = 0;
174 
175   /*!
176    * \brief Set multiple parameters at once.
177    *
178    * \param args parameters.
179    */
180   virtual void SetParams(Args const& args) = 0;
181   /*!
182    * \brief Set parameter for booster
183    *
184    *  The property will NOT be saved along with booster
185    *
186    * \param key   The key of parameter
187    * \param value The value of parameter
188    */
189   virtual void SetParam(const std::string& key, const std::string& value) = 0;
190 
191   /*!
192    * \brief Get the number of features of the booster.
193    * \return number of features
194    */
195   virtual uint32_t GetNumFeature() const = 0;
196 
197   /*!
198    * \brief Set additional attribute to the Booster.
199    *
200    *  The property will be saved along the booster.
201    *
202    * \param key The key of the property.
203    * \param value The value of the property.
204    */
205   virtual void SetAttr(const std::string& key, const std::string& value) = 0;
206   /*!
207    * \brief Get attribute from the booster.
208    *  The property will be saved along the booster.
209    * \param key The key of the attribute.
210    * \param out The output value.
211    * \return Whether the key exists among booster's attributes.
212    */
213   virtual bool GetAttr(const std::string& key, std::string* out) const = 0;
214   /*!
215    * \brief Delete an attribute from the booster.
216    * \param key The key of the attribute.
217    * \return Whether the key was found among booster's attributes.
218    */
219   virtual bool DelAttr(const std::string& key) = 0;
220   /*!
221    * \brief Get a vector of attribute names from the booster.
222    * \return vector of attribute name strings.
223    */
224   virtual std::vector<std::string> GetAttrNames() const = 0;
225   /*!
226    * \brief Set the feature names for current booster.
227    * \param fn Input feature names
228    */
229   virtual  void SetFeatureNames(std::vector<std::string> const& fn) = 0;
230   /*!
231    * \brief Get the feature names for current booster.
232    * \param fn Output feature names
233    */
234   virtual void GetFeatureNames(std::vector<std::string>* fn) const = 0;
235   /*!
236    * \brief Set the feature types for current booster.
237    * \param ft Input feature types.
238    */
239   virtual void SetFeatureTypes(std::vector<std::string> const& ft) = 0;
240   /*!
241    * \brief Get the feature types for current booster.
242    * \param fn Output feature types
243    */
244   virtual void GetFeatureTypes(std::vector<std::string>* ft) const = 0;
245 
246   /*!
247    * \return whether the model allow lazy checkpoint in rabit.
248    */
249   bool AllowLazyCheckPoint() const;
250   /*!
251    * \brief Slice the model.
252    *
253    * See InplacePredict for layer parameters.
254    *
255    * \param step step size between slice.
256    * \param out_of_bound Return true if end layer is out of bound.
257    *
258    * \return a sliced model.
259    */
260   virtual Learner *Slice(int32_t begin_layer, int32_t end_layer, int32_t step,
261                          bool *out_of_bound) = 0;
262   /*!
263    * \brief dump the model in the requested format
264    * \param fmap feature map that may help give interpretations of feature
265    * \param with_stats extra statistics while dumping model
266    * \param format the format to dump the model in
267    * \return a vector of dump for boosters.
268    */
269   virtual std::vector<std::string> DumpModel(const FeatureMap& fmap,
270                                              bool with_stats,
271                                              std::string format) = 0;
272 
273   virtual XGBAPIThreadLocalEntry& GetThreadLocal() const = 0;
274   /*!
275    * \brief Create a new instance of learner.
276    * \param cache_data The matrix to cache the prediction.
277    * \return Created learner.
278    */
279   static Learner* Create(const std::vector<std::shared_ptr<DMatrix> >& cache_data);
280 
281   virtual GenericParameter const& GetGenericParameter() const = 0;
282   /*!
283    * \brief Get configuration arguments currently stored by the learner
284    * \return Key-value pairs representing configuration arguments
285    */
286   virtual const std::map<std::string, std::string>& GetConfigurationArguments() const = 0;
287 
288  protected:
289   /*! \brief objective function */
290   std::unique_ptr<ObjFunction> obj_;
291   /*! \brief The gradient booster used by the model*/
292   std::unique_ptr<GradientBooster> gbm_;
293   /*! \brief The evaluation metrics used to evaluate the model. */
294   std::vector<std::unique_ptr<Metric> > metrics_;
295   /*! \brief Training parameter. */
296   GenericParameter generic_parameters_;
297 };
298 
299 struct LearnerModelParamLegacy;
300 
301 /*
302  * \brief Basic Model Parameters, used to describe the booster.
303  */
304 struct LearnerModelParam {
305   /* \brief global bias */
306   bst_float base_score { 0.5f };
307   /* \brief number of features  */
308   uint32_t num_feature { 0 };
309   /* \brief number of classes, if it is multi-class classification  */
310   uint32_t num_output_group { 0 };
311 
312   LearnerModelParam() = default;
313   // As the old `LearnerModelParamLegacy` is still used by binary IO, we keep
314   // this one as an immutable copy.
315   LearnerModelParam(LearnerModelParamLegacy const& user_param, float base_margin);
316   /* \brief Whether this parameter is initialized with LearnerModelParamLegacy. */
InitializedLearnerModelParam317   bool Initialized() const { return num_feature != 0; }
318 };
319 
320 }  // namespace xgboost
321 #endif  // XGBOOST_LEARNER_H_
322