Как реализовать алгоритм перечисления для сети Байеса, учитывая конкретный ввод?

#python #algorithm #bayesian-networks

#python #алгоритм #байесовские сети

Вопрос:

Я только начал изучать сети Байеса и пытался реализовать их на Python.

Идея заключается в том, чтобы, получив конкретный ввод из файла, который содержит узлы сети и таблицы распределения вероятностей для каждого узла, выполнить запрос, заданный в виде строки, применить алгоритм перечисления и вывести результат для этого запроса. Форматы следующие:

 [Nodes]
Burglary, Earthquake, Alarm, JohnCalls, MaryCalls

[Probabilities]
 Burglary = 0.001
 Earthquake = 0.002
 Alarm| Earthquake, Burglary = 0.95
 Alarm|-Earthquake,  Burglary = 0.94
 Alarm| Earthquake, -Burglary = 0.29
 Alarm|-Earthquake, -Burglary = 0.001
 JohnCalls| Alarm = 0.9
 JohnCalls|-Alarm = 0.05
 MaryCalls| Alarm = 0.7
 MaryCalls|-Alarm = 0.01

[Queries]
 Burglary| Earthquake,  JohnCalls
 Earthquake
-MaryCalls| Earthquake,  Alarm
 JohnCalls|-Earthquake, -MaryCalls,  Burglary
-Alarm|-Earthquake, -MaryCalls,  Burglary
-Alarm,  JohnCalls|-Earthquake, -MaryCalls,  Burglary
  

До сих пор мне удавалось анализировать этот текстовый файл и создавать:

  • список всех узлов, называемых сетью
  • список со всеми запросами в виде строк
  • класс узла, который включает заголовок, список родительских узлов и словарь для таблицы распределения вероятностей

Проблема в том, что я понятия не имею, как продолжить отсюда. Я знаю, как работает алгоритм, но у меня возникают большие проблемы с отображением его в коде.

Способ работы алгоритма заключается в следующем: https://www.youtube.com/watch?v=q5DHnmHtVmc

Какова может быть возможная реализация в Python для этого алгоритма? Где я могу найти хороший пример python этого алгоритма? Я искал в Google, но я нахожу большинство примеров и предложений алгоритмов слишком сложными для новичка в этой теме.

Вот код, который у меня есть на данный момент:

 import copy
import fileinput

network = [] #Network is a list of all the nodes
queries = [] #List of all the required queries
allProbs = {} #List with all the propabilities, given or calculated

class Node:
    def __init__(self, title, parents, pdt):
        self.title = title #String that identifies the node
        self.parents = parents #List of nodes that are parents of this node
        self.pdt = pdt #Dictionary where { ' title': value, '-title': value }

def readInput():
    input = fileinput.input()
    operation = 0
    for line in input:
        line = line.rstrip('n').rstrip('r')
        #Parsing the line that contains the nodes
        if operation is 1 and "[Probabilities]" not in line and "[Queries]" not in line and line is not "" and line is not "n":
            nodes = line.split(',')
            for element in nodes:
                node = Node(element.replace(" ", ""), [], {})
                network.append(node);
        #Parsing the lines that contain the propabilities
        if operation is 2 and "[Probabilties]" not in line and "[Queries]" not in line and line is not "" and line is not "n":
            lineAux = line.replace(" ", "").split("=")
            nodes = lineAux[0].split("|")
            queryNode = nodes[0].strip(" ")
            #Finding and assigning parent nodes to each node, based on the evidence nodes of the probabilities
            if len(nodes) > 1:
                evidenceNodes = nodes[1].split(",")
                for element in evidenceNodes:
                    rawElement = element.strip(" ").strip("-")
                    for node in network:
                        if node.title == queryNode:
                            alreadyInList = False
                            if len(node.parents) > 0:
                                for parent in node.parents:
                                    if parent.title == rawElement:
                                        alreadyInList = True
                                if not alreadyInList:
                                    for parentNode in network:
                                        if parentNode.title == rawElement:
                                            node.parents.append(parentNode)
                            else:
                                for parentNode in network:
                                    if parentNode.title == rawElement:
                                        node.parents.append(parentNode)
            #Assigning the Probability to the correct node
            for node in network:
                if node.title == queryNode:
                    node.pdt[lineAux[0]] = float(lineAux[1])
                    node.pdt["-"   lineAux[0].strip(" ")] = round(1.0 - float(lineAux[1]), 7)
        #Handling what to do based on the value of the line
        if "[Nodes]" in line:
            operation = 1
        if "[Probabilities]" in line:
            operation = 2
        if "[Queries]" in line:
            operation = 3

readInput()
for node in network:
    print("------------------------")
    print(node.title)
    print(node.pdt)
  

Я знаю, что это может быть не самый эффективный код, но сейчас я просто хочу найти решение, которое работает, а затем проблемы с оптимизацией.

Заранее спасибо!