Quelle combinaison de structures de données stocke efficacement les réseaux bayésiens discrets?

22

Je comprends la théorie derrière les réseaux bayésiens et je me demande ce qu'il faut pour en construire un en pratique. Disons pour cet exemple, que j'ai un réseau bayésien (dirigé) de 100 variables aléatoires discrètes; chaque variable peut prendre jusqu'à 10 valeurs.

Est-ce que je stocke tous les nœuds dans un DAG et pour chaque nœud stocke sa table de probabilité conditionnelle (CPT)? Existe-t-il d'autres structures de données que je devrais utiliser pour assurer un calcul efficace des valeurs lorsque certains CPT changent (en dehors de ceux utilisés par un DAG)?

cendre
la source
J'utilise en mémoire une base de données sqlite pour stocker des tables CP, car les bases de données devraient avoir des algorithmes et des structures de données efficaces pour gérer les tables. Fonctionne bien! :)
Pratik Deoghare
Veuillez définir ce que vous entendez par efficace (mémoire, performances, etc.) et inclure vos contraintes. Sans ceux-ci, cela pourrait facilement aboutir à un concours pour le plus efficace qui se dégraderait en code cryptique auquel je n'aurais jamais dû faire face dans le travail quotidien.
Justin Bozonier
1
@JustinBozonier nécessite moins de mémoire et est rapide?
Pratik Deoghare

Réponses:

12

La "meilleure" structure de données dépend probablement du problème particulier que vous essayez de résoudre avec. Voici une approche que j'ai vue (et que j'ai utilisée moi-même), qui stocke simplement toutes les informations et laisse à l'algorithme le soin d'en faire.

  1. Vous indexez d'abord les nœuds par des entiers uniques, de 0 à n-1. Ensuite, vous stockez simplement, pour chaque nœud, la liste de ses parents sous la forme d'un tableau d'entiers --- en C ++, par exemple, vous pouvez avoir un std::vector<std::vector<int> >: premier vecteur sur les nœuds, le deuxième vecteur répertorie les parents respectifs). Cela capture toute la structure DAG.

  2. De plus, étant donné que chaque nœud a exactement une table de probabilité conditionnelle qui lui est associée, vous pouvez indexer ceux ayant les mêmes ID entiers. Pour chaque table de probabilités, vous devez stocker sa portée, c'est-à-dire l'ensemble de variables aléatoires qui lui est défini. Deuxièmement, vous auriez probablement une grande liste de nombres à virgule flottante qui contient les probabilités conditionnelles réelles (et vous voudrez vous assurer d'obtenir l'indexation correcte). Pour donner à nouveau un exemple C ++, quelque chose comme ceci pourrait faire:

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

    Avec cela, vous pouvez utiliser un std::vector<CondProbTable>pour stocker tous vos CPT.

Encore une fois, cela ne stocke que le réseau Bayes, il ne suppose rien de ce que vous voulez en faire. L'inclusion de la portée CPT dans CondProbTable est quelque peu redondante, car elle pourrait être déduite de la liste des nœuds parents décrite au point 1.

lot
la source
0

Les CPT fondamentalement discrets sont des hypermatrices, et vous devriez les regarder de cette façon.

Une façon assez courante de représenter une hypermatrix consiste à utiliser une table de hachage à l'aide d'un index de chaîne. par exemple en 2 dimensions t [1] [2] serait t.get ("1_2")

Une solution plus efficace en mémoire est possible: si l'hypermatrix est clairsemée, vous pouvez utiliser une représentation clairsemée spéciale (par exemple, Fuchs 72), si elle a une structure, vous pouvez utiliser ADD (diagramme de décision algèbre) ou des règles logiques.

Votre dernière question n'est pas très claire, cependant si vous vous attendez à ce que votre CPT change souvent, vous serez probablement mieux avec une représentation plate du CPT avec une table ou une table de hachage.

Nicolas
la source