Learning (Parameter Learning)


Il Parameter Learning è un processo che permette di apprendere le probabilità dei fatti da dati osservati, senza doverle definire manualmente. È il meccanismo che trasforma un programma probabilistico in un modello guidato dai dati.
Il cuore del learning in ProbLog è il predicato t() che rende un fatto "apprendibile"; il motore del learning è un algoritmo Expectation-Maximization (EM), chiamato Learning From Interpretations (LFI).
Definendo i fatti in un programma per il learning si può scegliere tra le seguenti modalità:

Si provi questo primo esempio nell'editor on line selezionando il modello Learning e inserendo prima il programma

% Fatti apprendibili: probabilità che ogni moneta dia testa t(_)::heads(c1). t(_)::heads(c2). t(_)::heads(c3). % Regole per definire eventi complessi (opzionali) two_heads :- heads(c1), heads(c2). all_heads :- heads(c1), heads(c2), heads(c3).
e quindi negli Examples i seguenti dati osservati.
% Lancio 1: c1 e c3 danno testa, c2 dà croce evidence(heads(c1), true). evidence(heads(c3), true). evidence(heads(c2), false). --- % Lancio 2: solo c2 dà testa evidence(heads(c2), true). evidence(heads(c1), false). evidence(heads(c3), false). --- % Lancio 3: tutte e tre danno testa evidence(all_heads, true). --- % Lancio 4: nessuna dà testa evidence(heads(c1), false). evidence(heads(c2), false). evidence(heads(c3), false). --- % Lancio 5: c1 e c2 danno testa, c3 no evidence(heads(c1), true). evidence(heads(c2), true). evidence(heads(c3), false). --- % Lancio 6: solo c3 dà testa evidence(heads(c3), true). evidence(heads(c1), false). evidence(heads(c2), false). --- % Lancio 7: c1 e c3 danno testa evidence(heads(c1), true). evidence(heads(c3), true). evidence(heads(c2), false). --- % Lancio 8: due testa evidence(two_heads, true). --- % Lancio 9: tutte danno testa evidence(all_heads, true). --- % Lancio 10: solo c1 dà testa evidence(heads(c1), true). evidence(heads(c2), false). evidence(heads(c3), false).

Un primo semplice esempio da far girare in Python è il seguente.

from problog.logic import Term from problog.program import PrologString from problog.learning import lfi model = r""" % Fatti apprendibili: probabilità che la moneta dia testa t(_)::heads. """ # Definizione dei termini heads = Term('heads') examples = [ [(heads, False)], [(heads, False)], [(heads, True)], [(heads, False)], [(heads, False)], [(heads, False)], [(heads, False)], [(heads, False)], [(heads, True)], [(heads, False)] ] score, weights, atoms, iteration, lfi_problem = lfi.run_lfi(PrologString(model), examples, max_iter=50) print (lfi_problem.get_model())
0.2::heads.

L'esempio proposto per primo in questa pagina, nell'ambiente gestito da Python sarà descritto nel modo seguente.

model = r""" %Fatti apprendibili: probabilità che ogni moneta dia testa t(_)::heads(c1). t(_)::heads(c2). t(_)::heads(c3). % Regole per definire eventi complessi (opzionali) two_heads :- heads(c1), heads(c2). all_heads :- heads(c1), heads(c2), heads(c3). """ # Definizione di termini relativi alle monete per un utilizzo più semplice heads_c1 = Term('heads', Term('c1')) heads_c2 = Term('heads', Term('c2')) heads_c3 = Term('heads', Term('c3')) two_heads = Term('two_heads') all_heads = Term('all_heads') examples = [ [(heads_c1, True), (heads_c3, True), (heads_c2, False)], [(heads_c2, True), (heads_c1, False), (heads_c3, False)], [(all_heads, True)], [(heads_c1, False), (heads_c2, False), (heads_c3, False)], [(heads_c1, True), (heads_c2, True), (heads_c3, False)], [(heads_c3, True), (heads_c1, False), (heads_c2, False)], [(heads_c1, True), (heads_c3, True), (heads_c2, False)], [(two_heads, True)], [(all_heads, True)], [(heads_c1, True), (heads_c2, False), (heads_c3, False)] ] score, weights, atoms, iteration, lfi_problem = lfi.run_lfi(PrologString(model), examples, max_iter=5000) print (lfi_problem.get_model()) prog = lfi_problem.get_model()+""" query(two_heads). query(all_heads). """ run(PrologString(prog))
0.7::heads(c1). 0.5::heads(c2). 0.555555555555556::heads(c3). two_heads :- heads(c1), heads(c2). all_heads :- heads(c1), heads(c2), heads(c3). {two_heads: 0.3499999999999999, all_heads: 0.1944444444444446}
La classe Term in ProbLog, importata da problog.logic rappresenta un termine della logica del primo ordine.

Il seguente è un altro esempio.

model = r""" t(0.5)::burglary. 0.2::earthquake. t(_)::p_alarm1. t(_)::p_alarm2. t(_)::p_alarm3. alarm :- burglary, earthquake, p_alarm1. alarm :- burglary, \+earthquake, p_alarm2. alarm :- \+burglary, earthquake, p_alarm3. """ alarm = Term('alarm') burglary = Term('burglary') earthquake = Term('earthquake') examples = [ [(burglary, False), (alarm, False)], [(earthquake, False), (alarm, True), (burglary, True)], [(burglary, False)] ] score, weights, atoms, iteration, lfi_problem = lfi.run_lfi(PrologString(model), examples) print (lfi_problem.get_model())
0.333333333333333::burglary. 0.2::earthquake. 0.220226823615252::p_alarm1. 1.0::p_alarm2. 0.0::p_alarm3. alarm :- burglary, earthquake, p_alarm1. alarm :- burglary, \+earthquake, p_alarm2. alarm :- \+burglary, earthquake, p_alarm3.
e quindi
prog = lfi_problem.get_model()+""" query(alarm). """ run(PrologString(prog))
{alarm: 0.3068552187773007}