int testSetStatistics() { int ret = TRS_OK; float eps = 0.1f; int seed = pnlTestRandSeed(); pnlSeed( seed ); CBNet *pBNet = pnlExCreateCondGaussArBNet(); CModelDomain *pMD = pBNet->GetModelDomain(); CGraph *pGraph = CGraph::Copy(pBNet->GetGraph()); CBNet *pBNet1 = CBNet::CreateWithRandomMatrices( pGraph, pMD ); pEvidencesVector evidences; int nEvidences = pnlRand( 3000, 4000); pBNet->GenerateSamples( &evidences, nEvidences ); int i; for( i = 0; i < nEvidences; i++) { //evidences[i]->MakeNodeHiddenBySerialNum(0); } CEMLearningEngine *pLearn = CEMLearningEngine::Create(pBNet1); pLearn->SetData( nEvidences, &evidences.front() ); pLearn->SetMaxIterEM(); pLearn->Learn(); for( i = 0; i < pBNet->GetNumberOfFactors(); i++ ) { if( ! pBNet->GetFactor(i)->IsFactorsDistribFunEqual(pBNet1->GetFactor(i), eps)) { ret = TRS_FAIL; pBNet->GetFactor(i)->GetDistribFun()->Dump(); pBNet1->GetFactor(i)->GetDistribFun()->Dump(); } } CDistribFun *pDistr; const CMatrix<float>* pMat; CFactor *pCPD; pDistr = pBNet1->GetFactor(0)->GetDistribFun(); pMat = pDistr->GetStatisticalMatrix(stMatTable); pCPD = pBNet->GetFactor(0); pCPD->SetStatistics(pMat, stMatTable); pCPD->ProcessingStatisticalData(nEvidences); if( ! pCPD->IsFactorsDistribFunEqual(pBNet1->GetFactor(0), 0.0001f) ) { ret = TRS_FAIL; } pDistr = pBNet1->GetFactor(1)->GetDistribFun(); int parentVal; pCPD = pBNet->GetFactor(1); parentVal = 0; pCPD->SetStatistics(pMat, stMatCoeff); pMat = pDistr->GetStatisticalMatrix(stMatMu, &parentVal); pCPD->SetStatistics(pMat, stMatMu, &parentVal); pMat = pDistr->GetStatisticalMatrix(stMatSigma, &parentVal); pCPD->SetStatistics(pMat, stMatSigma, &parentVal); parentVal = 1; pMat = pDistr->GetStatisticalMatrix(stMatMu, &parentVal); pCPD->SetStatistics(pMat, stMatMu, &parentVal); pMat = pDistr->GetStatisticalMatrix(stMatSigma, &parentVal); pCPD->SetStatistics(pMat, stMatSigma, &parentVal); pCPD->ProcessingStatisticalData(nEvidences); if( ! pCPD->IsFactorsDistribFunEqual(pBNet1->GetFactor(1), eps) ) { ret = TRS_FAIL; } for( i = 0; i < nEvidences; i++) { delete evidences[i]; } delete pLearn; delete pBNet1; delete pBNet; return trsResult( ret, ret == TRS_OK ? "No errors" : "Bad test on SetStatistics"); }
bool CStaticStructLearnSEM::LearnOneStep() { intVecVector decompsition; CGraph* graph = m_pCurrBNet->GetGraph(); graph->GetConnectivityComponents( &decompsition ); CEMLearningEngine* pEMLearn; if(decompsition.size() > 1) { CExInfEngine< CJtreeInfEngine, CBNet, PNL_EXINFENGINEFLAVOUR_DISCONNECTED > *pInf = CExInfEngine< CJtreeInfEngine, CBNet, PNL_EXINFENGINEFLAVOUR_DISCONNECTED >:: Create( m_pCurrBNet ); pEMLearn = CEMLearningEngine::Create(m_pCurrBNet, pInf); } else { CJtreeInfEngine *pInf = CJtreeInfEngine::Create(m_pCurrBNet); pEMLearn = CEMLearningEngine::Create(m_pCurrBNet, pInf); } int i; for(i=0; i<decompsition.size(); i++) decompsition[i].clear(); decompsition.clear(); ConvertToCurrEvidences(m_pCurrBNet); pEMLearn->SetData(m_numberOfAllEvidences, &m_vCurrEvidences.front()); pEMLearn->SetMaxIterEM(m_IterEM); // pEMLearn->ClearStatisticData(); pCPDVector vNeighborCPDs; floatVector vNeighborLLs; EDGEOPVECTOR vValidMoves; intVector vRevCorrespDel; CreateNeighborCPDs(m_pCurrBNet, &vNeighborCPDs, &vValidMoves, &vRevCorrespDel); pEMLearn->LearnExtraCPDs(m_nMaxFanIn+1, &vNeighborCPDs, &vNeighborLLs); // m_pCurrBNet = static_cast<CBNet*>(pEMLearn->GetStaticModel()); const float* familyLL = pEMLearn->GetFamilyLogLik(); floatVector familyScores(m_nNodes,0); int j, freeparams; float logebase = (float)log(float(m_numberOfAllEvidences)); float total_score = 0.0f; CFactor* pCPD; for(i=0; i<m_nNodes; i++) { pCPD = m_pCurrBNet->GetFactor(i); freeparams = pCPD->GetNumberOfFreeParameters(); familyScores[i] = familyLL[i] - 0.5f * float(freeparams) * logebase; total_score += familyScores[i]; } int nMoves = vValidMoves.size(); floatVector neighborScores(nMoves, 0); for(i=0; i<nMoves; i++) { pCPD = static_cast<CFactor*>(vNeighborCPDs[i]); freeparams = pCPD->GetNumberOfFreeParameters(); neighborScores[i] = vNeighborLLs[i] - 0.5f * float(freeparams) * logebase; } int start, end, max_position=0; float tmp_score, best_score = -1e37f; EDGEOP move; for(i=0; i<nMoves; i++) { move = vValidMoves[i]; switch (move.DAGChangeType) { case DAG_DEL : end = move.originalEdge.endNode; tmp_score = neighborScores[i] - familyScores[end]; if( best_score<tmp_score ) { best_score = tmp_score; max_position = i; } break; case DAG_ADD : end = move.originalEdge.endNode; tmp_score = neighborScores[i] - familyScores[end]; if( best_score<tmp_score ) { best_score = tmp_score; max_position = i; } break; case DAG_REV : end = move.originalEdge.startNode; tmp_score = neighborScores[i] - familyScores[end]; end = move.originalEdge.endNode; tmp_score += neighborScores[vRevCorrespDel[i]] - familyScores[end]; if( best_score<tmp_score ) { best_score = tmp_score; max_position = i; } break; } } move = vValidMoves[max_position]; start = move.originalEdge.startNode; end = move.originalEdge.endNode; EDAGChangeType changeType = move.DAGChangeType; CCPD *addCPD=0, *delCPD=0; switch (changeType) { case DAG_DEL : delCPD = static_cast<CCPD*>((vNeighborCPDs[max_position])->Clone()); break; case DAG_ADD : addCPD = static_cast<CCPD*>((vNeighborCPDs[max_position])->Clone()); break; case DAG_REV : addCPD = static_cast<CCPD*>((vNeighborCPDs[max_position])->Clone()); delCPD = static_cast<CCPD*>((vNeighborCPDs[vRevCorrespDel[max_position]])->Clone()); break; } delete pEMLearn; for(i=0; i<vNeighborCPDs.size(); i++) { delete vNeighborCPDs[i]; } vNeighborCPDs.clear(); for(i=0; i<m_numberOfAllEvidences; i++) { delete m_vCurrEvidences[i]; } m_vCurrEvidences.clear(); vValidMoves.clear(); float score_gate = (float)fabs(m_minProgress * total_score); if(best_score <= score_gate) { if(changeType == DAG_REV) { delete addCPD; delete delCPD; } if(changeType == DAG_ADD)delete addCPD; if(changeType == DAG_DEL)delete delCPD; return false; } total_score += best_score; CDAG* pDAG = CDAG::Create(*(m_pCurrBNet->GetGraph())); int node, node1, newnode; if(!(pDAG->DoMove(start, end, changeType))) { PNL_THROW(CInternalError, "There are some internal errors"); } intVector vRenaming, Old2New; CDAG* iDAG; int TopologicSorted = pDAG->IsTopologicallySorted(); if( TopologicSorted ) { iDAG = pDAG->Clone(); for(i=0; i<m_nNodes; i++) vRenaming.push_back(i); } else iDAG = pDAG->TopologicalCreateDAG(vRenaming); pDAG->Dump(); intVector gRename; for(i=0; i<m_nNodes; i++) { node = vRenaming[i]; node1 = m_vGlobalRenaming[node]; gRename.push_back(node1); } m_vGlobalRenaming.assign(gRename.begin(), gRename.end()); int pos; for(i=0; i<m_nNodes; i++) { pos = std::find(vRenaming.begin(), vRenaming.end(), i) - vRenaming.begin(); Old2New.push_back(pos); } const int* oldNodeAsso = m_pCurrBNet->GetNodeAssociations(); intVector newNodeAsso(m_nNodes,0); for(i=0; i<m_nNodes; i++) { newNodeAsso[i] = oldNodeAsso[vRenaming[i]]; } nodeTypeVector vpnt; m_pCurrBNet->GetNodeTypes(&vpnt); CBNet* pBNet = CBNet::Create(m_nNodes, vpnt.size(), &vpnt.front(), &newNodeAsso.front(), static_cast<CGraph*>(iDAG)); CModelDomain* pMDnew = pBNet->GetModelDomain(); pBNet->AllocFactors(); intVector domainNew, domainOld; const CFactor* factor=0; CFactor* curFactor; for(i=0; i<m_nNodes; i++) { domainNew.clear(); newnode = Old2New[i]; if( (i != start) && (i != end) ) { factor = m_pCurrBNet->GetFactor(i); } else { if(changeType == DAG_REV) { if(i == start) factor = addCPD->Clone(); if(i == end) factor = delCPD->Clone(); } if(changeType == DAG_DEL) { if(i == start) factor = m_pCurrBNet->GetFactor(i); if(i == end) factor = delCPD->Clone(); } if(changeType == DAG_ADD) { if(i == start) factor = m_pCurrBNet->GetFactor(i); if(i == end) factor = addCPD->Clone(); } } factor->GetDomain(&domainOld); for(j=0; j<domainOld.size(); j++) { domainNew.push_back(Old2New[domainOld[j]]); } curFactor = CFactor::CopyWithNewDomain(factor, domainNew, pMDnew); pBNet->AttachFactor(curFactor); } if(changeType == DAG_REV) { delete addCPD; delete delCPD; } if(changeType == DAG_ADD)delete addCPD; if(changeType == DAG_DEL)delete delCPD; delete m_pCurrBNet; delete pDAG; m_pCurrBNet = pBNet; m_critValue.push_back(total_score); return true; }