Added Train overloads

This commit is contained in:
Rishabh Garg
2021-07-12 10:10:01 +05:30
parent 0dd0715b5f
commit a2c9cd0c2d
2 changed files with 286 additions and 0 deletions
@@ -257,6 +257,122 @@ class DecisionTreeRegressor :
* Clean up memory.
*/
~DecisionTreeRegressor();
/**
* Train the decision tree on the given data. This will overwrite the
* existing model. The data may have numeric and categorical types, specified
* by the datasetInfo parameter. Setting minimumLeafSize and
* minimumGainSplit too small may cause the tree to overfit, but setting them
* too large may cause it to underfit.
*
* Use std::move if data or labels are no longer needed to avoid copies.
*
* @param data Dataset to train on.
* @param datasetInfo Type information for each dimension.
* @param labels Labels for each training point.
* @param minimumLeafSize Minimum number of points in each leaf node.
* @param minimumGainSplit Minimum gain for the node to split.
* @param maximumDepth Maximum depth for the tree.
* @param dimensionSelector Instantiated dimension selection policy.
* @return The final entropy of decision tree.
*/
template<typename MatType, typename LabelsType>
double Train(MatType data,
const data::DatasetInfo& datasetInfo,
LabelsType labels,
const size_t minimumLeafSize = 10,
const double minimumGainSplit = 1e-7,
const size_t maximumDepth = 0,
DimensionSelectionType dimensionSelector =
DimensionSelectionType());
/**
* Train the decision tree on the given data, assuming that all dimensions are
* numeric. This will overwrite the given model. Setting minimumLeafSize and
* minimumGainSplit too small may cause the tree to overfit, but setting them
* too large may cause it to underfit.
*
* Use std::move if data or labels are no longer needed to avoid copies.
*
* @param data Dataset to train on.
* @param labels Labels for each training point.
* @param minimumLeafSize Minimum number of points in each leaf node.
* @param minimumGainSplit Minimum gain for the node to split.
* @param maximumDepth Maximum depth for the tree.
* @param dimensionSelector Instantiated dimension selection policy.
* @return The final entropy of decision tree.
*/
template<typename MatType, typename LabelsType>
double Train(MatType data,
LabelsType labels,
const size_t minimumLeafSize = 10,
const double minimumGainSplit = 1e-7,
const size_t maximumDepth = 0,
DimensionSelectionType dimensionSelector =
DimensionSelectionType());
/**
* Train the decision tree on the given weighted data. This will overwrite
* the existing model. The data may have numeric and categorical types,
* specified by the datasetInfo parameter. Setting minimumLeafSize and
* minimumGainSplit too small may cause the tree to overfit, but setting them
* too large may cause it to underfit.
*
* Use std::move if data, labels or weights are no longer needed to avoid
* copies.
*
* @param data Dataset to train on.
* @param datasetInfo Type information for each dimension.
* @param labels Labels for each training point.
* @param weights Weights of all the labels
* @param minimumLeafSize Minimum number of points in each leaf node.
* @param minimumGainSplit Minimum gain for the node to split.
* @param maximumDepth Maximum depth for the tree.
* @param dimensionSelector Instantiated dimension selection policy.
* @return The final entropy of decision tree.
*/
template<typename MatType, typename LabelsType, typename WeightsType>
double Train(MatType data,
const data::DatasetInfo& datasetInfo,
LabelsType labels,
WeightsType weights,
const size_t minimumLeafSize = 10,
const double minimumGainSplit = 1e-7,
const size_t maximumDepth = 0,
DimensionSelectionType dimensionSelector =
DimensionSelectionType(),
const std::enable_if_t<arma::is_arma_type<typename
std::remove_reference<WeightsType>::type>::value>* = 0);
/**
* Train the decision tree on the given weighted data, assuming that all
* dimensions are numeric. This will overwrite the given model. Setting
* minimumLeafSize and minimumGainSplit too small may cause the tree to
* overfit, but setting them too large may cause it to underfit.
*
* Use std::move if data, labels or weights are no longer needed to avoid
* copies.
*
* @param data Dataset to train on.
* @param labels Labels for each training point.
* @param weights Weights of all the labels
* @param minimumLeafSize Minimum number of points in each leaf node.
* @param minimumGainSplit Minimum gain for the node to split.
* @param maximumDepth Maximum depth for the tree.
* @param dimensionSelector Instantiated dimension selection policy.
* @return The final entropy of decision tree.
*/
template<typename MatType, typename LabelsType, typename WeightsType>
double Train(MatType data,
LabelsType labels,
WeightsType weights,
const size_t minimumLeafSize = 10,
const double minimumGainSplit = 1e-7,
const size_t maximumDepth = 0,
DimensionSelectionType dimensionSelector =
DimensionSelectionType(),
const std::enable_if_t<arma::is_arma_type<typename
std::remove_reference<WeightsType>::type>::value>* = 0);
};
@@ -420,6 +420,176 @@ DecisionTreeRegressor<FitnessFunction,
delete children[i];
}
//! Train on the given data.
template<typename FitnessFunction,
template<typename> class NumericSplitType,
template<typename> class CategoricalSplitType,
typename DimensionSelectionType,
bool NoRecursion>
template<typename MatType, typename LabelsType>
double DecisionTreeRegressor<FitnessFunction,
NumericSplitType,
CategoricalSplitType,
DimensionSelectionType,
NoRecursion>::Train(
MatType data,
const data::DatasetInfo& datasetInfo,
LabelsType labels,
const size_t minimumLeafSize,
const double minimumGainSplit,
const size_t maximumDepth,
DimensionSelectionType dimensionSelector)
{
// Sanity check on data.
util::CheckSameSizes(data, labels, "DecisionTreeRegressor::Train()");
using TrueMatType = typename std::decay<MatType>::type;
using TrueLabelsType = typename std::decay<LabelsType>::type;
// Copy or move data.
TrueMatType tmpData(std::move(data));
TrueLabelsType tmpLabels(std::move(labels));
// Set the correct dimensionality for the dimension selector.
dimensionSelector.Dimensions() = tmpData.n_rows;
// Pass off work to the Train() method.
arma::rowvec weights; // Fake weights, not used.
return Train<false>(tmpData, 0, tmpData.n_cols, datasetInfo, tmpLabels,
numClasses, weights, minimumLeafSize, minimumGainSplit, maximumDepth,
dimensionSelector);
}
//! Train on the given data, assuming all dimensions are numeric.
template<typename FitnessFunction,
template<typename> class NumericSplitType,
template<typename> class CategoricalSplitType,
typename DimensionSelectionType,
bool NoRecursion>
template<typename MatType, typename LabelsType>
double DecisionTreeRegressor<FitnessFunction,
NumericSplitType,
CategoricalSplitType,
DimensionSelectionType,
NoRecursion>::Train(
MatType data,
LabelsType labels,
const size_t minimumLeafSize,
const double minimumGainSplit,
const size_t maximumDepth,
DimensionSelectionType dimensionSelector)
{
// Sanity check on data.
util::CheckSameSizes(data, labels, "DecisionTreeRegressor::Train()");
using TrueMatType = typename std::decay<MatType>::type;
using TrueLabelsType = typename std::decay<LabelsType>::type;
// Copy or move data.
TrueMatType tmpData(std::move(data));
TrueLabelsType tmpLabels(std::move(labels));
// Set the correct dimensionality for the dimension selector.
dimensionSelector.Dimensions() = tmpData.n_rows;
// Pass off work to the Train() method.
arma::rowvec weights; // Fake weights, not used.
return Train<false>(tmpData, 0, tmpData.n_cols, tmpLabels, numClasses,
weights, minimumLeafSize, minimumGainSplit, maximumDepth,
dimensionSelector);
}
//! Train on the given weighted data.
template<typename FitnessFunction,
template<typename> class NumericSplitType,
template<typename> class CategoricalSplitType,
typename DimensionSelectionType,
bool NoRecursion>
template<typename MatType, typename LabelsType, typename WeightsType>
double DecisionTreeRegressor<FitnessFunction,
NumericSplitType,
CategoricalSplitType,
DimensionSelectionType,
NoRecursion>::Train(
MatType data,
const data::DatasetInfo& datasetInfo,
LabelsType labels,
WeightsType weights,
const size_t minimumLeafSize,
const double minimumGainSplit,
const size_t maximumDepth,
DimensionSelectionType dimensionSelector,
const std::enable_if_t<
arma::is_arma_type<
typename std::remove_reference<
WeightsType>::type>::value>*)
{
// Sanity check on data.
util::CheckSameSizes(data, labels, "DecisionTreeRegressor::Train()");
using TrueMatType = typename std::decay<MatType>::type;
using TrueLabelsType = typename std::decay<LabelsType>::type;
using TrueWeightsType = typename std::decay<WeightsType>::type;
// Copy or move data.
TrueMatType tmpData(std::move(data));
TrueLabelsType tmpLabels(std::move(labels));
TrueWeightsType tmpWeights(std::move(weights));
// Set the correct dimensionality for the dimension selector.
dimensionSelector.Dimensions() = tmpData.n_rows;
// Pass off work to the Train() method.
return Train<true>(tmpData, 0, tmpData.n_cols, datasetInfo, tmpLabels,
numClasses, tmpWeights, minimumLeafSize, minimumGainSplit, maximumDepth,
dimensionSelector);
}
//! Train on the given weighted all numeric data.
template<typename FitnessFunction,
template<typename> class NumericSplitType,
template<typename> class CategoricalSplitType,
typename DimensionSelectionType,
bool NoRecursion>
template<typename MatType, typename LabelsType, typename WeightsType>
double DecisionTreeRegressor<FitnessFunction,
NumericSplitType,
CategoricalSplitType,
DimensionSelectionType,
NoRecursion>::Train(
MatType data,
LabelsType labels,
WeightsType weights,
const size_t minimumLeafSize,
const double minimumGainSplit,
const size_t maximumDepth,
DimensionSelectionType dimensionSelector,
const std::enable_if_t<
arma::is_arma_type<
typename std::remove_reference<
WeightsType>::type>::value>*)
{
// Sanity check on data.
util::CheckSameSizes(data, labels, "DecisionTreeRegressor::Train()");
using TrueMatType = typename std::decay<MatType>::type;
using TrueLabelsType = typename std::decay<LabelsType>::type;
using TrueWeightsType = typename std::decay<WeightsType>::type;
// Copy or move data.
TrueMatType tmpData(std::move(data));
TrueLabelsType tmpLabels(std::move(labels));
TrueWeightsType tmpWeights(std::move(weights));
// Set the correct dimensionality for the dimension selector.
dimensionSelector.Dimensions() = tmpData.n_rows;
// Pass off work to the Train() method.
return Train<true>(tmpData, 0, tmpData.n_cols, tmpLabels, numClasses,
tmpWeights, minimumLeafSize, minimumGainSplit, maximumDepth,
dimensionSelector);
}
} // namespace tree
} // namespace mlpack