Реализация распространения убеждений
Я пытаюсь реализовать Байесовские сети.
Мой основной график - это факторный график, который я хочу использовать для распространения убеждений. Но при распространении убеждений при вычислении сообщений не все аргументы передаются в функцию, и конечная функция будет ограничением совместного распространения.
Лучший способ, который приходит мне в голову, - это как-то ограничить функции, чтобы не выполнять всю замену каждый раз, когда я хочу вычислить маржинальное значение для нового значения.
Я спросил, как реализовать такую функцию здесь.
Я хочу знать, есть ли лучший способ сделать такую вещь или есть более простые и быстрые подходы, чем тот, который я хочу сделать.
1 ответ
Вот предложение: создайте замыкание, которое принимает карту, содержащую исходные переменные и их соответствующие значения, в качестве пар ключ-значение для первого вычисления. Это же замыкание возвращает внутреннюю функцию, которая принимает другую карту с оставшимися переменными и значениями для окончательного вычисления.
Итак, определите замыкание, где первое частичное вычисление выполняется во внешней функции. Основываясь на вашей ссылке, частичное вычисление является суммой, но я думаю, что вы будете вычислять произведения вероятностей. Внутренняя функция имеет доступ к частичной сумме как свободная переменная. Вычисление завершается, когда вы вызываете его с картой, содержащей оставшиеся пары переменная-значение.
Вы также можете определить во внешней функции набор для хранения всех переменных, использованных в первом вычислении. Затем разрешите внутренней функции также обращаться к этому набору в качестве свободной переменной. Это обеспечит исключение значений любых переменных ключей, встречающихся в первом вычислении, в окончательном вычислении.
Все это проиллюстрировано ниже.
def f1(map1):
# set to contain seen variables as keys
seen_keys = set()
computed_val1 = 0.0
for key in map1.keys():
val = map1[key]
computed_val1 += val
# remember keys already in 1st computed
seen_keys.add(key)
def f2(map2):
computed_val2 = computed_val1
for key2 in map2.keys():
# omit keys in first computation
if key2 in seen_keys:
continue
val2 = map2[key2]
computed_val2 += val2
return computed_val2
return f2
if __name__ == '__main__':
partial_map = {'factor1': 1, 'factor2': 2}
func = f1(partial_map)
remaining_map1 = {'factor3': 3}
answer1A = func(remaining_map1)
print "Answer after using partial and remaining maps = ", answer1A
# complete the partial map with factor3 to show that
# the return function will ignore variables already seen in 1st computaion
partial_map['factor3'] = 3
answer1B = func(partial_map)
print "Answer with completed map to same func = ", answer1B
# Compute remaining map with different value for factor 3
remaining_map2 = {'factor3': 15}
answer2 = func(remaining_map2)
print "Answer with different second map = ", answer2