Skip to main content

Paquete Inteligencia Artificial

Paquete de algoritmos de Inteligencia Artificial para aprendizaje de estructura de Redes Bayesianas.

Instalación

pip install inteligenciartificial

O desde fuente local:

pip install ./fia

Uso

Algoritmos de aprendizaje de estructura

K2

Algoritmo greedy que requiere un orden topológico de variables. Agrega padres iterativamente si mejoran la métrica de scoring.

from inteligenciartificial.modelografosprobabilisticos.busqueda import K2
from inteligenciartificial.modelografosprobabilisticos.metricas import Entropia, BIC

orden = ["Churn", "tenure_cat", "OnlineSecurity", "TechSupport", "Contract"]
k2 = K2(orden, max_padres=4, df=df_train, metrica=Entropia())
# [K2] Grafos explorados: 35 | Tiempo: 0.1234 s | Throughput: 283.61 grafos/s

modelo = k2.fit(X_train, y_train, alpha=1.0)

Hill-Climbing

Algoritmo de búsqueda local que en cada paso evalúa operaciones de agregar, eliminar e invertir aristas, seleccionando la que mayor mejora produce.

A partir de la versión 0.0.6 acepta configurar el estado inicial:

  • Por defecto parte de un grafo vacío.
  • grafo_inicial: Grafo desde el cual iniciar la búsqueda.
  • grafos_iniciales: lista de Grafo para ejecutar varias corridas con inicios manuales.
  • reinicios + seed: número de reinicios desde DAGs aleatorios reproducibles.
from inteligenciartificial.modelografosprobabilisticos.busqueda import HillClimbing
from inteligenciartificial.modelografosprobabilisticos.metricas import BIC
from inteligenciartificial.modelografosprobabilisticos.grafo import Grafo

variables = ["Churn", "tenure_cat", "OnlineSecurity", "TechSupport", "Contract"]

# Inicio por defecto (grafo vacío)
hc = HillClimbing(variables, max_padres=4, df=df_train, metrica=BIC(), max_iter=100)

# Inicio desde un grafo dado
hc = HillClimbing(variables, max_padres=4, df=df_train, metrica=BIC(), max_iter=100,
                  grafo_inicial=Grafo([("Contract", "Churn")]))

# Reinicios aleatorios reproducibles
hc = HillClimbing(variables, max_padres=4, df=df_train, metrica=BIC(), max_iter=100,
                  reinicios=5, seed=42)

# Reinicios manuales
hc = HillClimbing(variables, max_padres=4, df=df_train, metrica=BIC(), max_iter=100,
                  grafos_iniciales=[Grafo([]), Grafo([("Contract", "Churn")])])

modelo = hc.fit(X_train, y_train, alpha=1.0)

Simulated Annealing

Búsqueda estocástica que en cada iteración propone una operación vecina aleatoria (agregar / eliminar / invertir arista). Si la operación mejora el score se acepta; si lo empeora, se acepta con probabilidad exp(Δ / T). La temperatura decae geométricamente con factor enfriamiento.

from inteligenciartificial.modelografosprobabilisticos.busqueda import SimulatedAnnealing
from inteligenciartificial.modelografosprobabilisticos.metricas import BIC

sa = SimulatedAnnealing(
    variables, max_padres=4, df=df_train, metrica=BIC(),
    max_iter=2000, t_inicial=1.0, t_min=1e-3, enfriamiento=0.995, seed=42,
)
modelo = sa.fit(X_train, y_train, alpha=1.0)

Fuerza bruta

A partir de la versión 0.0.8. Enumera todos los DAG posibles (respetando max_padres) y garantiza el óptimo global, por lo que solo es viable con pocas variables: n_variables ≤ 5.

Variables 1 2 3 4 5 6
DAG posibles 1 3 25 543 29 281 3 781 503

Qué conjuntos de variables explora, dado variables (con objetivo, este va en todos):

Opción Conjuntos explorados (ejemplo con n_variables=3)
por defecto uno: las n_variables primeras
recursivo=True los tamaños 1, 2 y 3 (las primeras variables de cada tamaño)
combinatorio=True todas las combinaciones de 3 variables
ambos todas las combinaciones de 1, 2 y 3 variables

Cada DAG se puntúa con metrica (BIC o Entropía) y, si se indica objetivo, se evalúa como clasificador sobre df_eval (o sobre df si no se da, lo que es optimista) con AUC, accuracy, precision, recall y F1. Las redes con el mismo manto de Markov del objetivo predicen lo mismo y se evalúan una sola vez.

from inteligenciartificial.modelografosprobabilisticos.busqueda import FuerzaBruta
from inteligenciartificial.modelografosprobabilisticos.metricas import BIC

variables = ["Churn", "Contract", "TechSupport", "tenure_cat", "OnlineSecurity", "InternetService"]

fb = FuerzaBruta(
    variables, max_padres=2, df=df_train, metrica=BIC(),
    objetivo="Churn", df_eval=df_test, n_variables=3,
    recursivo=True, combinatorio=True,           # tamaños 1..3, todas las combinaciones
    criterio="auc", umbral=0.3,                  # elige por AUC; F1, etc. con P(Yes) >= 0.3
    csv="resultados/fuerza_bruta.csv",           # una fila por DAG
    png="resultados", metricas_png=["auc", "f1"],  # un PNG por métrica
)
# [FuerzaBruta] Conjuntos de variables: 16 | Grafos explorados: 266 | Tiempo: … | Mejor auc: …

fb.resultados.sort_values("auc", ascending=False).head()   # variables, aristas, score y métricas
modelo = fb.fit(X_train, y_train, alpha=1.0)               # RedBayesiana con la mejor red
fb.graficar("recall", "resultados/recall.png")             # otro gráfico cuando se quiera
  • criterio: "score" (por defecto con un solo conjunto de variables) o una de las métricas. Con recursivo o combinatorio se comparan redes con distintas variables, cuyas puntuaciones BIC no son comparables, así que hace falta objetivo y un criterio de clasificación (por defecto, "auc"). A igual valor gana la red más simple.
  • umbral (solo objetivo binario): probabilidad mínima de pos_label (por defecto, la última clase: "Yes", 1) para predecirla. Sin él, accuracy, precision, recall y F1 usan la clase más probable; con clases desbalanceadas eso puede dar F1 = 0 en todas las redes. El AUC no depende del umbral.
  • Gráficos: a la izquierda, todas las redes ordenadas por la métrica (color = número de variables); a la derecha, la métrica frente al score de estructura (un conjunto) o su rango en cada conjunto de variables (varios). Requieren matplotlib: pip install "inteligenciartificial[graficos]".
  • max_grafos (1 000 000 por defecto) evita búsquedas desmedidas; como referencia, 29 281 DAG con métricas tardan en torno a 1 s.

Métricas de throughput

Todos los algoritmos (K2, Hill-Climbing, Simulated Annealing y Fuerza bruta) reportan automáticamente al finalizar el entrenamiento:

Atributo Descripción
grafos_explorados Cantidad de configuraciones de grafo (conjuntos de padres) evaluadas
tiempo_segundos Tiempo total de la búsqueda de estructura en segundos
throughput Tasa de exploración: grafos_explorados / tiempo_segundos (grafos/s)
print(k2.grafos_explorados)   # e.g., 35
print(k2.tiempo_segundos)     # e.g., 0.1234
print(k2.throughput)           # e.g., 283.61

Métricas de scoring

Métrica Descripción
Entropia Usa -H(X|Pa) como score (mayor es mejor)
BIC Bayesian Information Criterion con penalización (k/2)*log(N)

Modelos

  • RedBayesiana: Red Bayesiana discreta con CPTs estimadas por conteos + suavizado Dirichlet(alpha).
  • NaiveBayes: Caso especial donde todas las features dependen únicamente de la clase.

Ambos son clasificadores de scikit-learn (ver abajo).

Integración con scikit-learn

A partir de la versión 0.0.7, RedBayesiana y NaiveBayes heredan de ClassifierMixin y BaseEstimator: se pueden clonar y, tras fit, exponen classes_ y predict_proba (P(objetivo | X), una columna por clase). Por eso se acoplan directamente a TunedThresholdClassifierCV (scikit-learn ≥ 1.5), que elige por validación cruzada el umbral de decisión que maximiza una métrica en problemas binarios. En la RedBayesiana la estructura del grafo queda fija y en cada fold solo se re-estiman las CPTs.

from sklearn.metrics import f1_score, make_scorer
from sklearn.model_selection import TunedThresholdClassifierCV

red = hc.fit(X_train, y_train, alpha=1.0)   # o RedBayesiana(grafo, alpha=1.0)

ajustado = TunedThresholdClassifierCV(
    red, scoring=make_scorer(f1_score, pos_label="Yes"), cv=5,
).fit(X_train, y_train)

print(ajustado.best_threshold_, ajustado.best_score_)
y_pred = ajustado.predict(X_test)
  • La variable objetivo es el nombre de y (pd.Series). Si y no tiene nombre, indícala con RedBayesiana(grafo, objetivo="Churn").
  • Con etiquetas de texto, las métricas que usan pos_label (F1, precisión, recall) necesitan make_scorer(..., pos_label=...); la métrica por defecto, balanced_accuracy, no.
  • Con un conjunto de validación aparte: TunedThresholdClassifierCV(red, cv="prefit", refit=False).fit(X_val, y_val).
  • NaiveBayes se usa igual: TunedThresholdClassifierCV(NaiveBayes(clase="Churn"), cv=5).fit(X_train, y_train).

Por la misma razón funcionan con LearningCurveDisplay, que re-entrena el modelo con porciones crecientes de los datos:

import numpy as np
from sklearn.model_selection import LearningCurveDisplay

red = fb.fit(X_train, y_train)   # o hc.fit(...), RedBayesiana(grafo), NaiveBayes(clase="Churn")
LearningCurveDisplay.from_estimator(
    red, X_train, y_train, cv=5, scoring="roc_auc",
    train_sizes=np.linspace(0.1, 1.0, 5), shuffle=True, random_state=0,
)
  • Para F1, precision o recall con etiquetas de texto: scoring=make_scorer(f1_score, pos_label="Yes"), score_name="F1". Sin score_name, LearningCurveDisplay falla con un make_scorer.
  • shuffle=True evita porciones pequeñas con una sola clase cuando los datos vienen ordenados.

Dependencias

  • numpy >= 1.23
  • pandas >= 1.5
  • scikit-learn >= 1.5
  • Opcional, para los gráficos PNG de FuerzaBruta y LearningCurveDisplay: matplotlib >= 3.6 (pip install "inteligenciartificial[graficos]")

Licencia

MIT

Metadata

Release files for inteligenciartificial 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for inteligenciartificial 0.0.8
File Size Uploaded
inteligenciartificial-0.0.8.tar.gz 26.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for inteligenciartificial 0.0.8
File Interpreter ABI Platform
inteligenciartificial-0.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 59.2 kB

Release files / inteligenciartificial-0.0.8.tar.gz

Download URL inteligenciartificial-0.0.8.tar.gz
Size 26.9 kB
Tags Source
SHA-256 checksum
How to use checksums
1f6928f9f554cf342e1eb69bb99638728cafe4a34a58b8e4b813a74746a75573
BLAKE2b-256 checksum
How to use checksums
d132e917ac108b7408d31458ba0df9b907000ec648356f9c2d36f093abfeea81
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / inteligenciartificial-0.0.8-py3-none-any.whl

Download URL inteligenciartificial-0.0.8-py3-none-any.whl
Size 32.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e5b4dd37c18a5337166c4e0c74ab3370d335d4220b4e6edc1f2c5935a7498b15
BLAKE2b-256 checksum
How to use checksums
bd28c1e9248ad6c004f09858214e7d51fd34e601c61ee3d7aa075ee20f0768f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.0.9

2 release files

This release

0.0.8 This release

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page