utility function for python_package/catboost/core.py plot_tree function
| 178 | |
| 179 | // utility function for python_package/catboost/core.py plot_tree function |
| 180 | TVector<TString> GetTreeSplitsDescriptions(const TFullModel& model, size_t treeIdx, const NCB::TDataProviderPtr pool) { |
| 181 | CB_ENSURE(treeIdx < model.GetTreeCount(), |
| 182 | "Requested tree splits description for tree " << treeIdx << ", but model has " << model.GetTreeCount()); |
| 183 | |
| 184 | if (pool) { |
| 185 | CheckModelAndDatasetCompatibility(model, *pool->ObjectsData.Get()); |
| 186 | } |
| 187 | |
| 188 | TVector<TString> splits; |
| 189 | |
| 190 | const auto binFeatures = model.ModelTrees->GetBinFeatures(); |
| 191 | |
| 192 | size_t treeSplitEnd = (treeIdx + 1 < model.GetTreeCount()) |
| 193 | ? model.ModelTrees->GetModelTreeData()->GetTreeStartOffsets()[treeIdx + 1] |
| 194 | : model.ModelTrees->GetModelTreeData()->GetTreeSplits().size(); |
| 195 | |
| 196 | THashMap<ui32, TString> catFeaturesHash; |
| 197 | NCB::TFeaturesLayout featuresLayout; |
| 198 | if (pool) { |
| 199 | catFeaturesHash = MergeCatFeaturesHashToString(pool.Get()->ObjectsData.Get()[0]); |
| 200 | featuresLayout = *(pool.Get()->MetaInfo.FeaturesLayout.Get()); |
| 201 | } else { |
| 202 | TVector<ui32> catFeaturesExternalIndexes; |
| 203 | for (const auto& feature: model.ModelTrees->GetCatFeatures()) { |
| 204 | catFeaturesExternalIndexes.push_back(feature.Position.FlatIndex); |
| 205 | } |
| 206 | featuresLayout = NCB::TFeaturesLayout(model.GetNumFloatFeatures() + model.GetNumCatFeatures(), catFeaturesExternalIndexes, {}, {}, {}, false); |
| 207 | } |
| 208 | |
| 209 | for (size_t splitIdx = model.ModelTrees->GetModelTreeData()->GetTreeStartOffsets()[treeIdx]; splitIdx < treeSplitEnd; ++splitIdx) { |
| 210 | TModelSplit binFeature = binFeatures[model.ModelTrees->GetModelTreeData()->GetTreeSplits()[splitIdx]]; |
| 211 | TString featureDescription = BuildDescription(featuresLayout, binFeature); |
| 212 | |
| 213 | if (binFeature.Type == ESplitType::OneHotFeature) { |
| 214 | CB_ENSURE(pool, |
| 215 | "Please pass training dataset to plot_tree function, " |
| 216 | "training dataset is required if categorical features are present in the model."); |
| 217 | featureDescription += catFeaturesHash[(ui32)binFeature.OneHotFeature.Value]; |
| 218 | } |
| 219 | |
| 220 | splits.push_back(featureDescription); |
| 221 | } |
| 222 | |
| 223 | return splits; |
| 224 | } |
| 225 | |
| 226 | TVector<TString> GetTreeLeafValuesDescriptions(const TFullModel& model, size_t treeIdx) { |
| 227 | CB_ENSURE(treeIdx < model.GetTreeCount(), |
nothing calls this directly
no test coverage detected