| 123 | } |
| 124 | |
| 125 | static TVector<double> GetPredictionDiffSingle( |
| 126 | const TFeaturesLayout& layout, |
| 127 | const TVector<double>& featureValues, |
| 128 | const TFullModel& model, |
| 129 | const TVector<ui32>& borderIdxForSplit, |
| 130 | const TVector<ui32>& borders, |
| 131 | TArrayRef<ui32> treeLeafIdxes, |
| 132 | bool tryIncrease |
| 133 | ) { |
| 134 | TVector<TVector<double>> floatFeatureImpact; |
| 135 | CalcIndicatorCoefficients( |
| 136 | model, |
| 137 | borderIdxForSplit, |
| 138 | featureValues, |
| 139 | treeLeafIdxes, |
| 140 | &floatFeatureImpact |
| 141 | ); |
| 142 | TVector<double> impact(layout.GetExternalFeatureCount()); |
| 143 | |
| 144 | for (const auto& feature: model.ModelTrees->GetFloatFeatures()) { |
| 145 | int featureIdx = feature.Position.Index; |
| 146 | double diff = 0; |
| 147 | auto externalIdx = feature.Position.FlatIndex; |
| 148 | for (int splitIdx = borders[featureIdx] - 1; splitIdx >= 0; --splitIdx) { |
| 149 | diff += floatFeatureImpact[featureIdx][splitIdx]; |
| 150 | if ((tryIncrease && diff > 0.) || (!tryIncrease && diff < 0.)) { |
| 151 | impact[externalIdx] = std::max(impact[externalIdx], abs(diff)); |
| 152 | } |
| 153 | } |
| 154 | diff = 0; |
| 155 | for (int splitIdx = borders[featureIdx] + 1; splitIdx < floatFeatureImpact[featureIdx].ysize(); ++splitIdx) { |
| 156 | diff += floatFeatureImpact[featureIdx][splitIdx]; |
| 157 | if ((tryIncrease && diff > 0.) || (!tryIncrease && diff < 0.)) { |
| 158 | impact[externalIdx] = std::max(impact[externalIdx], abs(diff)); |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | return impact; |
| 163 | } |
| 164 | |
| 165 | TVector<double> GetPredictionDiff( |
| 166 | const TFullModel& model, |
no test coverage detected