import pandas as pd from sklearn.ensemble import IsolationForest import joblib import os import pyodbc from datetime import datetime print("--- INICIANDO SCRIPT DE ENTRENAMIENTO DE SISTEMA ---") # --- 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;' MODEL_FILE = 'modelo_sistema_anomalias.joblib' CONTAMINATION_RATE = 0.02 # Tasa de contaminación del 0.2% (ajustable según tus necesidades) # --- 2. Carga y Agregación de Datos desde SQL Server --- try: print("Conectando a la base de datos...") cnxn = pyodbc.connect(CONNECTION_STRING) # Consulta para agregar los datos por día query = """ SELECT CAST(Fecha AS DATE) AS fecha_dia, DATEPART(weekday, Fecha) as dia_semana, -- 1=Domingo, 2=Lunes... COUNT(DISTINCT Id_Canilla) as total_canillitas_activos, SUM(CantSalida) as total_salidas, SUM(CantEntrada) as total_devoluciones FROM dist_EntradasSalidasCanillas WHERE CantSalida > 0 -- Solo considerar días con actividad de salida GROUP BY CAST(Fecha AS DATE), DATEPART(weekday, Fecha) """ print("Ejecutando consulta de agregación de datos históricos...") 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 históricos para entrenar el modelo de sistema. Saliendo.") exit() # --- 3. Feature Engineering para el modelo de sistema --- print(f"Preparando {len(df)} registros agregados para el entrenamiento...") # El ratio de devolución es una característica muy potente df['ratio_devolucion'] = (df['total_devoluciones'] / df['total_salidas']).fillna(0) # Ratio de salidas por canillita activo df['salidas_por_canillita'] = (df['total_salidas'] / df['total_canillitas_activos']).fillna(0) # Seleccionamos las características que el modelo usará features = ['dia_semana', 'total_salidas', 'ratio_devolucion', 'salidas_por_canillita'] X = df[features] # --- 4. Entrenamiento del Modelo --- print(f"Entrenando el modelo IsolationForest de sistema con tasa de contaminación de {CONTAMINATION_RATE}...") model = IsolationForest( n_estimators=100, contamination=CONTAMINATION_RATE, random_state=42 ) model.fit(X) # --- 5. Guardado del Modelo --- joblib.dump(model, MODEL_FILE) print("--- ENTRENAMIENTO DE SISTEMA COMPLETADO ---") print(f"Modelo de sistema guardado exitosamente como '{MODEL_FILE}'")