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:Grafodesde el cual iniciar la búsqueda.grafos_iniciales: lista deGrafopara 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. Conrecursivoocombinatoriose comparan redes con distintas variables, cuyas puntuaciones BIC no son comparables, así que hace faltaobjetivoy un criterio de clasificación (por defecto,"auc"). A igual valor gana la red más simple.umbral(solo objetivo binario): probabilidad mínima depos_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). Siyno tiene nombre, indícala conRedBayesiana(grafo, objetivo="Churn"). - Con etiquetas de texto, las métricas que usan
pos_label(F1, precisión, recall) necesitanmake_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). NaiveBayesse 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". Sinscore_name,LearningCurveDisplayfalla con unmake_scorer. shuffle=Trueevita porciones pequeñas con una sola clase cuando los datos vienen ordenados.
Dependencias
numpy >= 1.23pandas >= 1.5scikit-learn >= 1.5- Opcional, para los gráficos PNG de
FuerzaBrutayLearningCurveDisplay: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)
| File | Size | Uploaded | |
|---|---|---|---|
| inteligenciartificial-0.0.8.tar.gz | 26.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|