1629 lines
66 KiB
Markdown
1629 lines
66 KiB
Markdown
# RF-BI-003: Analisis Predictivo y Forecasting
|
||
|
||
**Epica:** MAI-006 - Reportes y Business Intelligence
|
||
**Modulo:** Analisis Predictivo y Machine Learning
|
||
**Responsable:** Product Owner
|
||
**Fecha:** 2025-11-17
|
||
**Version:** 1.0
|
||
|
||
---
|
||
|
||
## 1. Objetivo
|
||
|
||
Proporcionar capacidades avanzadas de analisis predictivo y forecasting mediante algoritmos de machine learning e inteligencia artificial para predecir costos finales, fechas de termino, identificar riesgos potenciales y simular escenarios what-if que apoyen la toma de decisiones estrategicas.
|
||
|
||
---
|
||
|
||
## 2. Casos de Uso
|
||
|
||
### CU-BI-010: Prediccion de Costos Finales
|
||
|
||
**Actor:** CFO, Gerente de Proyecto, Director de Costos
|
||
**Precondiciones:**
|
||
- Proyecto tiene al menos 20% de avance fisico
|
||
- Existe historial de costos registrados (minimo 3 meses)
|
||
|
||
**Flujo Principal:**
|
||
|
||
1. Usuario accede a modulo de prediccion de costos
|
||
2. Usuario selecciona proyecto "Fraccionamiento Del Valle"
|
||
3. Sistema analiza datos historicos:
|
||
- Presupuesto original: $120M
|
||
- Costo acumulado: $35M (29%)
|
||
- Avance fisico: 25%
|
||
- Tendencia de costos ultimos 3 meses
|
||
4. Sistema aplica algoritmo de regresion lineal y analisis de curva S
|
||
5. Sistema muestra prediccion:
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Prediccion de Costo Final │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Presupuesto Original: $120.0M │
|
||
│ Costo Actual (25%): $35.0M │
|
||
│ │
|
||
│ ┌─ Prediccion ─────────────────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ Costo Final Estimado: $125.5M │ │
|
||
│ │ Sobrecosto Proyectado: +$5.5M (+4.6%) │ │
|
||
│ │ Nivel de Confianza: 87% │ │
|
||
│ │ │ │
|
||
│ │ Rango de Estimacion: │ │
|
||
│ │ • Escenario Optimista: $122.0M (+1.7%) │ │
|
||
│ │ • Escenario Esperado: $125.5M (+4.6%) │ │
|
||
│ │ • Escenario Pesimista: $130.2M (+8.5%) │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Grafica de Proyeccion ──────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ $150M│ ╱─── Pesim. │ │
|
||
│ │ $130M│ ╱──● │ │
|
||
│ │ $120M│ ────────────────────● Esperado │ │
|
||
│ │ $100M│ ╱─● Optimista │ │
|
||
│ │ $80M│ ╱──● │ │
|
||
│ │ $60M│ ╱──● │ │
|
||
│ │ $40M│ ╱──● ← Costo Real │ │
|
||
│ │ $20M│● │ │
|
||
│ │ $0M└────────────────────────────────→ │ │
|
||
│ │ 0% 10% 20% 30%... 80% 90% 100% │ │
|
||
│ │ Avance Fisico │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ Factores Identificados: │
|
||
│ 🔴 CPI actual: 0.88 (12% sobre presupuesto) │
|
||
│ 🟡 Tendencia alcista en costos de materiales │
|
||
│ 🟢 Productividad dentro de rangos normales │
|
||
│ │
|
||
│ Recomendaciones: │
|
||
│ • Revisar partidas de estructura (mayor varianza) │
|
||
│ • Negociar contratos marco para materiales │
|
||
│ • Considerar value engineering en acabados │
|
||
│ │
|
||
│ [Exportar] [Simular Escenarios] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
6. Usuario puede ajustar parametros de prediccion
|
||
7. Usuario puede explorar factores que afectan la prediccion
|
||
8. Sistema guarda prediccion con timestamp para seguimiento
|
||
|
||
**Postcondiciones:**
|
||
- Prediccion registrada en historial
|
||
- CFO notificado si sobrecosto proyectado > umbral (ej: 5%)
|
||
|
||
**Algoritmo de Prediccion:**
|
||
|
||
```python
|
||
# Metodo 1: Estimate at Completion (EAC) basado en CPI
|
||
EAC_CPI = BAC / CPI
|
||
# Donde BAC = Budget at Completion, CPI = Cost Performance Index
|
||
|
||
# Metodo 2: Regresion Lineal sobre curva de costos
|
||
from sklearn.linear_model import LinearRegression
|
||
model = LinearRegression()
|
||
model.fit(X=[[avance_fisico]], y=[[costo_acumulado]])
|
||
costo_final_pred = model.predict([[100]])[0]
|
||
|
||
# Metodo 3: Curva S con parametros ajustados
|
||
def curva_s(x, L, k, x0):
|
||
return L / (1 + np.exp(-k * (x - x0)))
|
||
|
||
params, _ = curve_fit(curva_s, avances_historicos, costos_historicos)
|
||
costo_final_curva_s = params[0] # L = asintota = costo final
|
||
|
||
# Prediccion Combinada (Ensemble)
|
||
prediccion_final = (
|
||
0.4 * EAC_CPI +
|
||
0.3 * costo_final_pred +
|
||
0.3 * costo_final_curva_s
|
||
)
|
||
|
||
# Calculo de Intervalo de Confianza
|
||
std_error = calcular_error_estandar(modelo)
|
||
intervalo_confianza = 1.96 * std_error # 95% confianza
|
||
```
|
||
|
||
---
|
||
|
||
### CU-BI-011: Proyeccion de Fechas de Termino
|
||
|
||
**Actor:** Gerente de Proyecto, Director de Operaciones
|
||
**Precondiciones:**
|
||
- Proyecto tiene cronograma registrado
|
||
- Existen mediciones de avance fisico historicas
|
||
|
||
**Flujo Principal:**
|
||
|
||
1. Usuario solicita proyeccion de fecha de termino
|
||
2. Sistema analiza datos:
|
||
- Fecha de inicio: 01/01/2025
|
||
- Fecha planificada de termino: 30/06/2026 (18 meses)
|
||
- Avance fisico actual: 25% (15/05/2025)
|
||
- SPI historico: 0.92 (8% de retraso)
|
||
3. Sistema calcula velocidad de ejecucion:
|
||
```
|
||
Velocidad promedio = 25% / 4.5 meses = 5.56% por mes
|
||
Tiempo restante = 75% / 5.56% = 13.5 meses
|
||
Fecha estimada = 15/05/2025 + 13.5 meses = 30/06/2026
|
||
```
|
||
4. Sistema muestra proyeccion:
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Proyeccion de Fecha de Termino │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Fecha Inicio: 01/01/2025 │
|
||
│ Fecha Plan Termino: 30/06/2026 (18 meses) │
|
||
│ Avance Actual: 25% (15/05/2025) │
|
||
│ │
|
||
│ ┌─ Proyeccion ─────────────────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ Fecha Estimada Termino: 15/08/2026 │ │
|
||
│ │ Retraso Proyectado: 45 dias │ │
|
||
│ │ Nivel de Confianza: 82% │ │
|
||
│ │ │ │
|
||
│ │ Escenarios: │ │
|
||
│ │ • Optimista (SPI=1.1): 15/05/2026 ✅ │ │
|
||
│ │ • Esperado (SPI=0.92): 15/08/2026 🟡 │ │
|
||
│ │ • Pesimista (SPI=0.80): 30/10/2026 🔴 │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Timeline Proyectado ────────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ Ene ──────────────────────────────────── Dic │ │
|
||
│ │ 2025 │████████░░░░░░░░░░░░░░░░░░░░ 2026 │ │
|
||
│ │ ↑ ↑ ↑ ↑ │ │
|
||
│ │ Inicio Hoy Plan Est. │ │
|
||
│ │ │ │
|
||
│ │ Hitos Criticos: │ │
|
||
│ │ ✅ Cimentacion (Completado) │ │
|
||
│ │ 🔄 Estructura (En Progreso - 60%) │ │
|
||
│ │ ⏱ Instalaciones (Inicio: 01/09/2025) │ │
|
||
│ │ ⏱ Acabados (Inicio: 01/12/2025) │ │
|
||
│ │ ⏱ Entrega (Proyectado: 15/08/2026) │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ Factores de Riesgo: │
|
||
│ 🔴 Actividades criticas con retraso promedio 12% │
|
||
│ 🟡 Temporada de lluvias puede retrasar +2 semanas │
|
||
│ 🟢 Recursos asignados adecuadamente │
|
||
│ │
|
||
│ Acciones para Recuperar Cronograma: │
|
||
│ • Aumentar cuadrillas en estructura (+15%) │
|
||
│ • Fast-track en instalaciones (traslape 20%) │
|
||
│ • Trabajo en sabados durante 2 meses │
|
||
│ • Impacto estimado: Recuperar 30 dias │
|
||
│ │
|
||
│ [Exportar] [Simular Acciones Correctivas] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
5. Usuario puede simular acciones correctivas
|
||
6. Sistema recalcula proyeccion con acciones propuestas
|
||
7. Usuario aprueba plan de accion
|
||
|
||
**Postcondiciones:**
|
||
- Proyeccion guardada en historial
|
||
- Plan de accion registrado para seguimiento
|
||
|
||
---
|
||
|
||
### CU-BI-012: Analisis de Tendencias Historicas
|
||
|
||
**Actor:** Director de Operaciones, Analista de BI
|
||
**Precondiciones:**
|
||
- Existen al menos 5 proyectos completados
|
||
- Datos historicos disponibles
|
||
|
||
**Flujo Principal:**
|
||
|
||
1. Usuario accede a modulo de analisis de tendencias
|
||
2. Usuario selecciona metrica: "Varianza de Costo"
|
||
3. Sistema analiza proyectos historicos (ultimos 3 anos):
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Analisis de Tendencias: Varianza de Costo │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─ Tendencia General ──────────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ +15%│ │ │
|
||
│ │ +10%│ ● │ │
|
||
│ │ +5%│ ● ● ● ● │ │
|
||
│ │ 0%├─────────────────●───────●───●───●── │ │
|
||
│ │ -5%│ │ │
|
||
│ │ └─────────────────────────────────→ │ │
|
||
│ │ Q1 Q2 Q3 Q4 Q1 Q2 Q3 Q4 Q1 Q2 │ │
|
||
│ │ 2023 2023 2023 2023 2024 2024 2024 2024 25 │ │
|
||
│ │ │ │
|
||
│ │ Tendencia: MEJORANDO ↓ │ │
|
||
│ │ Varianza promedio 2023: +4.2% │ │
|
||
│ │ Varianza promedio 2024: +1.8% │ │
|
||
│ │ Varianza YTD 2025: -0.5% │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Analisis por Tipo de Proyecto ─────────────┐ │
|
||
│ │ │ │
|
||
│ │ Fraccionamientos (15 proyectos): │ │
|
||
│ │ ████████░░░░ Promedio: +3.2% │ │
|
||
│ │ │ │
|
||
│ │ Edificios Verticales (8 proyectos): │ │
|
||
│ │ ██████░░░░░░ Promedio: +1.8% │ │
|
||
│ │ │ │
|
||
│ │ Proyectos Mixtos (3 proyectos): │ │
|
||
│ │ ███████████░ Promedio: +5.1% │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Correlaciones Identificadas ───────────────┐ │
|
||
│ │ │ │
|
||
│ │ • Presupuesto > $100M → +2.5% varianza │ │
|
||
│ │ Correlacion: 0.68 (moderada-fuerte) │ │
|
||
│ │ │ │
|
||
│ │ • Duracion > 18 meses → +3.8% varianza │ │
|
||
│ │ Correlacion: 0.72 (fuerte) │ │
|
||
│ │ │ │
|
||
│ │ • Temporada lluvias → +1.2% varianza │ │
|
||
│ │ Correlacion: 0.45 (moderada) │ │
|
||
│ │ │ │
|
||
│ │ • Gerente con exp. >5a → -1.8% varianza │ │
|
||
│ │ Correlacion: -0.61 (moderada-fuerte) │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ Patrones Detectados: │
|
||
│ • Proyectos Q1-Q2 tienen mejor desempeno (menor │
|
||
│ impacto climatico) │
|
||
│ • Fast-tracking aumenta riesgo de sobrecosto +4% │
|
||
│ • Proyectos con BIM tienen -2.5% varianza │
|
||
│ │
|
||
│ Prediccion para Nuevos Proyectos: │
|
||
│ Fracc. >$120M, 20 meses, sin BIM: │
|
||
│ → Varianza esperada: +5.2% ± 2.1% │
|
||
│ │
|
||
│ [Exportar Analisis] [Ver Detalles] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
4. Usuario explora correlaciones interesantes
|
||
5. Usuario identifica mejores practicas de proyectos exitosos
|
||
6. Usuario exporta insights para presentacion ejecutiva
|
||
|
||
**Postcondiciones:**
|
||
- Insights guardados en base de conocimiento
|
||
- Recomendaciones aplicables a proyectos futuros
|
||
|
||
---
|
||
|
||
### CU-BI-013: Identificacion de Riesgos con IA
|
||
|
||
**Actor:** Gerente de Proyecto, Director de Riesgos
|
||
**Precondiciones:**
|
||
- Proyecto activo con datos actualizados
|
||
- Modelo de IA entrenado con proyectos historicos
|
||
|
||
**Flujo Principal:**
|
||
|
||
1. Usuario solicita analisis de riesgos con IA
|
||
2. Sistema recopila datos del proyecto:
|
||
- Metricas de desempeno (SPI, CPI, SV, CV)
|
||
- Historial de incidencias
|
||
- Condiciones externas (clima, mercado)
|
||
- Comparacion con proyectos similares
|
||
3. Sistema aplica modelo de Machine Learning (Random Forest + Neural Network)
|
||
4. Sistema identifica riesgos potenciales:
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Analisis de Riesgos con IA │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Proyecto: Fraccionamiento Del Valle │
|
||
│ Analisis ejecutado: 17/11/2025 14:32 │
|
||
│ │
|
||
│ ┌─ Score de Riesgo General ────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ ┌─────────────────────────┐ │ │
|
||
│ │ │ MEDIO │ │ │
|
||
│ │ │ 62% │ │ │
|
||
│ │ └─────────────────────────┘ │ │
|
||
│ │ │ │
|
||
│ │ Bajo ├────●───────────┤ Alto │ │
|
||
│ │ 0-30% │ 30-70% 70-100% │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Riesgos Identificados (Ordenados por Impacto) ─┐ │
|
||
│ │ │ │
|
||
│ │ 🔴 CRITICO - Probabilidad: 78% │ │
|
||
│ │ Sobrecosto en Estructura │ │
|
||
│ │ Impacto: +$8M (+6.7%) │ │
|
||
│ │ │ │
|
||
│ │ Factores: │ │
|
||
│ │ • CPI actual en estructura: 0.82 │ │
|
||
│ │ • Precio acero subio 12% vs presupuesto │ │
|
||
│ │ • Patron similar en 4 proyectos historicos │ │
|
||
│ │ │ │
|
||
│ │ Acciones Recomendadas: │ │
|
||
│ │ 1. Renegociar contrato de acero (ahorro est: $2M)│ │
|
||
│ │ 2. Value engineering en elementos secundarios │ │
|
||
│ │ 3. Acelerar compras para fijar precios │ │
|
||
│ │ │ │
|
||
│ ├──────────────────────────────────────────────────┤ │
|
||
│ │ │ │
|
||
│ │ 🟡 ALTO - Probabilidad: 65% │ │
|
||
│ │ Retraso en Fase de Acabados │ │
|
||
│ │ Impacto: +45 dias │ │
|
||
│ │ │ │
|
||
│ │ Factores: │ │
|
||
│ │ • Inicio de acabados coincide con temporada alta │ │
|
||
│ │ • Escasez de mano de obra especializada │ │
|
||
│ │ • Ruta critica tiene holgura de solo 10 dias │ │
|
||
│ │ │ │
|
||
│ │ Acciones Recomendadas: │ │
|
||
│ │ 1. Pre-contratar cuadrillas de acabados YA │ │
|
||
│ │ 2. Considerar fast-track con instalaciones │ │
|
||
│ │ 3. Buffer adicional de 15 dias en cronograma │ │
|
||
│ │ │ │
|
||
│ ├──────────────────────────────────────────────────┤ │
|
||
│ │ │ │
|
||
│ │ 🟡 MEDIO - Probabilidad: 55% │ │
|
||
│ │ Problemas de Liquidez en Q3-2025 │ │
|
||
│ │ Impacto: Necesidad de $12M credito puente │ │
|
||
│ │ │ │
|
||
│ │ Factores: │ │
|
||
│ │ • Desfase entre egresos y cobro de estimaciones │ │
|
||
│ │ • Cliente historicamente tarda 45 dias en pagar │ │
|
||
│ │ • Pico de egresos en Jul-Ago (acabados) │ │
|
||
│ │ │ │
|
||
│ │ Acciones Recomendadas: │ │
|
||
│ │ 1. Negociar anticipos adicionales con cliente │ │
|
||
│ │ 2. Preparar linea de credito con banco │ │
|
||
│ │ 3. Escalonar pagos a proveedores │ │
|
||
│ │ │ │
|
||
│ ├──────────────────────────────────────────────────┤ │
|
||
│ │ │ │
|
||
│ │ 🟢 BAJO - Probabilidad: 28% │ │
|
||
│ │ Incumplimiento en Calidad de Concreto │ │
|
||
│ │ Impacto: Demolicion parcial (-$2M, +20 dias) │ │
|
||
│ │ │ │
|
||
│ │ Factores: │ │
|
||
│ │ • Nuevo proveedor sin track record │ │
|
||
│ │ • Pero: ensayos de laboratorio son satisfactorios│ │
|
||
│ │ │ │
|
||
│ │ Acciones Recomendadas: │ │
|
||
│ │ 1. Incrementar frecuencia de muestreo (20% mas) │ │
|
||
│ │ 2. Supervision estricta en primeras fundiciones │ │
|
||
│ └──────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Comparacion con Proyectos Similares ────────┐ │
|
||
│ │ │ │
|
||
│ │ Proyectos analizados: 12 (mismo tipo/tamano) │ │
|
||
│ │ │ │
|
||
│ │ Distribucion de Riesgos: │ │
|
||
│ │ • 25% tuvieron riesgo critico similar │ │
|
||
│ │ • 58% evitaron sobrecosto con acciones early │ │
|
||
│ │ • 17% no detectaron riesgo a tiempo │ │
|
||
│ │ │ │
|
||
│ │ Tu proyecto esta en percentil: 68 │ │
|
||
│ │ (Mayor riesgo que 68% de proyectos similares) │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ Confianza del Modelo: 84% │
|
||
│ Ultima actualizacion del modelo: 01/11/2025 │
|
||
│ │
|
||
│ [Exportar Informe] [Crear Plan de Mitigacion] │
|
||
│ [Configurar Alertas Automaticas] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
5. Usuario revisa riesgos identificados
|
||
6. Usuario crea plan de mitigacion para riesgos criticos
|
||
7. Sistema programa alertas automaticas para monitorear indicadores
|
||
|
||
**Postcondiciones:**
|
||
- Riesgos registrados en matriz de riesgos
|
||
- Alertas configuradas para early warning
|
||
- Plan de mitigacion activo
|
||
|
||
**Algoritmo de ML para Identificacion de Riesgos:**
|
||
|
||
```python
|
||
from sklearn.ensemble import RandomForestClassifier
|
||
from sklearn.neural_network import MLPClassifier
|
||
import numpy as np
|
||
|
||
class RiskPredictionModel:
|
||
def __init__(self):
|
||
# Random Forest para clasificacion de nivel de riesgo
|
||
self.rf_model = RandomForestClassifier(n_estimators=100)
|
||
|
||
# Neural Network para prediccion de impacto
|
||
self.nn_model = MLPClassifier(hidden_layers=(64, 32, 16))
|
||
|
||
def prepare_features(self, project):
|
||
"""Extrae features del proyecto para el modelo"""
|
||
features = [
|
||
project.spi,
|
||
project.cpi,
|
||
project.physical_progress,
|
||
project.financial_progress,
|
||
project.budget_size / 1_000_000, # Normalizado
|
||
project.duration_months,
|
||
project.team_experience_years,
|
||
project.weather_risk_score,
|
||
project.market_conditions_index,
|
||
project.client_payment_history_score,
|
||
project.contractor_reliability_score,
|
||
# ... mas features
|
||
]
|
||
return np.array(features).reshape(1, -1)
|
||
|
||
def predict_cost_overrun_risk(self, project):
|
||
"""Predice probabilidad y magnitud de sobrecosto"""
|
||
features = self.prepare_features(project)
|
||
|
||
# Clasificacion: Bajo/Medio/Alto
|
||
risk_level = self.rf_model.predict(features)[0]
|
||
risk_prob = self.rf_model.predict_proba(features)[0]
|
||
|
||
# Regresion: Magnitud del sobrecosto
|
||
overrun_amount = self.nn_model.predict(features)[0]
|
||
|
||
return {
|
||
'risk_level': risk_level,
|
||
'probability': risk_prob[risk_level],
|
||
'estimated_overrun': overrun_amount,
|
||
'confidence': self.calculate_confidence(features)
|
||
}
|
||
|
||
def identify_risk_factors(self, project):
|
||
"""Identifica factores que contribuyen al riesgo"""
|
||
features = self.prepare_features(project)
|
||
|
||
# Feature importance de Random Forest
|
||
importances = self.rf_model.feature_importances_
|
||
|
||
risk_factors = []
|
||
feature_names = ['SPI', 'CPI', 'Avance', ...]
|
||
|
||
for idx, importance in enumerate(importances):
|
||
if importance > 0.1: # Umbral de relevancia
|
||
risk_factors.append({
|
||
'factor': feature_names[idx],
|
||
'importance': importance,
|
||
'current_value': features[0][idx]
|
||
})
|
||
|
||
return sorted(risk_factors, key=lambda x: x['importance'], reverse=True)
|
||
|
||
def recommend_actions(self, risk_factors, historical_projects):
|
||
"""Genera recomendaciones basadas en proyectos historicos"""
|
||
recommendations = []
|
||
|
||
# Buscar proyectos similares que mitigaron exitosamente
|
||
similar_successful = self.find_similar_successful_projects(
|
||
risk_factors, historical_projects
|
||
)
|
||
|
||
for project in similar_successful:
|
||
actions_taken = project.mitigation_actions
|
||
effectiveness = project.risk_reduction_achieved
|
||
|
||
recommendations.append({
|
||
'action': actions_taken,
|
||
'effectiveness': effectiveness,
|
||
'based_on_project': project.name
|
||
})
|
||
|
||
return recommendations
|
||
```
|
||
|
||
---
|
||
|
||
### CU-BI-014: Simulacion de Escenarios What-If
|
||
|
||
**Actor:** Gerente de Proyecto, Director de Operaciones, CFO
|
||
**Precondiciones:**
|
||
- Proyecto activo con datos base
|
||
- Parametros de simulacion definidos
|
||
|
||
**Flujo Principal:**
|
||
|
||
1. Usuario accede a simulador de escenarios
|
||
2. Usuario define escenario base (situacion actual del proyecto)
|
||
3. Usuario configura variables a modificar:
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Simulador de Escenarios What-If │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Escenario Base: Fraccionamiento Del Valle (Actual) │
|
||
│ │
|
||
│ ┌─ Variables a Modificar ──────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ ☑ Productividad de Cuadrillas │ │
|
||
│ │ Actual: 100% │ │
|
||
│ │ Modificar a: [120% ] (+20%) │ │
|
||
│ │ Costo: +$800K (horas extra) │ │
|
||
│ │ │ │
|
||
│ │ ☑ Precio de Materiales │ │
|
||
│ │ Actual: $45M presupuestado │ │
|
||
│ │ Modificar a: [110% ] (+10%) │ │
|
||
│ │ Costo: +$4.5M │ │
|
||
│ │ │ │
|
||
│ │ ☑ Duracion de Fase Critica │ │
|
||
│ │ Actual: 6 meses │ │
|
||
│ │ Modificar a: [5 meses ] (-17%) │ │
|
||
│ │ (Fast-tracking) │ │
|
||
│ │ │ │
|
||
│ │ ☐ Condiciones Climaticas │ │
|
||
│ │ Actual: Normal │ │
|
||
│ │ Modificar a: [▼ Normal ] │ │
|
||
│ │ │ │
|
||
│ │ ☑ Financiamiento │ │
|
||
│ │ Actual: Tasa 12% anual │ │
|
||
│ │ Modificar a: [9% ] (-3pp) │ │
|
||
│ │ Ahorro: -$1.2M en intereses │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ [Simular] [Limpiar] [Guardar] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
4. Usuario hace clic en "Simular"
|
||
5. Sistema ejecuta simulacion Monte Carlo (1000 iteraciones)
|
||
6. Sistema muestra resultados comparativos:
|
||
```
|
||
┌─────────────────────────────────────────────────────┐
|
||
│ Resultados de Simulacion │
|
||
├─────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─ Comparacion Base vs Escenario ──────────────┐ │
|
||
│ │ │ │
|
||
│ │ │ Base │ Escenario │ Delta │ │
|
||
│ │ ──────────────┼──────────┼───────────┼────── │ │
|
||
│ │ Costo Final │ $125.5M │ $128.6M │ +2.5% │ │
|
||
│ │ Fecha Termino │ 15/08/26 │ 01/07/26 │ -45d │ │
|
||
│ │ Margen Neto │ 18.2% │ 17.1% │ -1.1pp│ │
|
||
│ │ ROI │ 24.5% │ 23.2% │ -1.3pp│ │
|
||
│ │ Riesgo Retraso│ 65% │ 35% │ -30pp │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Analisis de Sensibilidad ───────────────────┐ │
|
||
│ │ │ │
|
||
│ │ Impacto en Costo Final: │ │
|
||
│ │ Precio Materiales (+10%): +$4.5M (3.6%) │ │
|
||
│ │ Productividad (+20%): +$0.8M (0.6%) │ │
|
||
│ │ Financiamiento (-3pp): -$1.2M (-1.0%) │ │
|
||
│ │ Fast-tracking: +$2.5M (2.0%) │ │
|
||
│ │ ────────────── │ │
|
||
│ │ TOTAL NETO: +$6.6M (+5.3%) │ │
|
||
│ │ │ │
|
||
│ │ Impacto en Plazo: │ │
|
||
│ │ Productividad (+20%): -25 dias │ │
|
||
│ │ Fast-tracking: -30 dias │ │
|
||
│ │ Riesgo climatico: +10 dias │ │
|
||
│ │ ────────────── │ │
|
||
│ │ TOTAL NETO: -45 dias │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Distribucion de Probabilidades ─────────────┐ │
|
||
│ │ │ │
|
||
│ │ Costo Final: │ │
|
||
│ │ │ │
|
||
│ │ 30│ ╱─╲ │ │
|
||
│ │ 25│ ╱ ╲ │ │
|
||
│ │ 20│ ╱ ╲ │ │
|
||
│ │ 15│ ╱ ╲ │ │
|
||
│ │ 10│ ╱─╱ ╲─╲ │ │
|
||
│ │ 5│─╱ ╲── │ │
|
||
│ │ 0└──────────────────────────→ │ │
|
||
│ │ $120M $125M $130M $135M │ │
|
||
│ │ │ │
|
||
│ │ P10: $122.5M | P50: $128.6M | P90: $135.2M│ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌─ Recomendacion ──────────────────────────────┐ │
|
||
│ │ │ │
|
||
│ │ ✅ IMPLEMENTAR ESCENARIO │ │
|
||
│ │ │ │
|
||
│ │ Justificacion: │ │
|
||
│ │ • Reduce riesgo de retraso de 65% a 35% │ │
|
||
│ │ • Entrega 45 dias antes (critico para │ │
|
||
│ │ cumplir compromiso con cliente) │ │
|
||
│ │ • Costo adicional de $6.6M es aceptable │ │
|
||
│ │ considerando penalizaciones por retraso │ │
|
||
│ │ ($15M si no entrega 30/06/26) │ │
|
||
│ │ │ │
|
||
│ │ ROI del Escenario: │ │
|
||
│ │ Inversion: $6.6M │ │
|
||
│ │ Evita penalizacion: $15M │ │
|
||
│ │ Retorno Neto: $8.4M (127% ROI) │ │
|
||
│ └───────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ [Exportar] [Crear Plan de Accion] [Comparar Mas] │
|
||
└─────────────────────────────────────────────────────┘
|
||
```
|
||
7. Usuario puede crear escenarios adicionales para comparar
|
||
8. Usuario puede guardar escenarios favoritos
|
||
9. Usuario exporta analisis comparativo para presentar a direccion
|
||
|
||
**Postcondiciones:**
|
||
- Escenarios guardados para referencia futura
|
||
- Decision documentada con justificacion cuantitativa
|
||
|
||
---
|
||
|
||
## 3. Requerimientos Funcionales
|
||
|
||
### RF-BI-003.1: Prediccion de Costos Finales
|
||
- El sistema DEBE predecir costo final usando minimo 3 metodos (EAC, regresion, curva S)
|
||
- El sistema DEBE calcular nivel de confianza de prediccion (minimo 70% para alertar)
|
||
- El sistema DEBE mostrar rango de estimacion (optimista, esperado, pesimista)
|
||
- El sistema DEBE identificar partidas con mayor varianza
|
||
- El sistema DEBE generar recomendaciones de mitigacion
|
||
- El sistema DEBE alertar automaticamente si sobrecosto proyectado > umbral
|
||
|
||
### RF-BI-003.2: Proyeccion de Fechas de Termino
|
||
- El sistema DEBE calcular fecha estimada basada en velocidad historica
|
||
- El sistema DEBE proyectar 3 escenarios (optimista, esperado, pesimista)
|
||
- El sistema DEBE identificar hitos criticos en riesgo
|
||
- El sistema DEBE sugerir acciones correctivas para recuperar cronograma
|
||
- El sistema DEBE calcular impacto de acciones correctivas en plazo y costo
|
||
- El sistema DEBE considerar factores externos (clima, disponibilidad recursos)
|
||
|
||
### RF-BI-003.3: Analisis de Tendencias Historicas
|
||
- El sistema DEBE analizar minimo 5 proyectos historicos completados
|
||
- El sistema DEBE calcular tendencias por periodo (trimestral, anual)
|
||
- El sistema DEBE identificar correlaciones entre variables (r > 0.6)
|
||
- El sistema DEBE segmentar analisis por tipo de proyecto
|
||
- El sistema DEBE detectar patrones estadisticamente significativos (p < 0.05)
|
||
- El sistema DEBE generar insights accionables
|
||
|
||
### RF-BI-003.4: Identificacion de Riesgos con IA
|
||
- El sistema DEBE aplicar modelos de ML entrenados con proyectos historicos
|
||
- El sistema DEBE clasificar riesgos en 4 niveles (critico, alto, medio, bajo)
|
||
- El sistema DEBE calcular probabilidad e impacto de cada riesgo
|
||
- El sistema DEBE identificar factores contribuyentes a cada riesgo
|
||
- El sistema DEBE generar recomendaciones de mitigacion basadas en casos exitosos
|
||
- El sistema DEBE mostrar confianza del modelo (minimo 75%)
|
||
- El sistema DEBE permitir configurar alertas automaticas por riesgo
|
||
|
||
### RF-BI-003.5: Simulacion de Escenarios What-If
|
||
- El sistema DEBE permitir modificar minimo 5 variables simultaneamente
|
||
- El sistema DEBE ejecutar simulacion Monte Carlo con minimo 1000 iteraciones
|
||
- El sistema DEBE calcular distribucion de probabilidades de resultados
|
||
- El sistema DEBE mostrar analisis de sensibilidad de variables
|
||
- El sistema DEBE permitir comparar hasta 5 escenarios simultaneamente
|
||
- El sistema DEBE calcular ROI de cada escenario
|
||
- El sistema DEBE guardar escenarios para analisis futuro
|
||
|
||
### RF-BI-003.6: Reentrenamiento de Modelos
|
||
- El sistema DEBE reentrenar modelos de ML mensualmente con nuevos datos
|
||
- El sistema DEBE validar precision de modelos (minimo 80% accuracy)
|
||
- El sistema DEBE notificar cuando precision de modelo cae <75%
|
||
- El sistema DEBE mantener version history de modelos
|
||
|
||
---
|
||
|
||
## 4. Modelo de Datos
|
||
|
||
```typescript
|
||
// Prediccion de Costos
|
||
interface CostPrediction {
|
||
id: string;
|
||
projectId: string;
|
||
predictionDate: Date;
|
||
|
||
currentState: {
|
||
budgetOriginal: number;
|
||
costToDate: number;
|
||
physicalProgress: number;
|
||
financialProgress: number;
|
||
cpi: number;
|
||
spi: number;
|
||
};
|
||
|
||
predictions: {
|
||
method: 'EAC_CPI' | 'LINEAR_REGRESSION' | 'S_CURVE' | 'ENSEMBLE';
|
||
finalCost: number;
|
||
variance: number;
|
||
variancePercent: number;
|
||
confidence: number; // 0-100%
|
||
}[];
|
||
|
||
ensemble: {
|
||
finalCost: number;
|
||
variance: number;
|
||
variancePercent: number;
|
||
confidence: number;
|
||
|
||
scenarios: {
|
||
optimistic: { cost: number; probability: number };
|
||
expected: { cost: number; probability: number };
|
||
pessimistic: { cost: number; probability: number };
|
||
};
|
||
};
|
||
|
||
contributingFactors: {
|
||
factor: string;
|
||
impact: number; // en pesos
|
||
importance: number; // 0-1
|
||
}[];
|
||
|
||
recommendations: {
|
||
action: string;
|
||
estimatedSavings: number;
|
||
effort: 'low' | 'medium' | 'high';
|
||
priority: number;
|
||
}[];
|
||
|
||
alertTriggered: boolean;
|
||
createdAt: Date;
|
||
}
|
||
|
||
// Proyeccion de Fechas
|
||
interface SchedulePrediction {
|
||
id: string;
|
||
projectId: string;
|
||
predictionDate: Date;
|
||
|
||
currentState: {
|
||
startDate: Date;
|
||
plannedEndDate: Date;
|
||
currentProgress: number;
|
||
currentDate: Date;
|
||
spi: number;
|
||
};
|
||
|
||
velocityAnalysis: {
|
||
avgMonthlyProgress: number;
|
||
last3MonthsVelocity: number[];
|
||
trend: 'accelerating' | 'stable' | 'decelerating';
|
||
};
|
||
|
||
predictions: {
|
||
estimatedEndDate: Date;
|
||
delayDays: number;
|
||
confidence: number;
|
||
|
||
scenarios: {
|
||
optimistic: { endDate: Date; spi: number };
|
||
expected: { endDate: Date; spi: number };
|
||
pessimistic: { endDate: Date; spi: number };
|
||
};
|
||
};
|
||
|
||
criticalMilestones: {
|
||
milestoneId: string;
|
||
name: string;
|
||
plannedDate: Date;
|
||
estimatedDate: Date;
|
||
atRisk: boolean;
|
||
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
||
}[];
|
||
|
||
correctiveActions: {
|
||
action: string;
|
||
scheduleImpact: number; // dias recuperados
|
||
costImpact: number;
|
||
feasibility: 'low' | 'medium' | 'high';
|
||
priority: number;
|
||
}[];
|
||
|
||
externalFactors: {
|
||
factor: string; // 'weather', 'resource_availability', etc.
|
||
impact: number; // dias
|
||
probability: number;
|
||
}[];
|
||
|
||
createdAt: Date;
|
||
}
|
||
|
||
// Analisis de Tendencias
|
||
interface TrendAnalysis {
|
||
id: string;
|
||
metric: 'cost_variance' | 'schedule_variance' | 'margin' | 'roi';
|
||
analysisDate: Date;
|
||
|
||
timeRange: {
|
||
from: Date;
|
||
to: Date;
|
||
};
|
||
|
||
projectsAnalyzed: {
|
||
total: number;
|
||
projectIds: string[];
|
||
};
|
||
|
||
overallTrend: {
|
||
direction: 'improving' | 'stable' | 'worsening';
|
||
averageValue: number;
|
||
changePercent: number;
|
||
periodComparison: {
|
||
period: string; // "Q1-2024", "2023", etc.
|
||
value: number;
|
||
}[];
|
||
};
|
||
|
||
segmentation: {
|
||
dimension: string; // 'project_type', 'budget_range', etc.
|
||
segments: {
|
||
name: string;
|
||
projectCount: number;
|
||
averageValue: number;
|
||
trend: 'improving' | 'stable' | 'worsening';
|
||
}[];
|
||
}[];
|
||
|
||
correlations: {
|
||
variable1: string;
|
||
variable2: string;
|
||
coefficient: number; // Pearson correlation -1 to 1
|
||
strength: 'weak' | 'moderate' | 'strong';
|
||
pValue: number;
|
||
significant: boolean; // p < 0.05
|
||
}[];
|
||
|
||
patterns: {
|
||
description: string;
|
||
confidence: number; // 0-100%
|
||
sampleSize: number;
|
||
examples: string[]; // project IDs
|
||
}[];
|
||
|
||
insights: {
|
||
insight: string;
|
||
actionable: boolean;
|
||
relatedProjects: string[];
|
||
}[];
|
||
|
||
createdBy: string;
|
||
createdAt: Date;
|
||
}
|
||
|
||
// Identificacion de Riesgos con IA
|
||
interface AIRiskAnalysis {
|
||
id: string;
|
||
projectId: string;
|
||
analysisDate: Date;
|
||
|
||
overallRiskScore: number; // 0-100
|
||
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
||
|
||
modelInfo: {
|
||
modelVersion: string;
|
||
confidence: number; // 0-100%
|
||
lastTrainedDate: Date;
|
||
accuracy: number; // 0-100%
|
||
};
|
||
|
||
risks: {
|
||
id: string;
|
||
type: 'cost_overrun' | 'schedule_delay' | 'quality_issue' | 'liquidity_crisis' | 'safety_incident';
|
||
name: string;
|
||
description: string;
|
||
|
||
riskLevel: 'low' | 'medium' | 'high' | 'critical';
|
||
probability: number; // 0-100%
|
||
impact: {
|
||
cost?: number;
|
||
schedule?: number; // dias
|
||
quality?: string;
|
||
safety?: string;
|
||
};
|
||
|
||
contributingFactors: {
|
||
factor: string;
|
||
currentValue: any;
|
||
threshold: any;
|
||
importance: number; // 0-1 (from model feature importance)
|
||
}[];
|
||
|
||
recommendedActions: {
|
||
action: string;
|
||
effectiveness: number; // 0-100% based on historical data
|
||
basedOnProjects: string[]; // IDs de proyectos donde funciono
|
||
cost: number;
|
||
effort: 'low' | 'medium' | 'high';
|
||
priority: number;
|
||
}[];
|
||
|
||
historicalComparison: {
|
||
similarProjectsCount: number;
|
||
percentileRank: number; // 0-100
|
||
successfulMitigationRate: number; // 0-100%
|
||
};
|
||
}[];
|
||
|
||
alerts: {
|
||
riskId: string;
|
||
threshold: number;
|
||
currentValue: number;
|
||
alertType: 'email' | 'sms' | 'dashboard';
|
||
recipients: string[];
|
||
enabled: boolean;
|
||
}[];
|
||
|
||
createdAt: Date;
|
||
}
|
||
|
||
// Simulacion de Escenarios
|
||
interface ScenarioSimulation {
|
||
id: string;
|
||
projectId: string;
|
||
name: string;
|
||
description: string;
|
||
|
||
baseScenario: {
|
||
cost: number;
|
||
duration: number;
|
||
endDate: Date;
|
||
margin: number;
|
||
roi: number;
|
||
};
|
||
|
||
variables: {
|
||
name: string;
|
||
type: 'productivity' | 'material_price' | 'duration' | 'interest_rate' | 'weather' | 'resource_availability';
|
||
baseValue: any;
|
||
modifiedValue: any;
|
||
changePercent: number;
|
||
cost: number; // costo de implementar el cambio
|
||
}[];
|
||
|
||
simulationConfig: {
|
||
iterations: number; // Monte Carlo iterations
|
||
method: 'monte_carlo' | 'discrete_event' | 'system_dynamics';
|
||
randomSeed?: number;
|
||
};
|
||
|
||
results: {
|
||
cost: {
|
||
expected: number;
|
||
p10: number; // 10th percentile
|
||
p50: number; // median
|
||
p90: number; // 90th percentile
|
||
variance: number;
|
||
variancePercent: number;
|
||
};
|
||
|
||
schedule: {
|
||
expectedEndDate: Date;
|
||
p10EndDate: Date;
|
||
p50EndDate: Date;
|
||
p90EndDate: Date;
|
||
delayDays: number;
|
||
};
|
||
|
||
margin: {
|
||
expected: number;
|
||
p10: number;
|
||
p50: number;
|
||
p90: number;
|
||
};
|
||
|
||
roi: {
|
||
expected: number;
|
||
p10: number;
|
||
p50: number;
|
||
p90: number;
|
||
};
|
||
};
|
||
|
||
sensitivityAnalysis: {
|
||
variable: string;
|
||
impactOnCost: number;
|
||
impactOnSchedule: number;
|
||
impactOnMargin: number;
|
||
elasticity: number; // % change in outcome / % change in variable
|
||
}[];
|
||
|
||
recommendation: {
|
||
implement: boolean;
|
||
justification: string;
|
||
netBenefit: number;
|
||
roiOfScenario: number;
|
||
};
|
||
|
||
comparisonWithBase: {
|
||
costDelta: number;
|
||
scheduleDelta: number;
|
||
marginDelta: number;
|
||
roiDelta: number;
|
||
};
|
||
|
||
createdBy: string;
|
||
createdAt: Date;
|
||
}
|
||
|
||
// ML Model Metadata
|
||
interface MLModel {
|
||
id: string;
|
||
name: string;
|
||
type: 'classification' | 'regression' | 'clustering';
|
||
purpose: 'cost_prediction' | 'risk_identification' | 'schedule_forecasting';
|
||
|
||
version: string;
|
||
trainedDate: Date;
|
||
trainingDataset: {
|
||
projectCount: number;
|
||
features: string[];
|
||
timeRange: { from: Date; to: Date };
|
||
};
|
||
|
||
performance: {
|
||
accuracy: number; // 0-100%
|
||
precision: number;
|
||
recall: number;
|
||
f1Score: number;
|
||
mse?: number; // Mean Squared Error for regression
|
||
r2?: number; // R-squared for regression
|
||
};
|
||
|
||
hyperparameters: Record<string, any>;
|
||
|
||
status: 'active' | 'deprecated' | 'testing';
|
||
filePath: string; // path to saved model file
|
||
|
||
createdBy: string;
|
||
createdAt: Date;
|
||
}
|
||
```
|
||
|
||
### SQL Schema
|
||
|
||
```sql
|
||
-- Cost Predictions
|
||
CREATE TABLE cost_predictions (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
project_id UUID NOT NULL REFERENCES projects(id),
|
||
prediction_date TIMESTAMP NOT NULL,
|
||
|
||
current_state JSONB NOT NULL,
|
||
predictions JSONB NOT NULL,
|
||
ensemble JSONB NOT NULL,
|
||
contributing_factors JSONB,
|
||
recommendations JSONB,
|
||
|
||
alert_triggered BOOLEAN DEFAULT false,
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_cost_pred_project (project_id),
|
||
INDEX idx_cost_pred_date (prediction_date),
|
||
INDEX idx_cost_pred_alert (alert_triggered) WHERE alert_triggered = true
|
||
);
|
||
|
||
-- Schedule Predictions
|
||
CREATE TABLE schedule_predictions (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
project_id UUID NOT NULL REFERENCES projects(id),
|
||
prediction_date TIMESTAMP NOT NULL,
|
||
|
||
current_state JSONB NOT NULL,
|
||
velocity_analysis JSONB NOT NULL,
|
||
predictions JSONB NOT NULL,
|
||
critical_milestones JSONB,
|
||
corrective_actions JSONB,
|
||
external_factors JSONB,
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_schedule_pred_project (project_id),
|
||
INDEX idx_schedule_pred_date (prediction_date)
|
||
);
|
||
|
||
-- Trend Analysis
|
||
CREATE TABLE trend_analyses (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
metric VARCHAR(50) NOT NULL,
|
||
analysis_date TIMESTAMP NOT NULL,
|
||
|
||
time_range JSONB NOT NULL,
|
||
projects_analyzed JSONB NOT NULL,
|
||
overall_trend JSONB NOT NULL,
|
||
segmentation JSONB,
|
||
correlations JSONB,
|
||
patterns JSONB,
|
||
insights JSONB,
|
||
|
||
created_by UUID NOT NULL REFERENCES users(id),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_trend_metric (metric),
|
||
INDEX idx_trend_date (analysis_date)
|
||
);
|
||
|
||
-- AI Risk Analysis
|
||
CREATE TABLE ai_risk_analyses (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
project_id UUID NOT NULL REFERENCES projects(id),
|
||
analysis_date TIMESTAMP NOT NULL,
|
||
|
||
overall_risk_score NUMERIC(5,2) NOT NULL CHECK (overall_risk_score BETWEEN 0 AND 100),
|
||
risk_level VARCHAR(20) NOT NULL,
|
||
|
||
model_info JSONB NOT NULL,
|
||
risks JSONB NOT NULL,
|
||
alerts JSONB,
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_ai_risk_project (project_id),
|
||
INDEX idx_ai_risk_score (overall_risk_score),
|
||
INDEX idx_ai_risk_level (risk_level)
|
||
);
|
||
|
||
-- Scenario Simulations
|
||
CREATE TABLE scenario_simulations (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
project_id UUID NOT NULL REFERENCES projects(id),
|
||
name VARCHAR(255) NOT NULL,
|
||
description TEXT,
|
||
|
||
base_scenario JSONB NOT NULL,
|
||
variables JSONB NOT NULL,
|
||
simulation_config JSONB NOT NULL,
|
||
results JSONB NOT NULL,
|
||
sensitivity_analysis JSONB,
|
||
recommendation JSONB,
|
||
comparison_with_base JSONB,
|
||
|
||
created_by UUID NOT NULL REFERENCES users(id),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_scenario_project (project_id),
|
||
INDEX idx_scenario_creator (created_by)
|
||
);
|
||
|
||
-- ML Models
|
||
CREATE TABLE ml_models (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
name VARCHAR(255) NOT NULL,
|
||
type VARCHAR(50) NOT NULL,
|
||
purpose VARCHAR(100) NOT NULL,
|
||
|
||
version VARCHAR(20) NOT NULL,
|
||
trained_date TIMESTAMP NOT NULL,
|
||
training_dataset JSONB NOT NULL,
|
||
performance JSONB NOT NULL,
|
||
hyperparameters JSONB,
|
||
|
||
status VARCHAR(20) DEFAULT 'active',
|
||
file_path VARCHAR(500) NOT NULL,
|
||
|
||
created_by UUID NOT NULL REFERENCES users(id),
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
UNIQUE(name, version),
|
||
INDEX idx_ml_model_purpose (purpose),
|
||
INDEX idx_ml_model_status (status)
|
||
);
|
||
|
||
-- Prediction History (para tracking de accuracy)
|
||
CREATE TABLE prediction_history (
|
||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||
prediction_id UUID NOT NULL,
|
||
prediction_type VARCHAR(50) NOT NULL, -- 'cost', 'schedule', 'risk'
|
||
|
||
predicted_value NUMERIC,
|
||
predicted_date TIMESTAMP NOT NULL,
|
||
|
||
actual_value NUMERIC,
|
||
actual_date TIMESTAMP,
|
||
|
||
error NUMERIC,
|
||
error_percent NUMERIC,
|
||
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
|
||
INDEX idx_pred_history_type (prediction_type),
|
||
INDEX idx_pred_history_date (predicted_date)
|
||
);
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Criterios de Aceptacion
|
||
|
||
### Prediccion de Costos
|
||
- [ ] Prediccion usa minimo 3 metodos diferentes (EAC, regresion, curva S)
|
||
- [ ] Ensemble combina predicciones con pesos configurables
|
||
- [ ] Nivel de confianza se calcula correctamente (basado en desviacion estandar)
|
||
- [ ] Rango de escenarios cubre P10-P90 de distribucion
|
||
- [ ] Factores contribuyentes se ordenan por importancia
|
||
- [ ] Recomendaciones son especificas y accionables
|
||
- [ ] Alerta se dispara automaticamente si sobrecosto > umbral configurado
|
||
- [ ] Prediccion tiene precision ±10% vs costo final real
|
||
|
||
### Proyeccion de Fechas
|
||
- [ ] Calculo de velocidad considera ultimos 3 meses minimo
|
||
- [ ] Escenarios optimista/pesimista consideran ±20% variabilidad
|
||
- [ ] Hitos criticos se identifican correctamente (ruta critica)
|
||
- [ ] Acciones correctivas muestran impacto cuantitativo en plazo y costo
|
||
- [ ] Factores externos (clima) se incorporan en prediccion
|
||
- [ ] Proyeccion tiene precision ±15 dias vs fecha real de termino
|
||
|
||
### Analisis de Tendencias
|
||
- [ ] Analisis incluye minimo 5 proyectos completados
|
||
- [ ] Tendencias se calculan por periodo (trimestral, anual)
|
||
- [ ] Correlaciones con |r| > 0.6 se destacan como significativas
|
||
- [ ] Prueba de significancia estadistica (p-value < 0.05)
|
||
- [ ] Patrones tienen confianza > 70%
|
||
- [ ] Insights son accionables y especificos
|
||
|
||
### Identificacion de Riesgos IA
|
||
- [ ] Modelo tiene accuracy > 80% en dataset de validacion
|
||
- [ ] Riesgos se clasifican en 4 niveles correctamente
|
||
- [ ] Probabilidad e impacto se calculan consistentemente
|
||
- [ ] Factores contribuyentes ordenados por feature importance
|
||
- [ ] Recomendaciones basadas en proyectos historicos similares
|
||
- [ ] Confianza del modelo > 75% para mostrar prediccion
|
||
- [ ] Alertas configurables por tipo de riesgo y umbral
|
||
- [ ] Precision del modelo se valida mensualmente vs resultados reales
|
||
|
||
### Simulacion de Escenarios
|
||
- [ ] Simulacion Monte Carlo ejecuta minimo 1000 iteraciones
|
||
- [ ] Se pueden modificar hasta 10 variables simultaneamente
|
||
- [ ] Distribucion de probabilidades se visualiza correctamente (histograma)
|
||
- [ ] Analisis de sensibilidad identifica variables con mayor impacto
|
||
- [ ] Comparacion de escenarios muestra deltas claramente
|
||
- [ ] ROI de escenario se calcula correctamente
|
||
- [ ] Escenarios guardados se pueden recargar fielmente
|
||
- [ ] Simulacion completa en <10 segundos para proyecto tipico
|
||
|
||
### Reentrenamiento de Modelos
|
||
- [ ] Modelos se reentrenan automaticamente cada mes
|
||
- [ ] Nuevos datos de proyectos completados se incorporan
|
||
- [ ] Accuracy se valida antes de promover modelo a produccion
|
||
- [ ] Notificacion se envia si accuracy cae <75%
|
||
- [ ] Version history de modelos se mantiene (minimo 6 meses)
|
||
- [ ] Rollback a version anterior funciona correctamente
|
||
|
||
---
|
||
|
||
## 6. Notas Tecnicas
|
||
|
||
### Implementacion de Prediccion con Ensemble
|
||
|
||
```python
|
||
import numpy as np
|
||
from sklearn.linear_model import LinearRegression
|
||
from scipy.optimize import curve_fit
|
||
|
||
class CostPredictor:
|
||
def __init__(self, project):
|
||
self.project = project
|
||
self.budget = project.budget_original
|
||
self.cost_to_date = project.cost_accumulated
|
||
self.physical_progress = project.physical_progress / 100
|
||
self.cpi = project.cpi
|
||
|
||
def predict_eac_cpi(self):
|
||
"""Estimate at Completion basado en CPI"""
|
||
if self.cpi == 0:
|
||
return None
|
||
|
||
eac = self.budget / self.cpi
|
||
confidence = self._calculate_confidence_cpi()
|
||
|
||
return {
|
||
'method': 'EAC_CPI',
|
||
'final_cost': eac,
|
||
'variance': eac - self.budget,
|
||
'variance_percent': ((eac - self.budget) / self.budget) * 100,
|
||
'confidence': confidence
|
||
}
|
||
|
||
def predict_linear_regression(self):
|
||
"""Regresion lineal sobre puntos historicos"""
|
||
historical_data = self.project.get_historical_cost_data()
|
||
|
||
if len(historical_data) < 3:
|
||
return None
|
||
|
||
X = np.array([[d['progress']] for d in historical_data])
|
||
y = np.array([[d['cost']] for d in historical_data])
|
||
|
||
model = LinearRegression()
|
||
model.fit(X, y)
|
||
|
||
final_cost = model.predict([[1.0]])[0][0] # 100% progress
|
||
confidence = model.score(X, y) * 100 # R²
|
||
|
||
return {
|
||
'method': 'LINEAR_REGRESSION',
|
||
'final_cost': final_cost,
|
||
'variance': final_cost - self.budget,
|
||
'variance_percent': ((final_cost - self.budget) / self.budget) * 100,
|
||
'confidence': confidence
|
||
}
|
||
|
||
def predict_s_curve(self):
|
||
"""Ajuste de curva S (sigmoid)"""
|
||
historical_data = self.project.get_historical_cost_data()
|
||
|
||
if len(historical_data) < 5:
|
||
return None
|
||
|
||
progress = np.array([d['progress'] for d in historical_data])
|
||
costs = np.array([d['cost'] for d in historical_data])
|
||
|
||
# Curva S: f(x) = L / (1 + exp(-k*(x - x0)))
|
||
def s_curve(x, L, k, x0):
|
||
return L / (1 + np.exp(-k * (x - x0)))
|
||
|
||
try:
|
||
# Initial guess
|
||
p0 = [self.budget * 1.1, 10, 0.5]
|
||
params, covariance = curve_fit(s_curve, progress, costs, p0=p0, maxfev=10000)
|
||
|
||
final_cost = params[0] # L parameter = asymptote
|
||
|
||
# Calculate R² for confidence
|
||
y_pred = s_curve(progress, *params)
|
||
ss_res = np.sum((costs - y_pred) ** 2)
|
||
ss_tot = np.sum((costs - np.mean(costs)) ** 2)
|
||
r_squared = 1 - (ss_res / ss_tot)
|
||
confidence = r_squared * 100
|
||
|
||
return {
|
||
'method': 'S_CURVE',
|
||
'final_cost': final_cost,
|
||
'variance': final_cost - self.budget,
|
||
'variance_percent': ((final_cost - self.budget) / self.budget) * 100,
|
||
'confidence': confidence
|
||
}
|
||
except:
|
||
return None
|
||
|
||
def predict_ensemble(self):
|
||
"""Combina multiples metodos con pesos"""
|
||
predictions = []
|
||
|
||
eac = self.predict_eac_cpi()
|
||
if eac: predictions.append(eac)
|
||
|
||
regression = self.predict_linear_regression()
|
||
if regression: predictions.append(regression)
|
||
|
||
s_curve = self.predict_s_curve()
|
||
if s_curve: predictions.append(s_curve)
|
||
|
||
if len(predictions) == 0:
|
||
return None
|
||
|
||
# Pesos basados en confianza
|
||
weights = np.array([p['confidence'] for p in predictions])
|
||
weights = weights / np.sum(weights) # Normalizar
|
||
|
||
# Prediccion ponderada
|
||
final_cost = np.sum([p['final_cost'] * w for p, w in zip(predictions, weights)])
|
||
confidence = np.mean([p['confidence'] for p in predictions])
|
||
|
||
# Calcular escenarios
|
||
std_error = np.std([p['final_cost'] for p in predictions])
|
||
|
||
scenarios = {
|
||
'optimistic': {
|
||
'cost': final_cost - 1.28 * std_error, # P10
|
||
'probability': 10
|
||
},
|
||
'expected': {
|
||
'cost': final_cost,
|
||
'probability': 50
|
||
},
|
||
'pessimistic': {
|
||
'cost': final_cost + 1.28 * std_error, # P90
|
||
'probability': 90
|
||
}
|
||
}
|
||
|
||
return {
|
||
'final_cost': final_cost,
|
||
'variance': final_cost - self.budget,
|
||
'variance_percent': ((final_cost - self.budget) / self.budget) * 100,
|
||
'confidence': confidence,
|
||
'scenarios': scenarios,
|
||
'methods_used': [p['method'] for p in predictions],
|
||
'individual_predictions': predictions
|
||
}
|
||
|
||
def _calculate_confidence_cpi(self):
|
||
"""Calcula confianza basada en estabilidad de CPI"""
|
||
historical_cpi = self.project.get_historical_cpi()
|
||
|
||
if len(historical_cpi) < 3:
|
||
return 50.0
|
||
|
||
# Menos variabilidad = mayor confianza
|
||
std_cpi = np.std(historical_cpi)
|
||
mean_cpi = np.mean(historical_cpi)
|
||
|
||
coefficient_of_variation = std_cpi / mean_cpi if mean_cpi != 0 else 1
|
||
|
||
# Convertir CV a confianza (0-100%)
|
||
confidence = max(0, min(100, (1 - coefficient_of_variation) * 100))
|
||
|
||
return confidence
|
||
|
||
# Usage
|
||
predictor = CostPredictor(project)
|
||
prediction = predictor.predict_ensemble()
|
||
|
||
if prediction and prediction['variance_percent'] > THRESHOLD:
|
||
send_alert(project, prediction)
|
||
```
|
||
|
||
### Simulacion Monte Carlo para Escenarios
|
||
|
||
```python
|
||
import numpy as np
|
||
from dataclasses import dataclass
|
||
from typing import List, Dict
|
||
|
||
@dataclass
|
||
class Variable:
|
||
name: str
|
||
base_value: float
|
||
distribution: str # 'normal', 'triangular', 'uniform'
|
||
params: Dict # distribution parameters
|
||
|
||
class MonteCarloSimulator:
|
||
def __init__(self, project, variables: List[Variable], iterations=10000):
|
||
self.project = project
|
||
self.variables = variables
|
||
self.iterations = iterations
|
||
self.results = None
|
||
|
||
def run(self):
|
||
"""Ejecuta simulacion Monte Carlo"""
|
||
cost_results = []
|
||
duration_results = []
|
||
margin_results = []
|
||
|
||
for i in range(self.iterations):
|
||
# Generar valores aleatorios para cada variable
|
||
scenario_values = {}
|
||
for var in self.variables:
|
||
scenario_values[var.name] = self._sample_variable(var)
|
||
|
||
# Calcular metricas para este escenario
|
||
cost = self._calculate_cost(scenario_values)
|
||
duration = self._calculate_duration(scenario_values)
|
||
margin = self._calculate_margin(scenario_values)
|
||
|
||
cost_results.append(cost)
|
||
duration_results.append(duration)
|
||
margin_results.append(margin)
|
||
|
||
# Calcular estadisticas
|
||
self.results = {
|
||
'cost': {
|
||
'expected': np.mean(cost_results),
|
||
'p10': np.percentile(cost_results, 10),
|
||
'p50': np.percentile(cost_results, 50),
|
||
'p90': np.percentile(cost_results, 90),
|
||
'std': np.std(cost_results),
|
||
'distribution': cost_results
|
||
},
|
||
'duration': {
|
||
'expected': np.mean(duration_results),
|
||
'p10': np.percentile(duration_results, 10),
|
||
'p50': np.percentile(duration_results, 50),
|
||
'p90': np.percentile(duration_results, 90),
|
||
'std': np.std(duration_results),
|
||
'distribution': duration_results
|
||
},
|
||
'margin': {
|
||
'expected': np.mean(margin_results),
|
||
'p10': np.percentile(margin_results, 10),
|
||
'p50': np.percentile(margin_results, 50),
|
||
'p90': np.percentile(margin_results, 90),
|
||
'std': np.std(margin_results),
|
||
'distribution': margin_results
|
||
}
|
||
}
|
||
|
||
return self.results
|
||
|
||
def _sample_variable(self, var: Variable):
|
||
"""Genera valor aleatorio segun distribucion"""
|
||
if var.distribution == 'normal':
|
||
return np.random.normal(var.params['mean'], var.params['std'])
|
||
|
||
elif var.distribution == 'triangular':
|
||
return np.random.triangular(
|
||
var.params['left'],
|
||
var.params['mode'],
|
||
var.params['right']
|
||
)
|
||
|
||
elif var.distribution == 'uniform':
|
||
return np.random.uniform(var.params['low'], var.params['high'])
|
||
|
||
else:
|
||
return var.base_value
|
||
|
||
def _calculate_cost(self, scenario_values):
|
||
"""Calcula costo total para escenario"""
|
||
base_cost = self.project.budget_original
|
||
|
||
# Ajustar por precio de materiales
|
||
material_factor = scenario_values.get('material_price', 1.0)
|
||
material_cost = self.project.material_budget * material_factor
|
||
|
||
# Ajustar por productividad
|
||
productivity_factor = scenario_values.get('productivity', 1.0)
|
||
labor_cost = self.project.labor_budget / productivity_factor
|
||
|
||
# Ajustar por duracion (gastos indirectos)
|
||
duration_factor = scenario_values.get('duration_months', self.project.planned_duration) / self.project.planned_duration
|
||
indirect_cost = self.project.indirect_costs * duration_factor
|
||
|
||
total_cost = material_cost + labor_cost + indirect_cost + self.project.other_costs
|
||
|
||
return total_cost
|
||
|
||
def _calculate_duration(self, scenario_values):
|
||
"""Calcula duracion para escenario"""
|
||
base_duration = self.project.planned_duration
|
||
|
||
productivity_factor = scenario_values.get('productivity', 1.0)
|
||
weather_delay = scenario_values.get('weather_delay_days', 0)
|
||
|
||
duration = (base_duration / productivity_factor) + (weather_delay / 30) # convert days to months
|
||
|
||
return duration
|
||
|
||
def _calculate_margin(self, scenario_values):
|
||
"""Calcula margen para escenario"""
|
||
revenue = self.project.contract_value
|
||
cost = self._calculate_cost(scenario_values)
|
||
|
||
margin = ((revenue - cost) / revenue) * 100
|
||
|
||
return margin
|
||
|
||
def sensitivity_analysis(self):
|
||
"""Analiza sensibilidad de cada variable"""
|
||
sensitivities = []
|
||
|
||
base_results = self.run()
|
||
base_cost = base_results['cost']['expected']
|
||
|
||
for var in self.variables:
|
||
# Incrementar variable en 10%
|
||
original_value = var.base_value
|
||
var.params['mean'] = original_value * 1.1
|
||
|
||
new_results = self.run()
|
||
new_cost = new_results['cost']['expected']
|
||
|
||
# Calcular elasticidad
|
||
cost_change_percent = ((new_cost - base_cost) / base_cost) * 100
|
||
var_change_percent = 10
|
||
elasticity = cost_change_percent / var_change_percent
|
||
|
||
sensitivities.append({
|
||
'variable': var.name,
|
||
'impact_on_cost': new_cost - base_cost,
|
||
'elasticity': elasticity
|
||
})
|
||
|
||
# Restaurar valor original
|
||
var.params['mean'] = original_value
|
||
|
||
return sorted(sensitivities, key=lambda x: abs(x['elasticity']), reverse=True)
|
||
|
||
# Example usage
|
||
variables = [
|
||
Variable('material_price', 1.0, 'triangular', {'left': 0.95, 'mode': 1.0, 'right': 1.15}),
|
||
Variable('productivity', 1.0, 'normal', {'mean': 1.0, 'std': 0.1}),
|
||
Variable('weather_delay_days', 0, 'triangular', {'left': 0, 'mode': 10, 'right': 30})
|
||
]
|
||
|
||
simulator = MonteCarloSimulator(project, variables, iterations=10000)
|
||
results = simulator.run()
|
||
sensitivity = simulator.sensitivity_analysis()
|
||
```
|
||
|
||
---
|
||
|
||
**Fecha:** 2025-11-17
|
||
**Preparado por:** Equipo de Producto
|
||
**Version:** 1.0
|
||
**Estado:** Listo para Revision
|