import numpy as np
from matplotlib import pyplot as plt
# Load data
x, y = np.loadtxt("data/data.txt").T
x_bb = np.sort(x)
y_bb = 5 * np.cos(0.5*np.pi*x_bb/2)
# Plot data
plt.figure(figsize=(16,8))
plt.plot(x, y, 'bs', alpha=0.5, label=u"Medición")
plt.plot(x_bb, y_bb, 'k-', lw=2.0, label=u"Relación determinista")
plt.xlim([-2.5,2.5])
plt.ylim([-5,10])
plt.xlabel("x []", fontsize=20)
plt.ylabel("y []", fontsize=20)
plt.legend(numpoints=1, loc="lower center", fontsize=20)
plt.show()

"""
Explanation: <header class="w3-container w3-teal">
<img src="images/utfsm.png" alt="" height="100px" align="left"/>
<img src="images/mat.png" alt="" height="100px" align="right"/>
</header>
<br/><br/><br/><br/><br/>
MAT281
Aplicaciones de la Matemática en la Ingeniería
Sebastián Flores
https://www.github.com/usantamaria/mat281
¿Qué contenido aprenderemos?

Errores de Modelamiento
Modelo predictivo

¿Porqué aprenderemos ese contenido?

Errores de Modelamiento

Conocer errores comunes permite no repetirlos.

Modelo predictivo

Porque nuestros modelos deben no sólo explicar lo conocido, sino predecir lo desconocido.
¿Porqué no aprendemos de los errores?


Antes: Modelo de publicación actual privilegia resultados exitosos, por sobre documentación de experimentos fallidos. Existe un sesgo de publicación (publication bias).


Durante: Nunca hay tiempo suficiente. Priorización del tiempo a obtener más y mejores resultados, no a examinar casos fallidos.


Después: Posible y fácil, pero rara vez realizado, puesto que es opcional y requiere fuerza de voluntad. Común en la milicia, bajo el nombre de debriefing. 


Debriefing
El Debriefing es un proceso semi-estructurado, que permite analizar una cierta actividad que ha sido llevada a cabo. Se realiza una serie de preguntas que permite que los participantes refleccionen en lo
ocurrido, los resultados y metas, para mejorar el desempeño futuro.
Debriefing

Certámenes y Tareas:
¿Cuál era la solución correcta?
¿Porqué no llegué a la solución?

¿Cómo debería haber estudiado para optimizar mi nota?


Proyectos en grupo:

¿Existieron problemas en el grupo?
¿Qué podría haberse hecho de mejor forma?
¿Cómo fue la interacción entre los integrantes?
¿Estamos conformes con el resultado dado el tiempo invertido?

Debriefing no altera resultados pasados, pero permite mejorar incrementalmente y detectar errores metodológicos.
<img src="images/Modelamiento.png" alt="" width="600px" align="middle"/>
Fuentes de Error
Fuentes de error: Instrumental
Las mediciones son siempre indirectas. Lo que se mide no es necesariamente lo que se necesita.


Longitud: comparación directa (regla), comparación indirecta (sensor laser).


Temperatura: mediante dilatación (termómetro tradicional), cambio de densidad ( termómetro de Galileo), o cambio de resistencia eléctrica (termómetro digital).


Fuentes de error: humana
La definición del problema a resolver está dado por el cliente, y contiene:
* Deformación profesional.
* Expectativas a priori.
* Confianza infinita (o nula) en los métodos numéricos.
Fuentes de error: incerteza en parámetros
Los parámetros rara vez se conocen con buena precisión, incluso cuando el modelo físico-matemático ha sido bien definido. Por ello, siempre es necesario tomar un enfoque conservador en la incerteza de los parámetros involucrados dependiendo de la aplicación del modelo.
Fuentes de error: incerteza en parámetros
Por ejemplo, en el caso de minería subterránea:


Si el problema involucra seguridad en los túneles mineros, se  utiliza un modelo conservador que subestima los parámetros físicos de la roca: : la roca del modelo es menos resistente que en la realidad. Si el modelo indica que el túnel es resistente, tenemos confianza que en la realidad el tunel es seguro.


Si el problema involucra factibilidad de la técnica extractiva, se utiliza un modelo que sobreestima los parámetros físicos de la roca: la roca del modelo es más resistente que en la realidad. Si el modelo indica que la roca se quiebra adecuadamente durante el caving, tenemos confianza que la roca se quiebra durante el caving.


Errores Humanos

Medición: Falta de apego a protocolos e imprecisión.
Modelamiento Matemático: falta de cuidado a deformación profesional: Para quien tiene un martillo, todo parece un clavo.
Modelamiento Numérico: Errores de conceptuales, de unidades, o profesional.
Implementación Numérica:  Testeo deficiente permite que bugs permanezcan ocultos en la implementación.
Interpretación: Confianza ciega en la caja negra.

Error Experimental
El análisis de los errores en ingeniería no se realiza etapa por etapa.
Tradicionalmente y por conveniencia se supone que el error es
únicamente experimental, es decir, se han detectado y corregido los
errores ilegítimos o humanos.
Errores experimentales se dividen en 2 categorías:

Errores sistemáticos.
Errores aleatorios.

Errores Experimentales Sistemáticos

Afectan la exactitud (eng. accuracy) de una medición.
Provienen de la utilización de un método o técnica en particular.
En ausencia de otro tipo de errores, tiene un  sesgo (eng. bias) característico.
Son difíciles de detectar, por ser de carácter teórico/práctico.
Son fáciles de corregir una vez detectados.

Errores Experimentales Sistemáticos
Ejemplos:
* Instalación deficiente de instrumentos de medición.
* Mala calibración interna de intrumentos de medición.
<img src="images/parallax.jpg" alt="" width="600px" align="middle"/>
Errores Experimentales Aleatorios

Afectan la precisión  (eng. precision) de una medición.
Repetición de experimentos entregan valores con variabilidad (varianza).
Mediciones difieren debido a variaciones impredecibles e incontrolables en el proceso de medición.
Son fáciles de detectar.
Son difíciles de corregir, aunque existen técnicas estadísticas para su análisis.

<img src="images/SesgoVsVarianza1.png" alt="" width="600px" align="middle"/>
<img src="images/SesgoVsVarianza2.png" alt="" width="600px" align="middle"/>
¿Porqué utilizar modelos?
Permiten reproducir escalas temporales o espaciales donde las mediciones o los experimentos son costosos, difíciles o imposibles.
* Ejemplo: deriva continental, impacto de asteroides, evolución de enfermedades, etc.
¿Porqué utilizar modelos?
Permiten reproducir experimentos donde factores no pueden ser fácilmente controlados.
* Ejemplo: Comportamiento de cápsula lunar en gravedad cero y al atravesar atmósfera a gran velocidad.
¿Porqué utilizar modelos?
Permiten simplificar el entendimiento de sistemas complejos, al permitir el análisis y exploración de cada componente del sistema por separado.
* Ejemplo: Adelgazamiento de la capa de hielo polar por calentamiento global.
¿Porqué utilizar modelos?
Es mejor que no hacer nada o confiar en juicios dudosos de terceros.

Ejemplo: Predicción meteorológica versus danza de la lluvia.

Un modelo es

Una representación abstracta y conveniente de un sistema.
Una simplificación del mundo real.
Un medio de exploración y de explicación para nuestro entendimiento de la realidad.

Un modelo NO es

Igual al mundo real.
Un sustituto para mediciones o experimentos.

Objetivos de Modelamiento

Ayudar al diseño de experimentos y mediciones.
Condensar entendimiento al forzar la abstracción, integración y formalización de ideas científicas.
Permitir la realización de experimentos virtuales.
Divulgar conocimiento científico a no-expertos.
Realizar predicciones.

El modelamiento no es un objetivo en sí mismo.
Tipos de modelamiento
Modelamiento Exploratorio

Explora las relaciones entre las variables y parámetros.
No se conoce el grado de exactitud, pero si el grado de precisión.

Modelamiento Predictivo

Estimar valores futuros o inobservables para ser útil. 
Requiere estimar el error de predicción.
Difícil pero poderoso.

Algunos principios básicos

Un mismo fenómeno físico puede tener distintos modelos, cada uno bueno para el estudio de un cierto aspecto del fenómeno.
Modelamiento require tiempo: es necesario determinar el nivel de complejidad en función los resultados deseados y del tiempo disponible.
GIGO: Garbage In = Garbage Out: Un buen modelo no compensa malos datos de entrada.

Algunos principios básicos

El mundo es demasiado complejo para poder modelarlo perfectamente.
Todo modelo es una simplificación de la realidad.
Modelos complementan otras formas de conocimiento (experimentos, mediciones)
Que algo se pueda simular, no significa que se corresponda con la realidad.

Validación completa del un modelo es imposible, al igual que cualquier teoría.
"All models are wrong, 
some are useful" - George Box
"Since all models are wrong the scientist 
cannot obtain a correct one by excessive 
elaboration. On the contrary following William
of Occam he should seek an economical 
description of natural phenomena. [...] 
the ability to devise simple but evocative
models is the signature 
of the great scientist [...]"- George Box


Etapas del Modelamiento:

Meta: Definir el propósito del modelo.
Modelar: Desarrollar el modelo conceptual.
Afinar: Seleccionar el tipo de modelo y la escala. 
Codear: Realizar la implementación numérica del modelo conceptual.
Calibrar: Estimar los parámetros requeridos por el modelo.
Analizar: Evaluar el modelo con análisis de sensitividad e incertidumbre.
Validar: Comparar las predicciones del modelo con mediciones reales. Requiere parámetros y mediciones reales.
Utilizar: Aplicar el modelo al propósito. Requiere parámetros reales.

Ejemplo
Supongamos que ciertos datos provienen de la siguiente caja negra:
$$ y(x) = 5 \cos\Big( \frac{\pi x}{2}\Big) + \mathcal{N}(0,1)$$ 
Tenemos 200 mediciones, y deseamos ajustar un modelo de tipo polinomial a los datos. Después de todo, sabemos que 
$$ cos(x) = 1 - \frac{1}{2!}x^2 + \frac{1}{4!}x^4 - \frac{1}{6!}x^6 + \frac{1}{8!}x^8 + ...$$
Además, 200 datos son bastantes, por lo que, ¿qué tan mal lo podríamos hacer?
Los datos
End of explanation
"""


# Define error function
def error(vector_e):
  return abs(vector_e).mean()

# Parameters
nmax = 70 # max polynomial

# Load data
x, y = np.loadtxt("data/data.txt").T

# Fit best several models and record training error and prediction error
order_polynomial = range(1, nmax+1)
error_polynomial = []
for n in order_polynomial:
  fit_n = np.polyfit(x, y, n) # Obtains the best fitted polynomial of degree n
  pol_n = np.poly1d(fit_n) # Creates the polynomial with coefficients as in fit n
  error_polynomial.append( error(y - pol_n(x)) )

# Plot data
plt.figure(figsize=(16,8))
plt.semilogy(order_polynomial, error_polynomial, "-sb", lw=2.0, label="Error")
plt.xlabel("x []", fontsize=20)
plt.ylabel("y []", fontsize=20)
plt.xlabel("Grado del polinomio", fontsize=20)
plt.ylabel("Error", fontsize=20)
plt.show()

"""
Explanation: Error de entrenamiento
Si miramos el error cometido al utilizar polinomios de orden creciente, obtenemos el siguiente gráfico.
End of explanation
"""


# Parameters
n = 1 # order of polynomial

# Load data
x, y = np.loadtxt("data/data.txt").T

# Fit best several models and record training error and prediction error
fit_n = np.polyfit(x, y, n) # Obtains the best fitted polynomial of degree n
pol_n = np.poly1d(fit_n) # Creates the polynomial with coefficients as in fit n

# Plot data
x_bb = np.sort(x)
y_bb = 5 * np.cos(0.5*np.pi*x_bb/2)
plt.figure(figsize=(16,8))
plt.plot(x, y, 'bs', alpha=0.5, label=u"Medición")
plt.plot(x_bb, y_bb, 'k-', lw=2.0, label=u"Relación determinista")
plt.plot(x_bb, pol_n(x_bb), 'r-', lw=2.0, label=u"Polinomio grado %d" %n)
plt.xlabel("x []", fontsize=20)
plt.ylabel("y []", fontsize=20)
plt.legend(numpoints=1, loc="lower center", fontsize=20)
plt.show()

"""
Explanation: Conclusiones

¿Debemos utilizar un polinomio de grado extremadamente alto, $n=70$?
El error en los datos de calibración/entrenamiento siempre disminuye con $n$. ¿Porqué?
¿Cuál es el error real/predictivo del modelo?

Mirando el polinomio
Miremos el polinomio que obtenemos en cada interpolación de datos:
End of explanation
"""


# Parameters
n = 1 # order of polynomial

# Load data
x, y = np.loadtxt("data/data.txt").T

# Split into training and prediction data
t = int(len(x)*.7)
x_t = x[:t]
y_t = y[:t]
x_p = x[t:]
y_p = y[t:]

# Fit best several models and record training error and prediction error
fit_n = np.polyfit(x_t, y_t, n) # Obtains the best fitted polynomial of degree n
pol_n = np.poly1d(fit_n) # Creates the polynomial with coefficients as in fit n

# Plot data
x_bb = np.sort(x)
y_bb = 5 * np.cos(0.5*np.pi*x_bb/2)
plt.figure(figsize=(16,8))
plt.plot(x_t, y_t, 'bs', alpha=0.5, label=u"Training Set")
plt.plot(x_p, y_p, 'gs', alpha=0.5, label=u"Testing Set")
plt.plot(x_bb, y_bb, 'k-', lw=2.0, label=u"Relación determinista")
plt.plot(x_bb, pol_n(x_bb), 'r-', lw=2.0, label=u"Polinomio grado %d" %n)
plt.xlabel("x []", fontsize=20)
plt.ylabel("y []", fontsize=20)
plt.legend(numpoints=1, loc="lower center", fontsize=20)
plt.show()

"""
Explanation: Conclusiones

Modelo no se acerca al modelo subyacente, sino que sobreajusta a las mediciones.

¿Qué hacer? ¿Existe algún método que me permita seleccionar cuantitativamente el mejor orden?


¿Qué tal si entrenamos el modelo con algunos datos, y después comprobamos que tal se comporta el modelo en los datos reservados? (holdout set technique).


Error de Entrenamiento versus Error de Predicción
End of explanation
"""


# Parameters
nmax = 70 # max polynomial

# Load data
x, y = np.loadtxt("data/data.txt").T

# Fit best several models and record training error and prediction error
order_polynomial = range(1, nmax+1)
error_t = []
error_p = []
for n in order_polynomial:
  fit_n = np.polyfit(x_t, y_t, n) # Obtains the best fitted polynomial of degree n
  pol_n = np.poly1d(fit_n) # Creates the polynomial with coefficients as in fit n
  error_t.append( error(y_t - pol_n(x_t)) )
  error_p.append( error(y_p - pol_n(x_p)) )

# Plot the errors
plt.figure(figsize=(16,8))
plt.semilogy(order_polynomial, error_t, "-sb", lw=2.0, label="Training error")
plt.semilogy(order_polynomial, error_p, "-og", lw=2.0, label="Prediction error")
plt.legend(numpoints=1, loc="lower center", fontsize=20)
plt.xlabel("Grado del polinomio", fontsize=20)
plt.ylabel("Error", fontsize=20)
plt.show()

"""
Explanation: Conclusiones

Polinomios se siguen comportando mal, pero ahora podemos evaluar el error predictivo y seleccionar el grado de polinomio basado en el error predictivo (no en el error de calibración).

Error de Entrenamiento versus Error de Predicción
End of explanation
"""


