| 131 | } |
| 132 | |
| 133 | static inline void EstimatePriors(const NCB::TTrainingDataProvider& dataProvider, |
| 134 | TBinarizedFeaturesManager& featureManager, |
| 135 | NCatboostOptions::TCatFeatureParams& options, |
| 136 | NPar::ILocalExecutor* localExecutor) { |
| 137 | CB_ENSURE(&(featureManager.GetCatFeatureOptions()) == &options, "Error: for consistent catFeature options should be equal to one in feature manager"); |
| 138 | |
| 139 | bool needSimpleCtrsPriorEstimation = NeedPriorEstimation(options.SimpleCtrs); |
| 140 | const auto& borders = featureManager.GetTargetBorders(); |
| 141 | if (borders.size() > 1) { |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | const auto& featuresLayout = *dataProvider.MetaInfo.FeaturesLayout; |
| 146 | |
| 147 | auto binarizedTarget = NCB::BinarizeLine<ui8>((*dataProvider.TargetData->GetTarget())[0], ENanMode::Forbidden, borders); // espetrov: fix for multi-target + ctr |
| 148 | TAdaptiveLock lock; |
| 149 | |
| 150 | //TODO(noxoomo): locks here are ugly and error prone |
| 151 | NPar::ParallelFor(*localExecutor, 0, (int)featuresLayout.GetCatFeatureCount(), [&](int catFeatureIdx) { |
| 152 | if (!featuresLayout.GetInternalFeatureMetaInfo((ui32)catFeatureIdx, EFeatureType::Categorical).IsAvailable) { |
| 153 | return; |
| 154 | } |
| 155 | const auto& catFeatureValues = **(dataProvider.ObjectsData->GetCatFeature(catFeatureIdx)); |
| 156 | |
| 157 | bool hasPerFeatureCtr = false; |
| 158 | |
| 159 | auto catFeatureFlatIdx = featuresLayout.GetExternalFeatureIdx(catFeatureIdx, EFeatureType::Categorical); |
| 160 | |
| 161 | with_lock (lock) { |
| 162 | if (needSimpleCtrsPriorEstimation && !options.PerFeatureCtrs->contains(catFeatureFlatIdx)) { |
| 163 | options.PerFeatureCtrs.Get()[catFeatureFlatIdx] = options.SimpleCtrs; |
| 164 | } |
| 165 | hasPerFeatureCtr = options.PerFeatureCtrs->contains(catFeatureFlatIdx); |
| 166 | } |
| 167 | |
| 168 | if (hasPerFeatureCtr) { |
| 169 | TVector<NCatboostOptions::TCtrDescription> currentFeatureDescription; |
| 170 | with_lock (lock) { |
| 171 | currentFeatureDescription = options.PerFeatureCtrs->at(catFeatureFlatIdx); |
| 172 | } |
| 173 | if (!NeedPriorEstimation(currentFeatureDescription)) { |
| 174 | return; |
| 175 | } |
| 176 | |
| 177 | for (ui32 i = 0; i < currentFeatureDescription.size(); ++i) { |
| 178 | if (currentFeatureDescription[i].Type == ECtrType::Borders && options.TargetBinarization->BorderCount == 1u) { |
| 179 | ui32 uniqueValues = dataProvider.ObjectsData->GetQuantizedFeaturesInfo()->GetUniqueValuesCounts(TCatFeatureIdx((ui32)catFeatureIdx)).OnAll; |
| 180 | |
| 181 | TBetaPriorEstimator::TBetaPrior prior = TBetaPriorEstimator::EstimateBetaPrior( |
| 182 | binarizedTarget.data(), |
| 183 | catFeatureValues.GetBlockIterator(), |
| 184 | catFeatureValues.GetSize(), |
| 185 | uniqueValues |
| 186 | ); |
| 187 | |
| 188 | CATBOOST_INFO_LOG << "Estimate borders-ctr prior for feature #" << catFeatureFlatIdx << ": " << prior.Alpha << " / " << prior.Beta << Endl; |
| 189 | currentFeatureDescription[i].Priors = {{(float)prior.Alpha, (float)(prior.Alpha + prior.Beta)}}; |
| 190 | } else { |
no test coverage detected