| 193 | } |
| 194 | |
| 195 | TVector<TFeatureEffect> CalcRegularFeatureEffect( |
| 196 | const TVector<std::pair<double, TFeature>>& internalEffect, |
| 197 | const TFullModel& model) |
| 198 | { |
| 199 | int catFeaturesCount = model.GetNumCatFeatures(); |
| 200 | int floatFeaturesCount = model.GetNumFloatFeatures(); |
| 201 | int textFeaturesCount = model.GetNumTextFeatures(); |
| 202 | int embeddingFeaturesCount = model.GetNumEmbeddingFeatures(); |
| 203 | TVector<double> catFeatureEffect(catFeaturesCount); |
| 204 | TVector<double> floatFeatureEffect(floatFeaturesCount); |
| 205 | TVector<double> textFeatureEffect(textFeaturesCount); |
| 206 | TVector<double> embeddingFeatureEffect(embeddingFeaturesCount); |
| 207 | |
| 208 | for (const auto& effectWithSplit : internalEffect) { |
| 209 | TFeature feature = effectWithSplit.second; |
| 210 | switch (feature.Type) { |
| 211 | case ESplitType::FloatFeature: |
| 212 | floatFeatureEffect[feature.FeatureIdx] += effectWithSplit.first; |
| 213 | break; |
| 214 | case ESplitType::OneHotFeature: |
| 215 | catFeatureEffect[feature.FeatureIdx] += effectWithSplit.first; |
| 216 | break; |
| 217 | case ESplitType::OnlineCtr: { |
| 218 | auto& proj = feature.Ctr.Base.Projection; |
| 219 | int featuresInSplit = proj.BinFeatures.ysize() + proj.CatFeatures.ysize() |
| 220 | + proj.OneHotFeatures.ysize(); |
| 221 | double addEffect = effectWithSplit.first / featuresInSplit; |
| 222 | for (const auto& binFeature : proj.BinFeatures) { |
| 223 | floatFeatureEffect[binFeature.FloatFeature] += addEffect; |
| 224 | } |
| 225 | for (auto catIndex : proj.CatFeatures) { |
| 226 | catFeatureEffect[catIndex] += addEffect; |
| 227 | } |
| 228 | for (auto oneHotFeature : proj.OneHotFeatures) { |
| 229 | catFeatureEffect[oneHotFeature.CatFeatureIdx] += addEffect; |
| 230 | } |
| 231 | break; |
| 232 | } |
| 233 | case ESplitType::EstimatedFeature: { |
| 234 | if (feature.EstimatedFeature.SourceFeatureType == EEstimatedSourceFeatureType::Text) { |
| 235 | textFeatureEffect[feature.EstimatedFeature.SourceFeatureId] += effectWithSplit.first; |
| 236 | } else { |
| 237 | CB_ENSURE( |
| 238 | feature.EstimatedFeature.SourceFeatureType == EEstimatedSourceFeatureType::Embedding |
| 239 | ); |
| 240 | embeddingFeatureEffect[feature.EstimatedFeature.SourceFeatureId] += effectWithSplit.first; |
| 241 | } |
| 242 | break; |
| 243 | } |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | TVector<TFeatureEffect> regularFeatureEffect; |
| 248 | for (int i = 0; i < catFeatureEffect.ysize(); ++i) { |
| 249 | regularFeatureEffect.push_back( |
| 250 | TFeatureEffect(catFeatureEffect[i], EFeatureType::Categorical, i) |
| 251 | ); |
| 252 | } |
no test coverage detected