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)?
Réponses:
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.
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.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:
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.
la source
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.
la source