InsideForest
InsideForest agrupa la geometría de decisión de un RandomForestClassifier en reglas y regiones legibles. Ahora admite bosques entrenados internamente o proporcionados por el usuario, por lo que puedes reutilizar ensambles ajustados que ya formen parte de tu pipeline.
Inicio rápido
from sklearn.datasets import load_iris
from sheshe import InsideForest
X, y = load_iris(return_X_y=True)
explorer = InsideForest()
explorer.fit(X, y)
region_labels = explorer.transform(X, mode="best")
summary = explorer.explain(top_k=5)
Usar un RandomForestClassifier entrenado por el usuario
El estimador acepta un bosque previo mediante el argumento random_forest de fit. El ejemplo replica el experimento que cronometra el dataset de vino.
from sklearn.datasets import load_wine
from sklearn.ensemble import RandomForestClassifier
from sheshe import InsideForest
X, y = load_wine(return_X_y=True)
bosque_usuario = RandomForestClassifier(
n_estimators=200,
min_samples_leaf=2,
random_state=42,
n_jobs=-1,
).fit(X, y)
explorer = InsideForest()
explorer.fit(X, y, random_forest=bosque_usuario)
print(len(explorer.get_rules()), "reglas")
print(len(explorer.get_regions()), "regiones")
Transformar muestras y listar todas las regiones
Los experimentos sobre digits evalúan tanto la mejor región como la lista completa de coberturas. El fragmento muestra cómo obtener todas las regiones que cubren cada observación.
from sklearn.datasets import load_digits
from sheshe import InsideForest
X, y = load_digits(return_X_y=True)
explorer = InsideForest()
explorer.fit(X, y)
all_regions = explorer.transform(X, mode="all")
first_sample_regions = all_regions[0]
Generar hipótesis contrastantes
La generación de hipótesis empareja regiones similares con grandes diferencias de pureza. El experimento de tiempo mide este paso para cada dataset.
from sklearn.datasets import load_iris
from sheshe import InsideForest
X, y = load_iris(return_X_y=True)
explorer = InsideForest()
explorer.fit(X, y)
hypotheses = explorer.generate_hypotheses(top_pairs=5)
for hypothesis in hypotheses:
print(hypothesis["pair"], hypothesis["purity_delta"])
Diagnóstico de tiempos
Activa el parámetro verbose en fit, transform, explain o generate_hypotheses para registrar cuánto tarda cada etapa interna. Los valores recientes también quedan disponibles mediante get_last_timings(), que alimenta los experimentos descritos abajo.
explorer = InsideForest()
explorer.fit(X, y, verbose=1)
explorer.transform(X, mode="best", verbose=1)
print(explorer.get_last_timings()["fit"])
Experimentos de tiempo
El script experiments/inside_forest_runtime.py corre en Iris, Wine y Digits para comparar el entrenamiento interno contra la reutilización de un bosque ya entrenado. Ahora registra los tiempos por etapa expuestos por get_last_timings(), guarda los resultados en benchmark/inside_forest_runtime.csv e identifica los cuellos de botella.
| dataset | modo | n_rules | n_regions | fit_time_s | fit_bottleneck | fit_bottleneck_time_s | fit_cluster_total_s | fit_extract_rules_s | fit_train_random_forest_s | transform_bottleneck | transform_bottleneck_time_s | hypotheses_bottleneck | hypotheses_bottleneck_time_s |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| iris | interno | 724 | 159 | 5.47 | cluster_total | 4.67 | 4.67 | 0.045 | 0.76 | select_best_region | 0.0024 | scan_pairs | 0.25 |
| iris | externo | 724 | 159 | 4.51 | cluster_total | 4.47 | 4.47 | 0.043 | 0.00 | select_best_region | 0.0025 | scan_pairs | 0.24 |
| wine | interno | 842 | 214 | 15.03 | cluster_total | 14.24 | 14.24 | 0.055 | 0.74 | points_in_regions | 0.0038 | scan_pairs | 1.11 |
| wine | externo | 842 | 214 | 14.04 | cluster_total | 13.98 | 13.98 | 0.062 | 0.00 | points_in_regions | 0.0063 | scan_pairs | 0.94 |
| digits | interno | 8660 | 10 | 2.04 | train_random_forest | 0.90 | 0.35 | 0.80 | 0.89 | select_best_region | 0.026 | scan_pairs | 0.010 |
| digits | externo | 8660 | 10 | 1.07 | extract_rules | 0.78 | 0.29 | 0.78 | 0.00 | select_best_region | 0.022 | scan_pairs | 0.0099 |
En conjuntos pequeños domina la fase de agrupamiento de reglas, sobre todo el cálculo de Jaccard (cluster_total). Con los 8.6 mil rules de Digits el algoritmo recurre al fallback con KMeans: el modo interno dedica la mayor parte del tiempo al entrenamiento del bosque, mientras que el modo externo lo invierte en la extracción de reglas.