PJsonVal TDecisionTree::ExplainPositive() const { if (!HasRoot()) { return TJsonVal::NewArr(); } PJsonVal Result = Root->ExplainLabel(1); if (Result.Empty()) { return TJsonVal::NewArr(); } return Result; }
PJsonVal TDecisionTree::TNode::ExplainLabel(const int& Label) const { if (IsLeaf()) { if (ClassHist[Label] <= ClassHist[1 - Label]) { return PJsonVal(); } else { const double Prob = ClassHist[Label]; PJsonVal Result = TJsonVal::NewArr(); PJsonVal IntersectJson = TJsonVal::NewObj(); IntersectJson->AddToObj("covered", int(NExamples*Prob)); IntersectJson->AddToObj("purity", Prob); IntersectJson->AddToObj("terms", TJsonVal::NewArr()); Result->AddToArr(IntersectJson); return Result; } } PJsonVal Result = TJsonVal::NewArr(); if (HasLeft()) { PJsonVal LeftUnion = Left->ExplainLabel(Label); if (!LeftUnion.Empty()) { if (LeftUnion->GetArrVals() == 0) { LeftUnion->AddToArr(TJsonVal::NewArr()); } for (int i = 0; i < LeftUnion->GetArrVals(); i++) { PJsonVal IntersectJson = LeftUnion->GetArrVal(i); PJsonVal TermsJson = IntersectJson->GetObjKey("terms"); bool HadFtr = false; for (int TermN = 0; TermN < TermsJson->GetArrVals(); TermN++) { PJsonVal TermJson = TermsJson->GetArrVal(TermN); const int TermFtrN = TermJson->GetObjInt("ftrId"); if (TermFtrN == CutFtrN) { HadFtr = true; if (TermJson->GetObjNum("le") == TFlt::PInf) { TermJson->AddToObj("le", CutFtrVal); } } } if (!HadFtr) { PJsonVal TermJson = TJsonVal::NewObj(); TermJson->AddToObj("ftrId", CutFtrN); TermJson->AddToObj("le", CutFtrVal); TermJson->AddToObj("gt", TFlt::NInf); TermsJson->AddToArr(TermJson); } Result->AddToArr(IntersectJson); } } } if (HasRight()) { PJsonVal RightUnion = Right->ExplainLabel(Label); if (!RightUnion.Empty()) { if (RightUnion->GetArrVals() == 0) { RightUnion->AddToArr(TJsonVal::NewArr()); } for (int i = 0; i < RightUnion->GetArrVals(); i++) { PJsonVal IntersectJson = RightUnion->GetArrVal(i); PJsonVal TermsJson = IntersectJson->GetObjKey("terms"); bool HadFtr = false; for (int TermN = 0; TermN < TermsJson->GetArrVals(); TermN++) { PJsonVal TermJson = TermsJson->GetArrVal(TermN); const int TermFtrN = TermJson->GetObjInt("ftrId"); if (TermFtrN == CutFtrN) { HadFtr = true; if (TermJson->GetObjNum("gt") == TFlt::NInf) { TermJson->AddToObj("gt", CutFtrVal); } } } if (!HadFtr) { PJsonVal TermJson = TJsonVal::NewObj(); TermJson->AddToObj("ftrId", CutFtrN); TermJson->AddToObj("le", TFlt::PInf); TermJson->AddToObj("gt", CutFtrVal); TermsJson->AddToArr(TermJson); } Result->AddToArr(IntersectJson); } } } return Result->GetArrVals() > 0 ? Result : PJsonVal(); }