66 KiB
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:
- Usuario accede a modulo de prediccion de costos
- Usuario selecciona proyecto "Fraccionamiento Del Valle"
- Sistema analiza datos historicos:
- Presupuesto original: $120M
- Costo acumulado: $35M (29%)
- Avance fisico: 25%
- Tendencia de costos ultimos 3 meses
- Sistema aplica algoritmo de regresion lineal y analisis de curva S
- 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] │ └─────────────────────────────────────────────────────┘ - Usuario puede ajustar parametros de prediccion
- Usuario puede explorar factores que afectan la prediccion
- Sistema guarda prediccion con timestamp para seguimiento
Postcondiciones:
- Prediccion registrada en historial
- CFO notificado si sobrecosto proyectado > umbral (ej: 5%)
Algoritmo de Prediccion:
# 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:
- Usuario solicita proyeccion de fecha de termino
- 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)
- 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 - 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] │ └─────────────────────────────────────────────────────┘ - Usuario puede simular acciones correctivas
- Sistema recalcula proyeccion con acciones propuestas
- 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:
- Usuario accede a modulo de analisis de tendencias
- Usuario selecciona metrica: "Varianza de Costo"
- 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] │ └─────────────────────────────────────────────────────┘ - Usuario explora correlaciones interesantes
- Usuario identifica mejores practicas de proyectos exitosos
- 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:
- Usuario solicita analisis de riesgos con IA
- Sistema recopila datos del proyecto:
- Metricas de desempeno (SPI, CPI, SV, CV)
- Historial de incidencias
- Condiciones externas (clima, mercado)
- Comparacion con proyectos similares
- Sistema aplica modelo de Machine Learning (Random Forest + Neural Network)
- 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] │ └─────────────────────────────────────────────────────┘ - Usuario revisa riesgos identificados
- Usuario crea plan de mitigacion para riesgos criticos
- 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:
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:
- Usuario accede a simulador de escenarios
- Usuario define escenario base (situacion actual del proyecto)
- 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] │ └─────────────────────────────────────────────────────┘ - Usuario hace clic en "Simular"
- Sistema ejecuta simulacion Monte Carlo (1000 iteraciones)
- 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] │ └─────────────────────────────────────────────────────┘ - Usuario puede crear escenarios adicionales para comparar
- Usuario puede guardar escenarios favoritos
- 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
// 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
-- 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
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
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