Sesión 9A#

Factores#

Objetivos:

  • Entender el concepto de factor.

  • Apropiar las operaciones que podemos desarrollar con los factores.

  • Introducción al uso de la librería pgmpy

¿Qué es un factor?#

Un factor es una función o tabla que asigna un número real (no necesariamente una probabilidad) a cada combinación posible de valores de un conjunto de variables aleatorias.

\[ \phi: \mathrm{Val}(X_1, \dots, X_k) \to \mathbb{R}_{\geq 0} \]
  • Su entrada son las variables aleatorias \(X_1, X_2, \ldots, X_k\).

  • Su salida es un número real.

  • El conjunto de variables que se usa se llama alcance (scope):

\[ \text{scope}[\phi] = \{X_1, X_2, \ldots, X_k\} \]

Ejemplos de factores#

  • (a) Distribución conjunta:

Una distribución conjunta es un factor cuyo alcance son todas las variables aleatorias del modelo.

Por ejemplo:

\(P(I,D,G)\)

I

D

G

P(I,D,G)

i0

d0

g0

0.03

i0

d0

g1

0.25

i0

d1

g0

0.1

i0

d1

g1

0.35

i1

d0

g0

0.05

i1

d0

g1

0.15

i1

d1

g0

0.04

i1

d1

g1

0.03

La suma de todas las entradas es 1 — esa es la única diferencia con un factor general. Lo que hace a esto un factor es simplemente que cada entrada es un número real no negativo.

  • (b) Medida sin normalizar:

Partimos de la distribución conjunta P(I, D, G) del inciso anterior y fijamos G = g¹ — nos quedamos solo con las filas donde G toma ese valor:

Por ejemplo:

\(P(I, D, G=g^{1})\)

I

D

\(P(I, D, G=g^{1})\)

i⁰

d⁰

0.25

i⁰

0.35

d⁰

0.15

0.03

  • (c) Distribución condicional (CPD):

Por ejemplo:

\(P(G | I, D)\)

I

D

i⁰

d⁰

0.3

0.4

0.3

i⁰

0.05

0.25

0.7

d⁰

0.9

0.08

0.02

0.5

0.3

0.2

  • (d) Factores generales:

Por ejemplo:

A

B

\(\phi\)

a⁰

b⁰

30

a⁰

5

b⁰

1

10

Operaciones de factores#

1. Producto de factores

\[\phi_1(A, B)\]

A

B

\(\phi_1\)

\(a^0\)

\(b^0\)

5

\(a^0\)

\(b^1\)

8

\(a^1\)

\(b^0\)

1

\(a^1\)

\(b^1\)

0

\(a^2\)

\(b^0\)

3

\(a^2\)

\(b^1\)

9

\[\phi_2(B, C)\]

B

C

\(\phi_2\)

\(b^0\)

\(c^0\)

5

\(b^0\)

\(c^1\)

7

\(b^1\)

\(c^0\)

1

\(b^1\)

\(c^1\)

2

\[\phi_3(A, B, C) = \phi_1(A, B) \times \phi_2(B, C)\]

A

B

C

\(\phi_3\)

\(a^0\)

\(b^0\)

\(c^0\)

\(5\times 5 = 25\)

\(a^0\)

\(b^0\)

\(c^1\)

\(5\times 7 = 35\)

\(a^0\)

\(b^1\)

\(c^0\)

\(8\times 1 = 8\)

\(a^0\)

\(b^1\)

\(c^1\)

\(8\times 2 = 16\)

\(a^1\)

\(b^0\)

\(c^0\)

\(1\times 5 = 5\)

\(a^1\)

\(b^0\)

\(c^1\)

\(1\times 7 = 7\)

\(a^1\)

\(b^1\)

\(c^0\)

\(0\times 1 = 0\)

\(a^1\)

\(b^1\)

\(c^1\)

\(0\times 2 = 0\)

\(a^2\)

\(b^0\)

\(c^0\)

\(3\times 5 = 15\)

\(a^2\)

\(b^0\)

\(c^1\)

\(3\times 7 = 21\)

\(a^2\)

\(b^1\)

\(c^0\)

\(9\times 1 = 9\)

\(a^2\)

\(b^1\)

\(c^1\)

\(9\times 2 = 18\)

# Importamos pgmpy.factors.discrete.DiscreteFactor
from pgmpy.factors.discrete import DiscreteFactor
DiscreteFactor?
# Factores phi1, phi2
phi1 = DiscreteFactor(
    variables=['A', 'B'],
    cardinality=[3,2],
    values=[5,8,1,0,3,9]
)
phi2 = DiscreteFactor(
    variables=['B', 'C'],
    cardinality=[2,2],
    values=[5,7,1,2]
)

Factor: φ₁(A, B)

Variables y cardinalidades:

  • A → 3 valores posibles (a⁰, a¹, a²)

  • B → 2 valores posibles (b⁰, b¹)

Cardinalidad total: 3 × 2 = 6 combinaciones

#print
print(phi1)
+------+------+------------+
| A    | B    |   phi(A,B) |
+======+======+============+
| A(0) | B(0) |     5.0000 |
+------+------+------------+
| A(0) | B(1) |     8.0000 |
+------+------+------------+
| A(1) | B(0) |     1.0000 |
+------+------+------------+
| A(1) | B(1) |     0.0000 |
+------+------+------------+
| A(2) | B(0) |     3.0000 |
+------+------+------------+
| A(2) | B(1) |     9.0000 |
+------+------+------------+

Factor: φ₂(B, C)

Variables y cardinalidades:

  • B → 2 valores posibles (b⁰, b¹)

  • C → 2 valores posibles (c⁰, c¹)

Cardinalidad total: 2 × 2 = 4 combinaciones

#print
print(phi2)
+------+------+------------+
| B    | C    |   phi(B,C) |
+======+======+============+
| B(0) | C(0) |     5.0000 |
+------+------+------------+
| B(0) | C(1) |     7.0000 |
+------+------+------------+
| B(1) | C(0) |     1.0000 |
+------+------+------------+
| B(1) | C(1) |     2.0000 |
+------+------+------------+
# Producto de factores(.product)
phi3 = phi1.product(phi2, inplace=False)
print(phi3)
+------+------+------+--------------+
| C    | A    | B    |   phi(C,A,B) |
+======+======+======+==============+
| C(0) | A(0) | B(0) |      25.0000 |
+------+------+------+--------------+
| C(0) | A(0) | B(1) |       8.0000 |
+------+------+------+--------------+
| C(0) | A(1) | B(0) |       5.0000 |
+------+------+------+--------------+
| C(0) | A(1) | B(1) |       0.0000 |
+------+------+------+--------------+
| C(0) | A(2) | B(0) |      15.0000 |
+------+------+------+--------------+
| C(0) | A(2) | B(1) |       9.0000 |
+------+------+------+--------------+
| C(1) | A(0) | B(0) |      35.0000 |
+------+------+------+--------------+
| C(1) | A(0) | B(1) |      16.0000 |
+------+------+------+--------------+
| C(1) | A(1) | B(0) |       7.0000 |
+------+------+------+--------------+
| C(1) | A(1) | B(1) |       0.0000 |
+------+------+------+--------------+
| C(1) | A(2) | B(0) |      21.0000 |
+------+------+------+--------------+
| C(1) | A(2) | B(1) |      18.0000 |
+------+------+------+--------------+
#Producto de factores(*)
phi3 = phi1 * phi2
print(phi3)
+------+------+------+--------------+
| C    | A    | B    |   phi(C,A,B) |
+======+======+======+==============+
| C(0) | A(0) | B(0) |      25.0000 |
+------+------+------+--------------+
| C(0) | A(0) | B(1) |       8.0000 |
+------+------+------+--------------+
| C(0) | A(1) | B(0) |       5.0000 |
+------+------+------+--------------+
| C(0) | A(1) | B(1) |       0.0000 |
+------+------+------+--------------+
| C(0) | A(2) | B(0) |      15.0000 |
+------+------+------+--------------+
| C(0) | A(2) | B(1) |       9.0000 |
+------+------+------+--------------+
| C(1) | A(0) | B(0) |      35.0000 |
+------+------+------+--------------+
| C(1) | A(0) | B(1) |      16.0000 |
+------+------+------+--------------+
| C(1) | A(1) | B(0) |       7.0000 |
+------+------+------+--------------+
| C(1) | A(1) | B(1) |       0.0000 |
+------+------+------+--------------+
| C(1) | A(2) | B(0) |      21.0000 |
+------+------+------+--------------+
| C(1) | A(2) | B(1) |      18.0000 |
+------+------+------+--------------+

2. Marginalización de factores

Tienes un factor:

\[\phi_1(X, Y, Z)\]

X

Y

Z

\(\phi_1\)

\(x^0\)

\(y^0\)

\(z^0\)

10

\(x^0\)

\(y^0\)

\(z^1\)

5

\(x^0\)

\(y^1\)

\(z^0\)

15

\(x^0\)

\(y^1\)

\(z^1\)

16

\(x^1\)

\(y^0\)

\(z^0\)

14

\(x^1\)

\(y^0\)

\(z^1\)

30

\(x^1\)

\(y^1\)

\(z^0\)

2

\(x^1\)

\(y^1\)

\(z^1\)

8

queremos obtener otro más pequeño:

\(\psi(Y,Z) = \sum_{X}\phi_1(X, Y, Z)\)

Y

Z

\(\psi\)

\(y^0\)

\(z^0\)

10 + 14 = 24

\(y^0\)

\(z^1\)

5 + 30 = 35

\(y^1\)

\(z^0\)

15 + 2 = 17

\(y^1\)

\(z^1\)

16 + 8 = 24

Para cada combinación de \(Y\) y \(Z\), sumamos todos los valores posbiles de \(X\).

# Factor phi1
phi1 = DiscreteFactor(
    variables=['X', 'Y', 'Z'],
    cardinality=[2,2,2],
    values=[10,5,15,16,14,30,2,8]
)
# Marginalización resp. X (.marginalize)
phi_marg_x = phi1.marginalize(variables=['X'], inplace=False)
print(phi_marg_x)
+------+------+------------+
| Y    | Z    |   phi(Y,Z) |
+======+======+============+
| Y(0) | Z(0) |    24.0000 |
+------+------+------------+
| Y(0) | Z(1) |    35.0000 |
+------+------+------------+
| Y(1) | Z(0) |    17.0000 |
+------+------+------------+
| Y(1) | Z(1) |    24.0000 |
+------+------+------------+
# Marginalización resp. X, Y (.marginalize)
phi1_marg_xy = phi1.marginalize(variables=['X', 'Y'], inplace=False)
print(phi1_marg_xy)
+------+----------+
| Z    |   phi(Z) |
+======+==========+
| Z(0) |  41.0000 |
+------+----------+
| Z(1) |  59.0000 |
+------+----------+

3. Reducción de factores

\[\phi_1(X, Y, Z)\]

X

Y

Z

\(\phi_1(X,Y,Z)\)

\(x^0\)

\(y^0\)

\(z^0\)

10

\(x^0\)

\(y^0\)

\(z^1\)

5

\(x^0\)

\(y^1\)

\(z^0\)

15

\(x^0\)

\(y^1\)

\(z^1\)

16

\(x^1\)

\(y^0\)

\(z^0\)

14

\(x^1\)

\(y^0\)

\(z^1\)

30

\(x^1\)

\(y^1\)

\(z^0\)

2

\(x^1\)

\(y^1\)

\(z^1\)

8

\(\psi(X,Z) = \phi_1(X, y^1, Z)\)

X

Y

Z

\(\phi_1\)

\(x^0\)

\(y^1\)

\(z^0\)

15

\(x^0\)

\(y^1\)

\(z^1\)

16

\(x^1\)

\(y^1\)

\(z^0\)

2

\(x^1\)

\(y^1\)

\(z^1\)

8

Como \(Y=y^1\) es constante, el factor resultante no depende de Y:

X

Z

\(\phi_1\)

\(x^0\)

\(z^0\)

15

\(x^0\)

\(z^1\)

16

\(x^1\)

\(z^0\)

2

\(x^1\)

\(z^1\)

8

# Factor phi1
phi1 = DiscreteFactor(
    variables=['X', 'Y', 'Z'],
    cardinality=[2,2,2],
    values=[10,5,15,16,14,30,2,8]
)
# Reducción phi1(X, y1, Z)(.reduce)
phi1_red = phi1.reduce(values=[('Y', 1)], inplace=False)
print(phi1_red)
+------+------+------------+
| X    | Z    |   phi(X,Z) |
+======+======+============+
| X(0) | Z(0) |    15.0000 |
+------+------+------------+
| X(0) | Z(1) |    16.0000 |
+------+------+------------+
| X(1) | Z(0) |     2.0000 |
+------+------+------------+
| X(1) | Z(1) |     8.0000 |
+------+------+------------+
# Reducción phi1(X, y1, z0)(.reduce)
phi1_red2 = phi1.reduce(values=[('Y', 1), ('Z', 0)], inplace=False)
print(phi1_red2)
+------+----------+
| X    |   phi(X) |
+======+==========+
| X(0) |  15.0000 |
+------+----------+
| X(1) |   2.0000 |
+------+----------+

La gran pregunta#

¿Por qué los factores son tan importantes en redes bayesianas y modelos probabilísticos?

El problema de las distribuciones grandes#

Imaginen que tenemos muchas variables aleatorias, digamos que \(N=20\). Si cada una puede tomar solo 2 valores (por ejemplo, sí o no), una distribución conjunta completa tendría que guardar:

\(2^{20} = 1,048,576\) combinaciones posibles.

y si cada variable dependiera de las demás, la tabla sería enorme e imposible de manejar.

¿Y si las variables dependen entre sí?#

Los factores solo son útiles cuando las dependencias son locales — cuando cada variable depende de pocas otras, no de todas.