| 225 | } |
| 226 | |
| 227 | void NCB::NCoreML::ConfigureTreeModelIO( |
| 228 | const TFullModel& model, |
| 229 | const NJson::TJsonValue& userParameters, |
| 230 | TreeEnsembleRegressor* regressor, |
| 231 | ModelDescription* description, |
| 232 | TPerTypeFeatureIdxToInputIndex* perTypeFeatureIdxToInputIndex) { |
| 233 | |
| 234 | ConfigureFloatInput(model, description, &(perTypeFeatureIdxToInputIndex->ForFloatFeatures)); |
| 235 | |
| 236 | size_t catFeaturesCount = model.ModelTrees->GetCatFeatures().size(); |
| 237 | TVector<int> categoricalFlatIndexes(catFeaturesCount); |
| 238 | for (const auto& catFeature: model.ModelTrees->GetCatFeatures()) { |
| 239 | categoricalFlatIndexes[catFeature.Position.Index] = catFeature.Position.FlatIndex; |
| 240 | } |
| 241 | |
| 242 | for (const auto& oneHotFeature : model.ModelTrees->GetOneHotFeatures()) { |
| 243 | (*perTypeFeatureIdxToInputIndex).ForCatFeatures[oneHotFeature.CatFeatureIndex] = description->input().size(); |
| 244 | |
| 245 | auto feature = description->add_input(); |
| 246 | int flatFeatureIndex = categoricalFlatIndexes[oneHotFeature.CatFeatureIndex]; |
| 247 | |
| 248 | feature->set_name(("mapped_feature_" + std::to_string(flatFeatureIndex)).c_str()); |
| 249 | |
| 250 | auto featureType = new FeatureType(); |
| 251 | featureType->set_isoptional(false); |
| 252 | featureType->set_allocated_int64type(new Int64FeatureType()); |
| 253 | feature->set_allocated_type(featureType); |
| 254 | } |
| 255 | |
| 256 | const auto classesCount = static_cast<size_t>(model.ModelTrees->GetDimensionsCount()); |
| 257 | regressor->mutable_treeensemble()->set_numpredictiondimensions(classesCount); |
| 258 | if (classesCount == 1) { |
| 259 | regressor->mutable_treeensemble()->add_basepredictionvalue( |
| 260 | model.ModelTrees->GetScaleAndBias().GetOneDimensionalBias( |
| 261 | "Non single-dimension approxes are not supported") |
| 262 | ); |
| 263 | } else { |
| 264 | for (size_t outputIdx = 0; outputIdx < classesCount; ++outputIdx) { |
| 265 | regressor->mutable_treeensemble()->add_basepredictionvalue(0.0); |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | auto outputPrediction = description->add_output(); |
| 270 | outputPrediction->set_name("prediction"); |
| 271 | description->set_predictedfeaturename("prediction"); |
| 272 | description->set_predictedprobabilitiesname("prediction"); |
| 273 | |
| 274 | auto featureType = outputPrediction->mutable_type(); |
| 275 | featureType->set_isoptional(false); |
| 276 | |
| 277 | auto outputArray = new ArrayFeatureType(); |
| 278 | outputArray->set_datatype(ArrayFeatureType::DOUBLE); |
| 279 | outputArray->add_shape(classesCount); |
| 280 | |
| 281 | featureType->set_allocated_multiarraytype(outputArray); |
| 282 | |
| 283 | const auto& prediction_type = userParameters["prediction_type"].GetString(); |
| 284 | if (prediction_type == "probability") { |
nothing calls this directly
no test coverage detected