| 17 | |
| 18 | |
| 19 | TVector<double> CollectLeavesStatistics( |
| 20 | const TDataProvider& dataset, |
| 21 | const TFullModel& model, |
| 22 | NPar::ILocalExecutor* localExecutor) { |
| 23 | |
| 24 | TConstArrayRef<float> weights; |
| 25 | |
| 26 | TTargetDataProviderPtr targetData; // needed to own weights data |
| 27 | |
| 28 | if (const auto* modelInfoParams = MapFindPtr(model.ModelInfo, "params")) { |
| 29 | NJson::TJsonValue paramsJson = ReadTJsonValue(*modelInfoParams); |
| 30 | if (paramsJson.Has("loss_function")) { |
| 31 | TRestorableFastRng64 rand(0); |
| 32 | |
| 33 | targetData = CreateModelCompatibleProcessedDataProvider( |
| 34 | dataset, |
| 35 | {}, |
| 36 | model, |
| 37 | GetMonopolisticFreeCpuRam(), |
| 38 | &rand, |
| 39 | localExecutor, |
| 40 | /*metricsThatRequireTargetCanBeSkipped*/true, |
| 41 | /*skipMinMaxPairsCheck*/true, |
| 42 | /*skipTargetConsistencyCheck*/true |
| 43 | ).TargetData; |
| 44 | |
| 45 | weights = GetWeights(*targetData); |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | // If it is impossible to get properly adjusted weights use raw weights from RawTargetData |
| 50 | if (weights.empty()) { |
| 51 | const TWeights<float>& rawWeights = dataset.RawTargetData.GetWeights(); |
| 52 | if (!rawWeights.IsTrivial()) { |
| 53 | weights = rawWeights.GetNonTrivialData(); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | size_t treeCount = model.GetTreeCount(); |
| 58 | const int approxDimension = model.ModelTrees->GetDimensionsCount(); |
| 59 | TVector<double> leavesStatistics( |
| 60 | model.ModelTrees->GetModelTreeData()->GetLeafValues().size() / approxDimension |
| 61 | ); |
| 62 | |
| 63 | auto binFeatures = MakeQuantizedFeaturesForEvaluator(model, *dataset.ObjectsData.Get()); |
| 64 | |
| 65 | const auto documentsCount = dataset.GetObjectCount(); |
| 66 | auto applyData = model.ModelTrees->GetApplyData(); |
| 67 | for (size_t treeIdx = 0; treeIdx < treeCount; ++treeIdx) { |
| 68 | TVector<TIndexType> indices = BuildIndicesForBinTree(model, binFeatures.Get(), treeIdx); |
| 69 | const int offset = applyData->TreeFirstLeafOffsets[treeIdx] / approxDimension; |
| 70 | if (indices.empty()) { |
| 71 | continue; |
| 72 | } |
| 73 | |
| 74 | if (weights.empty()) { |
| 75 | for (size_t doc = 0; doc < documentsCount; ++doc) { |
| 76 | const TIndexType valueIndex = indices[doc]; |
no test coverage detected