| 185 | } |
| 186 | |
| 187 | TVector<double> GetPartialDependence( |
| 188 | const TFullModel& model, |
| 189 | const TVector<int>& features, |
| 190 | const NCB::TDataProviderPtr dataProvider, |
| 191 | int threadCount |
| 192 | ) { |
| 193 | CB_ENSURE(model.ModelTrees->GetDimensionsCount() == 1, "Is not supported for multiclass"); |
| 194 | CB_ENSURE(model.GetNumCatFeatures() == 0, "Models with categorical features are not supported"); |
| 195 | CB_ENSURE(features.size() > 0 && features.size() <= 2, "Number of features should be equal to one or two"); |
| 196 | //TODO(eermishkina): support non symmetric trees |
| 197 | CB_ENSURE(model.IsOblivious(), "Partial dependence is supported only for symmetric trees"); |
| 198 | |
| 199 | NPar::TLocalExecutor localExecutor; |
| 200 | localExecutor.RunAdditionalThreads(threadCount - 1); |
| 201 | |
| 202 | TVector<double> leafWeights = CollectLeavesStatistics(*dataProvider, model, &localExecutor); |
| 203 | |
| 204 | const auto& binSplits = model.ModelTrees->GetBinFeatures(); |
| 205 | |
| 206 | TVector<ui32> borderIdxForSplit(binSplits.size(), std::numeric_limits<ui32>::infinity()); |
| 207 | ui32 splitIdx = 0; |
| 208 | for (const auto& feature : model.ModelTrees->GetFloatFeatures()) { |
| 209 | if (splitIdx == binSplits.size() || |
| 210 | binSplits[splitIdx].Type != ESplitType::FloatFeature || |
| 211 | binSplits[splitIdx].FloatFeature.FloatFeature > feature.Position.Index |
| 212 | ) { |
| 213 | continue; |
| 214 | } |
| 215 | CB_ENSURE_INTERNAL(binSplits[splitIdx].FloatFeature.FloatFeature >= feature.Position.Index, "Only float features are supported"); |
| 216 | for (ui32 idx = 0; idx < feature.Borders.size() && binSplits[splitIdx].FloatFeature.FloatFeature == feature.Position.Index; ++idx) { |
| 217 | if (abs(binSplits[splitIdx].FloatFeature.Split - feature.Borders[idx]) < 1e-15) { |
| 218 | borderIdxForSplit[splitIdx] = idx; |
| 219 | ++splitIdx; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | TVector<double> predictionsByBuckets = CalculatePartialDependence( |
| 225 | model, |
| 226 | features, |
| 227 | *dataProvider, |
| 228 | borderIdxForSplit, |
| 229 | leafWeights, |
| 230 | &localExecutor |
| 231 | ); |
| 232 | return predictionsByBuckets; |
| 233 | } |
nothing calls this directly
no test coverage detected