| 312 | } |
| 313 | |
| 314 | TVector<TInternalFeatureInteraction> CalcInternalFeatureInteraction(const TFullModel& model) { |
| 315 | if (model.GetTreeCount() == 0) { |
| 316 | return TVector<TInternalFeatureInteraction>(); |
| 317 | } |
| 318 | CB_ENSURE_SCALE_IDENTITY(model.GetScaleAndBias(), "feature interaction"); |
| 319 | |
| 320 | TVector<TFeature> features; |
| 321 | THashMap<TFeature, int, TFeatureHash> featureToIdx = GetFeatureToIdxMap(model, &features); |
| 322 | |
| 323 | TVector<TFeaturePairInteractionInfo> pairwiseEffect; |
| 324 | |
| 325 | if (model.IsOblivious()) { |
| 326 | TVector<TMxTree> trees = BuildTrees(featureToIdx, model); |
| 327 | pairwiseEffect = CalcMostInteractingFeatures(trees); |
| 328 | } else { |
| 329 | pairwiseEffect = CalcMostInteractingFeatures( |
| 330 | model, |
| 331 | featureToIdx |
| 332 | ); |
| 333 | } |
| 334 | |
| 335 | TVector<TInternalFeatureInteraction> result; |
| 336 | result.reserve(pairwiseEffect.size()); |
| 337 | for (const auto& efffect : pairwiseEffect) { |
| 338 | result.emplace_back(efffect.Score, features[efffect.Feature1], features[efffect.Feature2]); |
| 339 | } |
| 340 | return result; |
| 341 | } |
| 342 | |
| 343 | TVector<TFeatureInteraction> CalcFeatureInteraction( |
| 344 | const TVector<TInternalFeatureInteraction>& internalFeatureInteraction, |
no test coverage detected