Files
GestionIntegralWeb/ProyectoIA_Gestion/train_distribuidores.py

68 lines
2.6 KiB
Python
Raw Permalink Normal View History

2025-11-10 15:06:10 -03:00
import pandas as pd
from sklearn.ensemble import IsolationForest
import joblib
import pyodbc
from datetime import datetime, timedelta
print("--- INICIANDO SCRIPT DE ENTRENAMIENTO (DISTRIBUIDORES) ---")
# --- 1. Configuración ---
DB_SERVER = 'TECNICA3'
DB_DATABASE = 'SistemaGestion'
CONNECTION_STRING = f'DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={DB_SERVER};DATABASE={DB_DATABASE};Trusted_Connection=yes;TrustServerCertificate=yes;'
2025-11-18 13:11:33 -03:00
MODEL_FILE = 'modelo_anomalias_dist.joblib'
CONTAMINATION_RATE = 0.01 # Un 1% de contaminación
2025-11-10 15:06:10 -03:00
# --- 2. Carga de Datos desde SQL Server ---
try:
print(f"Conectando a la base de datos '{DB_DATABASE}' en '{DB_SERVER}'...")
cnxn = pyodbc.connect(CONNECTION_STRING)
2025-11-18 13:11:33 -03:00
fecha_limite = datetime.now() - timedelta(days=730)
2025-11-10 15:06:10 -03:00
query = f"""
SELECT
Id_Distribuidor AS id_distribuidor,
CAST(Fecha AS DATE) AS fecha,
SUM(CASE WHEN TipoMovimiento = 'Salida' THEN Cantidad ELSE 0 END) as cantidad_enviada,
SUM(CASE WHEN TipoMovimiento = 'Entrada' THEN Cantidad ELSE 0 END) as cantidad_devuelta
FROM
dist_EntradasSalidas
WHERE
Fecha >= '{fecha_limite.strftime('%Y-%m-%d')}'
GROUP BY
Id_Distribuidor, CAST(Fecha AS DATE)
HAVING
SUM(CASE WHEN TipoMovimiento = 'Salida' THEN Cantidad ELSE 0 END) > 0
"""
print("Ejecutando consulta para obtener datos de entrenamiento de distribuidores...")
df = pd.read_sql(query, cnxn)
cnxn.close()
except Exception as e:
print(f"Error al conectar o consultar la base de datos: {e}")
exit()
if df.empty:
print("No se encontraron datos de entrenamiento de distribuidores en el último año. Saliendo.")
exit()
# --- 3. Preparación de Datos ---
print(f"Preparando {len(df)} registros para el entrenamiento del modelo de distribuidores...")
# Se usa (df['cantidad_enviada'] + 0.001) para evitar división por cero
df['porcentaje_devolucion'] = (df['cantidad_devuelta'] / (df['cantidad_enviada'] + 0.001)) * 100
df.fillna(0, inplace=True)
df['porcentaje_devolucion'] = df['porcentaje_devolucion'].clip(0, 100)
df['dia_semana'] = pd.to_datetime(df['fecha']).dt.dayofweek
2025-11-18 13:11:33 -03:00
features = ['id_distribuidor', 'porcentaje_devolucion', 'dia_semana']
2025-11-10 15:06:10 -03:00
X = df[features]
# --- 4. Entrenamiento y Guardado ---
print(f"Entrenando el modelo con tasa de contaminación de {CONTAMINATION_RATE}...")
model = IsolationForest(n_estimators=100, contamination=CONTAMINATION_RATE, random_state=42)
model.fit(X)
joblib.dump(model, MODEL_FILE)
print(f"--- ENTRENAMIENTO DE DISTRIBUIDORES COMPLETADO. Modelo guardado en '{MODEL_FILE}' ---")