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;
}
Esempio n. 2
0
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;
    }

}
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;
}