Quale combinazione di strutture dati memorizza in modo efficiente reti bayesiane discrete?


22

Comprendo la teoria alla base delle reti bayesiane e mi chiedo cosa serve per costruirne una in pratica. Diciamo per questo esempio che ho una rete bayesiana (diretta) di 100 variabili casuali discrete; ogni variabile può assumere uno di massimo 10 valori.

Conservo tutti i nodi in un DAG e per ciascun nodo memorizzo la sua tabella di probabilità condizionale (CPT)? Esistono altre strutture di dati da utilizzare per garantire un calcolo efficiente dei valori quando cambiano alcuni CPT (a parte quelli utilizzati da un DAG)?


Sto usando nel database sqlite di memoria per l'archiviazione di tabelle CP, poiché i DB dovrebbero avere algoritmi e strutture dati efficienti per gestire le tabelle. Funziona bene! :)
Pratik Deoghare

Definisci cosa intendi per efficiente (memoria, prestazioni, ecc.) E includi i tuoi vincoli. Senza quelli questo potrebbe facilmente finire per un concorso per il più efficiente che si degraderà al codice criptico che non avrei mai avuto a che fare con il lavoro quotidiano.
Justin Bozonier,

1
@JustinBozonier richiede meno memoria ed è veloce?
Pratik Deoghare

Risposte:


12

La "migliore" struttura dei dati dipende probabilmente dal particolare problema che stai cercando di risolvere. Ecco un approccio che ho visto (e che ho usato da solo), che semplicemente memorizza tutte le informazioni e lascia all'algoritmo cosa fare con esso.

  1. Per prima cosa indicizzi i nodi con numeri interi univoci, da 0 a n-1. Quindi semplicemente memorizzi, per ciascun nodo, l'elenco dei suoi genitori come una matrice di numeri interi --- in C ++, ad esempio, potresti avere un std::vector<std::vector<int> >: primo vettore su nodi, secondo vettore elenca i rispettivi genitori). Ciò cattura l'intera struttura del DAG.

  2. Inoltre, poiché a ciascun nodo è associata esattamente una tabella di probabilità condizionale, è possibile indicizzare quelli con gli stessi ID interi. Per ogni tabella di probabilità è necessario memorizzarne l'ambito, ovvero l'insieme di variabili casuali su cui è definito. In secondo luogo, avresti probabilmente un ampio elenco di numeri in virgola mobile che contiene le effettive probabilità condizionali (e vorrai assicurarti di ottenere l'indicizzazione corretta). Per dare nuovamente un esempio in C ++, qualcosa del genere potrebbe fare:

    struct CondProbTable {
        std::vector<int> scope;    // list of random variables the CPT is defined over
        std::vector<double> table; // appropriately sized and indexed table of
                                   // conditional probabilities
    };
    

    Con ciò, puoi utilizzare a std::vector<CondProbTable>per memorizzare tutti i tuoi CPT.

Ancora una volta, questo fondamentalmente memorizza solo la rete Bayes, non presuppone nulla su ciò che si desidera farne. Includere l'ambito CPT in CondProbTable è in qualche modo ridondante, poiché potrebbe essere dedotto dall'elenco dei nodi padre descritto al punto 1.


0

Le CPT sostanzialmente discrete sono ipermatrix e dovresti guardarle in questo modo.

Un modo abbastanza comune per rappresentare una hypermatrix è usare una tabella hash usando l'indice di stringa. ad es. in 2 dimensioni t [1] [2] sarebbe t.get ("1_2")

Sono possibili soluzioni più efficienti in termini di memoria: se l'hypermatrix è sparsa, è possibile utilizzare una rappresentazione sparsa speciale (ad esempio Fuchs 72), se ha struttura è possibile utilizzare ADD (diagramma di decisione algrebraico) o regole basate sulla logica.

La tua ultima domanda non è molto chiara, tuttavia se ti aspettavi che il tuo CPT cambi spesso, probabilmente starai meglio con una rappresentazione piatta del CPT con una tabella o una tabella hash.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.