void CBICLearningEngine::Learn() { CEMLearningEngine *pLearn = NULL; float resultBIC = -FLT_MAX; CBNet *pResultBNet = NULL; intVector resultOrder; pEvidencesVector pEv(m_Vector_pEvidences.size(), NULL ); CModelDomain *pMD = m_pGrModel->GetModelDomain(); int nnodes = m_pGrModel->GetNumberOfNodes(); nodeTypeVector varTypes; pMD->GetVariableTypes(&varTypes); intVector varAss( pMD->GetVariableAssociations(), pMD->GetVariableAssociations() + nnodes ); intVector currentAssociation(nnodes); intVector currentObsNodes(nnodes); int i; for( i = 0; i < nnodes; i++ ) { currentObsNodes[i] = i; } CGraph *pGraph = CGraph::Create(nnodes, NULL, NULL, NULL); CBNet *pBNet; int lineSz = int( nnodes * ( nnodes - 1 ) / 2 ); intVecVector connect; intVector indexes(lineSz, 0); int startNode, endNode; int ind; for( ind = 0; ind < lineSz ; ) { if( indexes[ind] == 1 ) { FindNodesByNumber(&startNode, &endNode, nnodes, ind); pGraph->RemoveEdge(startNode, endNode ); indexes[ind] = 0; ind++; } else { FindNodesByNumber(&startNode, &endNode, nnodes, ind); pGraph->AddEdge(startNode, endNode, 1 ); indexes[ind] = 1; ind = 0; connect.clear(); pGraph->GetConnectivityComponents(&connect); if( connect.size() == 1 ) { do { CGraph *pCopyGraph = CGraph::Copy(pGraph); int j; for( j = 0; j < nnodes; j++ ) { currentAssociation[j] = varAss[currentObsNodes[j]]; } pBNet = CBNet::Create(nnodes, varTypes, currentAssociation, pCopyGraph); pBNet->AllocFactors(); for( j = 0; j < nnodes; j++ ) { pBNet->AllocFactor( j ); pBNet->GetFactor(j)->CreateAllNecessaryMatrices(); } int dimOfModel = DimOfModel(pBNet); int k; for( k = 0; k < pEv.size(); k++ ) { valueVector vls; m_Vector_pEvidences[k]->GetRawData(&vls); pEv[k] = CEvidence::Create( pBNet->GetModelDomain(),currentObsNodes, vls ); } pLearn = CEMLearningEngine::Create(pBNet); pLearn->SetData(pEv.size(), &pEv.front()); pLearn->Learn(); int nsteps; const float *score; pLearn->GetCriterionValue(&nsteps, &score); float log_lik = score[nsteps-1]; float BIC = log_lik - 0.5f*float( dimOfModel*log(float(pEv.size())) ); if( BIC >= resultBIC ) { delete pResultBNet; resultBIC = BIC; m_critValue.push_back(BIC); pResultBNet = pBNet; resultOrder.assign( currentObsNodes.begin(), currentObsNodes.end() ); } else { delete pBNet; } for( k = 0; k < pEv.size(); k++ ) { delete pEv[k]; } delete pLearn; }while(std::next_permutation(currentObsNodes.begin(), currentObsNodes.end())); } } } delete pGraph; m_pResultGrModel = pResultBNet; m_resultRenaming.assign(resultOrder.begin(), resultOrder.end()); }
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; }