CSoftMaxCPD::CSoftMaxCPD(const CSoftMaxCPD& SMCPD): CCPD(dtSoftMax, ftCPD, SMCPD.GetModelDomain()) { if (SMCPD.m_CorrespDistribFun->GetDistributionType() == dtSoftMax) { delete m_CorrespDistribFun; m_CorrespDistribFun = CSoftMaxDistribFun::Copy( static_cast<CSoftMaxDistribFun*>(SMCPD.m_CorrespDistribFun)); } else { if (SMCPD.m_CorrespDistribFun->GetDistributionType() == dtCondSoftMax) { delete m_CorrespDistribFun; m_CorrespDistribFun = CCondSoftMaxDistribFun::Copy( static_cast<CCondSoftMaxDistribFun*>(SMCPD.m_CorrespDistribFun)); } else { PNL_THROW(CInconsistentType, "distribution must be SoftMax or conditional SoftMax") } } m_Domain = intVector(SMCPD.m_Domain); m_MaximizingMethod = SMCPD.m_MaximizingMethod; }
void CEMLearningEngine::Learn() { CStaticGraphicalModel *pGrModel = this->GetStaticModel(); PNL_CHECK_IS_NULL_POINTER(pGrModel); PNL_CHECK_LEFT_BORDER(GetNumEv() - GetNumberProcEv() , 1); CInfEngine *pInfEng = NULL; if (m_pInfEngine) { pInfEng = m_pInfEngine; } else { if (!m_bAllObserved) { pInfEng = CJtreeInfEngine::Create(pGrModel); m_pInfEngine = pInfEng; } } float loglik = 0.0f; int nFactors = pGrModel->GetNumberOfFactors(); const CEvidence *pEv; CFactor *pFactor; int iteration = 0; int ev; bool IsCastNeed = false; int i; for( i = 0; i < nFactors; i++ ) { pFactor = pGrModel->GetFactor(i); EDistributionType dt = pFactor->GetDistributionType(); if ( dt == dtSoftMax ) IsCastNeed = true; } float ** full_evid = NULL; if (IsCastNeed) { BuildFullEvidenceMatrix(&full_evid); } if (IsAllObserved()) { int i; float **evid = NULL; EDistributionType dt; CFactor *factor = NULL; for (i = 0; i < nFactors; i++) { factor = pGrModel->GetFactor(i); dt = factor->GetDistributionType(); if (dt != dtSoftMax) { factor->UpdateStatisticsML(&m_Vector_pEvidences[GetNumberProcEv()], GetNumEv() - GetNumberProcEv()); } else { intVector family; family.resize(0); pGrModel->GetGraph()->GetParents(i, &family); family.push_back(i); CSoftMaxCPD* SoftMaxFactor = static_cast<CSoftMaxCPD*>(factor); SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, &evid,family,m_Vector_pEvidences.size()); SoftMaxFactor->InitLearnData(); SoftMaxFactor->SetMaximizingMethod(m_MaximizingMethod); SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(), 0.00001f, 0.01f); SoftMaxFactor->CopyLearnDataToDistrib(); for (int k = 0; k < factor->GetDomainSize(); k++) { delete [] evid[k]; } delete [] evid; } } m_critValue.push_back(UpdateModel()); } else { bool bContinue; const CPotential * pot; /* bool IsCastNeed = false; int i; for( i = 0; i < nFactors; i++ ) { pFactor = pGrModel->GetFactor(i); EDistributionType dt = pFactor->GetDistributionType(); if ( dt == dtSoftMax ) IsCastNeed = true; } float ** full_evid; if (IsCastNeed) { BuildFullEvidenceMatrix(full_evid); }*/ do { ClearStatisticData(); iteration++; for( ev = GetNumberProcEv(); ev < GetNumEv() ; ev++ ) { bool bInfIsNeed = !GetObsFlags(ev)->empty(); pEv = m_Vector_pEvidences[ev]; if( bInfIsNeed ) { pInfEng->EnterEvidence(pEv, 0, 0); } int i; for( i = 0; i < nFactors; i++ ) { pFactor = pGrModel->GetFactor(i); int nnodes; const int * domain; pFactor->GetDomain( &nnodes, &domain ); if( bInfIsNeed && !IsDomainObserved(nnodes, domain, ev ) ) { pInfEng->MarginalNodes( domain, nnodes, 1 ); pot = pInfEng->GetQueryJPD(); if ( (!(m_Vector_pEvidences[ev])->IsNodeObserved(i)) && (IsCastNeed) ) { Cast(pot, i, ev, &full_evid); } EDistributionType dt; dt = pFactor->GetDistributionType(); if ( !(dt == dtSoftMax) ) pFactor->UpdateStatisticsEM( /*pInfEng->GetQueryJPD */ pot, pEv ); } else { if ((pFactor->GetDistributionType()) != dtSoftMax) pFactor->UpdateStatisticsML( &pEv, 1 ); } } } int i; /* printf ("\n My Full Evidence Matrix"); for (i=0; i<nFactors; i++) { for (j=0; j<GetNumEv(); j++) { printf ("%f ", full_evid[i][j]); } printf("\n"); } */ float **evid = NULL; EDistributionType dt; CFactor *factor = NULL; // int i; for (i = 0; i < nFactors; i++) { factor = pGrModel->GetFactor(i); dt = factor->GetDistributionType(); if (dt == dtSoftMax) { intVector family; family.resize(0); pGrModel->GetGraph()->GetParents(i, &family); family.push_back(i); CSoftMaxCPD* SoftMaxFactor = static_cast<CSoftMaxCPD*>(factor); SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, &evid,family,m_Vector_pEvidences.size()); SoftMaxFactor->InitLearnData(); SoftMaxFactor->SetMaximizingMethod(m_MaximizingMethod); // SoftMaxFactor->MaximumLikelihood(evid, m_numberOfLastEvidences, SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(), 0.00001f, 0.01f); SoftMaxFactor->CopyLearnDataToDistrib(); for (int k = 0; k < factor->GetDomainSize(); k++) { delete [] evid[k]; } delete [] evid; } } loglik = UpdateModel(); if( GetMaxIterEM() != 1) { bool flag = iteration == 1 ? true : (fabs(2*(m_critValue.back()-loglik)/(m_critValue.back() + loglik)) > GetPrecisionEM() ); bContinue = GetMaxIterEM() > iteration && flag; } else { bContinue = false; } m_critValue.push_back(loglik); }while(bContinue); } SetNumProcEv( GetNumEv() ); if (IsCastNeed) { int NumOfNodes = pGrModel->GetGraph()->GetNumberOfNodes(); for (i=0; i<NumOfNodes; i++) { delete [] full_evid[i]; } delete [] full_evid; } }
CCPD* CMlStaticStructLearn::ComputeFactor(intVector vFamily, CGraphicalModel* pGrModel, CEvidence** pEvidences) { int nFamily = vFamily.size(); int DomainSize; const int * domain; const CEvidence * pEv; int i; CTabularDistribFun *pDistribFun; CCPD* iCPD = this->CreateRandomCPD(nFamily, &vFamily.front(), pGrModel); int ncases = m_Vector_pEvidences.size(); if ( !(iCPD->GetDistributionType() == dtSoftMax)) { if (m_ScoreMethod != MarLh) { iCPD->UpdateStatisticsML( pEvidences, ncases ); iCPD->ProcessingStatisticalData(ncases); } else { iCPD->GetDomain(&DomainSize, &domain); pDistribFun = static_cast<CTabularDistribFun *>(iCPD->GetDistribFun()); pDistribFun->InitPseudoCounts(m_K2alfa); for (i=0; i<ncases; i++) { pEv = m_Vector_pEvidences[i]; const CEvidence *pEvidences[] = { pEv }; pDistribFun->BayesUpdateFactor(pEvidences, 1, domain); } pDistribFun->PriorToCPD(); } } else { float **evid = NULL; float **full_evid = NULL; BuildFullEvidenceMatrix(&full_evid); CSoftMaxCPD* SoftMaxFactor = (CSoftMaxCPD*)iCPD; SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, &evid,vFamily, m_Vector_pEvidences.size()); SoftMaxFactor->InitLearnData(); SoftMaxFactor->SetMaximizingMethod(mmGradient); SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(), 0.00001f, 0.01f); SoftMaxFactor->CopyLearnDataToDistrib(); for (int k = 0; k < SoftMaxFactor->GetDomainSize(); k++) { delete [] evid[k]; } delete [] evid; int i; intVector obsNodes; (m_Vector_pEvidences[0])->GetAllObsNodes(&obsNodes); for (i=0; i<obsNodes.size(); i++) { delete [] full_evid[i]; } delete [] full_evid; }; return iCPD; }
float CMlStaticStructLearn::ComputeFamilyScore(intVector vFamily) { int nFamily = vFamily.size(); CCPD* iCPD = this->CreateRandomCPD(nFamily, &vFamily.front(), m_pGrModel); CTabularDistribFun *pDistribFun; int ncases = m_Vector_pEvidences.size(); const CEvidence * pEv; float score; float pred = 0; EDistributionType NodeType; switch (m_ScoreMethod) { case MaxLh : if ( !((iCPD->GetDistribFun()->GetDistributionType() == dtSoftMax) || (iCPD->GetDistribFun()->GetDistributionType() == dtCondSoftMax))) { iCPD->UpdateStatisticsML( &m_Vector_pEvidences.front(), ncases ); score = iCPD->ProcessingStatisticalData(ncases); } else { float **evid = NULL; float **full_evid = NULL; BuildFullEvidenceMatrix(&full_evid); CSoftMaxCPD* SoftMaxFactor = static_cast<CSoftMaxCPD*>(iCPD); SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, &evid, vFamily,m_Vector_pEvidences.size()); SoftMaxFactor->InitLearnData(); SoftMaxFactor->SetMaximizingMethod(mmGradient); SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(), 0.00001f, 0.01f); SoftMaxFactor->CopyLearnDataToDistrib(); if (SoftMaxFactor->GetDistribFun()->GetDistributionType() == dtSoftMax) { score = ((CSoftMaxDistribFun*)SoftMaxFactor->GetDistribFun())->CalculateLikelihood(evid,ncases); } else { score = ((CCondSoftMaxDistribFun*)SoftMaxFactor->GetDistribFun())->CalculateLikelihood(evid,ncases); }; for (int k = 0; k < SoftMaxFactor->GetDomainSize(); k++) { delete [] evid[k]; } delete [] evid; int i; intVector obsNodes; (m_Vector_pEvidences[0])->GetAllObsNodes(&obsNodes); for (i=0; i<obsNodes.size(); i++) { delete [] full_evid[i]; } delete [] full_evid; }; break; case PreAs : int i; NodeType = iCPD->GetDistributionType(); switch (NodeType) { case dtTabular : for(i = 0; i < ncases; i++) { pConstEvidenceVector tempEv(0); tempEv.push_back(m_Vector_pEvidences[i]); iCPD->UpdateStatisticsML(&tempEv.front(), tempEv.size()); iCPD->ProcessingStatisticalData(tempEv.size()); pred += log(((CTabularCPD*)iCPD)->GetMatrixValue(m_Vector_pEvidences[i])); } break; case dtGaussian : for(i = 0; i < ncases; i += 1 ) { pConstEvidenceVector tempEv(0); tempEv.push_back(m_Vector_pEvidences[i]); iCPD->UpdateStatisticsML(&tempEv.front(), tempEv.size()); float tmp = 0; if (i != 0) { tmp =iCPD->ProcessingStatisticalData(1); pred +=tmp; } } break; case dtSoftMax: PNL_THROW(CNotImplemented, "This type score method has not been implemented yet"); break; default: PNL_THROW(CNotImplemented, "This type score method has not been implemented yet"); break; }; score = pred; break; case MarLh : { //проверка того, что потенциал дискретный if (iCPD->GetDistributionType() != dtTabular) { PNL_THROW(CNotImplemented, "This type of score method has been implemented only for discrete nets"); } int DomainSize; const int * domain; switch(m_priorType) { case Dirichlet: iCPD->GetDomain(&DomainSize, &domain); pDistribFun = static_cast<CTabularDistribFun *>(iCPD->GetDistribFun()); pDistribFun->InitPseudoCounts(); for (i=0; i<ncases; i++) { pEv = m_Vector_pEvidences[i]; const CEvidence *pEvidences[] = { pEv }; pDistribFun->BayesUpdateFactor(pEvidences, 1, domain); } score = pDistribFun->CalculateBayesianScore(); break; case K2: iCPD->GetDomain(&DomainSize, &domain); pDistribFun = static_cast<CTabularDistribFun *>(iCPD->GetDistribFun()); pDistribFun->InitPseudoCounts(m_K2alfa); for (i=0; i<ncases; i++) { pEv = m_Vector_pEvidences[i]; const CEvidence *pEvidences[] = { pEv }; pDistribFun->BayesUpdateFactor(pEvidences, 1, domain); } score = pDistribFun->CalculateBayesianScore(); break; case BDeu: iCPD->GetDomain(&DomainSize, &domain); pDistribFun = static_cast<CTabularDistribFun *>(iCPD->GetDistribFun()); pDistribFun->InitPseudoCounts(); for (i=0; i<ncases; i++) { pEv = m_Vector_pEvidences[i]; const CEvidence *pEvidences[] = { pEv }; pDistribFun->BayesUpdateFactor(pEvidences, 1, domain); } score = pDistribFun->CalculateBayesianScore() / iCPD->GetNumberOfFreeParameters(); break; default: PNL_THROW(CNotImplemented, "This type of prior has not been implemented yet"); break; } break; } default : PNL_THROW(CNotImplemented, "This type score method has not been implemented yet"); break; } int dim = iCPD->GetNumberOfFreeParameters(); switch (m_ScoreType) { case BIC : score -= 0.5f * float(dim) * float(log(float(ncases))); break; case AIC : score -= 0.5f * float(dim); break; case WithoutFine: break; case VAR : PNL_THROW(CNotImplemented, "This type score function has not been implemented yet"); break; default: PNL_THROW(CNotImplemented, "This type score function has not been implemented yet"); break; } delete iCPD; return score; }