763e06c127
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
"""Tests para theils_u."""
|
|
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
from theils_u import theils_u
|
|
|
|
|
|
def test_b_determines_a_gives_one():
|
|
"""Si b determina por completo a, U(a|b) debe ser ~1.0."""
|
|
# Cada valor de b mapea a un unico valor de a (relacion funcional b -> a).
|
|
a = ["x", "x", "y", "y", "z", "z"]
|
|
b = ["1", "1", "2", "2", "3", "3"]
|
|
u = theils_u(a, b)
|
|
assert abs(u - 1.0) < 1e-9
|
|
|
|
|
|
def test_asymmetry_n_to_one_relation():
|
|
"""Relacion N:1: la ciudad determina el pais pero no al reves.
|
|
|
|
theils_u(a, b) != theils_u(b, a) cuando la relacion es N:1.
|
|
"""
|
|
ciudad = ["Madrid", "Barcelona", "Paris", "Lyon", "Roma", "Milan"]
|
|
pais = ["ES", "ES", "FR", "FR", "IT", "IT"]
|
|
# Conocer la ciudad elimina toda la incertidumbre del pais.
|
|
u_pais_given_ciudad = theils_u(pais, ciudad)
|
|
# Conocer el pais solo reduce parcialmente la incertidumbre de la ciudad.
|
|
u_ciudad_given_pais = theils_u(ciudad, pais)
|
|
|
|
assert abs(u_pais_given_ciudad - 1.0) < 1e-9
|
|
assert u_ciudad_given_pais < 1.0
|
|
# Asimetria explicita.
|
|
assert u_pais_given_ciudad != u_ciudad_given_pais
|
|
|
|
|
|
def test_independence_gives_zero():
|
|
"""Si a y b son independientes, U(a|b) debe ser ~0.0."""
|
|
# a alterna x/y; b alterna 1/2 de forma cruzada -> b no informa sobre a.
|
|
a = ["x", "y", "x", "y", "x", "y", "x", "y"]
|
|
b = ["1", "1", "2", "2", "1", "1", "2", "2"]
|
|
u = theils_u(a, b)
|
|
assert abs(u) < 1e-9
|
|
|
|
|
|
def test_fewer_than_two_pairs_returns_zero():
|
|
"""Con menos de 2 pares validos devuelve 0.0, no None ni excepcion."""
|
|
assert theils_u([], []) == 0.0
|
|
assert theils_u(["x"], ["1"]) == 0.0
|
|
|
|
|
|
def test_constant_a_returns_zero():
|
|
"""Si a es constante (H(a)==0) no hay incertidumbre que eliminar -> 0.0."""
|
|
a = ["x", "x", "x", "x"]
|
|
b = ["1", "2", "3", "4"]
|
|
assert theils_u(a, b) == 0.0
|
|
|
|
|
|
def test_none_pairs_discarded():
|
|
"""Los pares con algun None se descartan antes de calcular."""
|
|
a = ["x", "x", "y", "y", None, "z"]
|
|
b = ["1", "1", "2", "2", "3", None]
|
|
# Tras descartar los pares con None quedan 4 pares con b->a funcional.
|
|
u = theils_u(a, b)
|
|
assert abs(u - 1.0) < 1e-9
|
|
|
|
|
|
def test_result_in_unit_interval():
|
|
"""El resultado siempre cae en [0.0, 1.0]."""
|
|
a = ["x", "y", "x", "z", "y", "z", "x", "y"]
|
|
b = ["1", "2", "1", "3", "2", "3", "2", "1"]
|
|
u = theils_u(a, b)
|
|
assert 0.0 <= u <= 1.0
|