Hay que implementar varias cosas para family_score funcione con un número arbitrario de padres. Según lo que pone en la página 818 de Koller, el cambio del score actual al añadir un arco from -> to es:
donde parents son las predictoras padres de to en el grafo actual. La función tiene tres argumentos: family_score(x, y, dataset). El family_score puede ser la log verosimilitud, el BIC o el AIC. En base a la página 805 de Koller, la log verosimilitud es
`loglik(x, y, dataset) = N · (mutual_information(x; y) − entropy(x)).`
El BIC y el AIC entonces serían:
BIC(x, y, dataset) = N · (mutual_information(x; y) − entropy(x)) - log(N) / 2 * df.
AIC(x, y, dataset) = N · (mutual_information(x; y) − entropy(x)) - df.
Para que esto se pueda calcular, hay que calcular mutual_information(x; y), entropy(x) y df (degrees of freedom). entropy(x) es fácil: utilizaentropy::entropy(xyz_freqs, method = "ML", unit = unit, verbose = F) (ver la función cmi_table()). Para df hay que adaptar la función cmi_degrees_of_freedom para que acepte matrices con mas de 3 dimensiones dimensiones. La formula es análoga y, por eficiencia, yo lo dejaría como:
Finalmente, hay que calcular mutual_information(x; y), donde y puede ser un vector de variables. Para ello hay que tomar en cuenta todas las posibles combinaciones de los padres, y. Para cada posible combinación, a, se calcula la entropía empírica de x filtrando los casos donde y == a y se multiplica por la probabilidad empírica de a. Finalmente se suma todo lo obtenido.
La manera más fácil de comprobar que se ha implementado correctamente es comparar el BIC(x, dataset) de un naive Bayes o un ODE con lo que se obtiene con los family_score().
Hay que implementar varias cosas para family_score funcione con un número arbitrario de padres. Según lo que pone en la página 818 de Koller, el cambio del score actual al añadir un arco
from -> to
es:delta score = family_score(to, c(from, parents, class), dataset) - family_score(to, c(parents, class), dataset)
donde parents son las predictoras padres de to en el grafo actual. La función tiene tres argumentos:
family_score(x, y, dataset)
. El family_score puede ser la log verosimilitud, el BIC o el AIC. En base a la página 805 de Koller, la log verosimilitud esEl BIC y el AIC entonces serían:
Para que esto se pueda calcular, hay que calcular
mutual_information(x; y), entropy(x) y df
(degrees of freedom).entropy(x)
es fácil: utilizaentropy::entropy(xyz_freqs, method = "ML", unit = unit, verbose = F)
(ver la funcióncmi_table()
). Paradf
hay que adaptar la funcióncmi_degrees_of_freedom
para que acepte matrices con mas de 3 dimensiones dimensiones. La formula es análoga y, por eficiencia, yo lo dejaría como:Finalmente, hay que calcular
mutual_information(x; y)
, donde y puede ser un vector de variables. Para ello hay que tomar en cuenta todas las posibles combinaciones de los padres,y
. Para cada posible combinación,a
, se calcula la entropía empírica de x filtrando los casos dondey == a
y se multiplica por la probabilidad empírica de a. Finalmente se suma todo lo obtenido.La manera más fácil de comprobar que se ha implementado correctamente es comparar el
BIC(x, dataset)
de un naive Bayes o un ODE con lo que se obtiene con losfamily_score
().