🧮 Derivación, Visualización y Optimización de Funciones en Python¶
Objetivo: Aplicar los conceptos fundamentales del cálculo diferencial en una variable a través de la derivación simbólica, la identificación de puntos críticos y la optimización de funciones.¶
👥 Alumno¶
- 🧑🎓 José Gómez Brizuela
📅 Entrega: Junio 2025
📘 Módulo 3: Sesión N° 3
Librerías requeridas¶
# Importación de librerías necesarias
import numpy as np
import sympy as sp
import matplotlib.pyplot as plt
from IPython.display import display, Math
from scipy.optimize import minimize
1.Definición y Derivación Simbólica de la Función:¶
- Función a Analizar: $f(x) = (x - 3)^2$
# Función personalizada para mostrar expresiones simbólicas con formato LaTeX
def mostrar_latex(expr, nombre_funcion="f"):
"""
Muestra en pantalla la representación LaTeX de una expresión simbólica.
Parámetros:
- expr: expresión simbólica de SymPy (por ejemplo, una función o derivada)
- nombre_funcion: nombre que queremos que aparezca como etiqueta (por defecto, 'f')
Resultado:
- Muestra la función en formato matemático bonito usando LaTeX en un notebook de Colab
"""
latex_expr = sp.latex(expr)
display(Math(rf"{nombre_funcion}(x) = {latex_expr}"))
# Definimos la variable simbólica x, que representa nuestro eje horizontal
x = sp.Symbol('x')
# Definimos la función f(x) = (x - 3)^2
f = (x - 3)**2
# Mostramos la función original de manera elegante
mostrar_latex(f, "f")
# Calculamos la derivada de f con respecto a x
f_prime = sp.diff(f, x)
# Mostramos la derivada simbólicamente
mostrar_latex(f_prime, "f'")
# Buscamos los puntos donde la derivada se anula, es decir, los puntos críticos
solucion = sp.solve(f_prime, x)
# Mostramos el resultado en consola y también en formato matemático
print("Punto crítico donde f'(x) = 0:", solucion)
display(Math(rf"x = {solucion[0]}"))
Punto crítico donde f'(x) = 0: [3]
2. Visualización de la Función y su Derivada:¶
- Rango de Análisis: Generar valores de x en el intervalo [−5,10][-5, 10].
# Mostramos nuevamente la función original y su derivada
mostrar_latex(f, "f") # f(x) = (x - 3)^2
mostrar_latex(f_prime, "f'") # f'(x) = 2(x - 3)
# === Determinación del Punto Crítico ===
# Resolvemos f'(x) = 0 para encontrar el mínimo o máximo
solucion = sp.solve(f_prime, x)
# Extraemos el punto crítico como número flotante (para graficar)
punto_critico = float(solucion[0])
# Evaluamos la función original en ese punto crítico para obtener el valor mínimo
valor_minimo = float(f.subs(x, punto_critico))
# Mostramos el punto crítico tanto en notación matemática como en consola
display(Math(rf"x = {punto_critico},\quad f(x) = {valor_minimo}"))
print("")
# === Preparación para graficar ===
# Convertimos las expresiones simbólicas a funciones numéricas para usar con NumPy
f_np = sp.lambdify(x, f, "numpy") # Versión numérica de f(x)
f_prime_np = sp.lambdify(x, f_prime, "numpy") # Versión numérica de f'(x)
# Generamos un rango de valores para analizar y graficar
x_vals = np.linspace(-5, 10, 400) # Rango amplio que incluye el punto crítico
y_vals = f_np(x_vals) # Evaluamos f(x)
y_prime_vals = f_prime_np(x_vals) # Evaluamos f'(x)
# === Gráfico Unificado: Función y Derivada ===
plt.figure(figsize=(8, 4))
# Graficamos la función original
plt.plot(x_vals, y_vals, label=r"$f(x) = (x - 3)^2$", color='blue')
# Graficamos la derivada como línea punteada
plt.plot(x_vals, y_prime_vals, label=r"$f'(x) = 2(x - 3)$", color='green', linestyle='--')
# Marcamos el punto crítico en rojo
plt.scatter([punto_critico], [valor_minimo], color='red', zorder=5)
# Líneas guía vertical y horizontal para resaltar el punto crítico
plt.axvline(punto_critico, color='gray', linestyle='--', alpha=0.6)
plt.axhline(0, color='black', linestyle=':', linewidth=0.8)
# Etiqueta visual del punto crítico
plt.text(punto_critico + 0.2, valor_minimo + 2.0,
f"[{punto_critico:.1f}, {valor_minimo:.1f}]",
color='red', fontsize=10, weight='bold')
# Configuraciones del gráfico
plt.title("Función y Derivada con Punto Crítico Marcado")
plt.xlabel("x")
plt.ylabel("Valor")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
3. Optimización Numérica con SciPy:¶
# === Función simbólica y derivada ===
x = sp.Symbol('x') # Definimos x como variable simbólica
# Definimos la función f(x) = (x - 3)^2
f_expr = (x - 3)**2
# Creamos una versión numérica de la función para usar con NumPy
f = sp.lambdify(x, f_expr, "numpy")
# Derivamos simbólicamente para encontrar el punto crítico
f_prime = sp.diff(f_expr, x)
# Obtenemos el punto crítico (donde la derivada es cero)
punto_critico_simbolico = float(sp.solve(f_prime, x)[0])
# Evaluamos la función original en ese punto crítico
valor_minimo_simbolico = float(f_expr.subs(x, punto_critico_simbolico))
# === Definición de la función objetivo para optimización numérica ===
def funcion_objetivo(x):
"""
Función que queremos minimizar numéricamente.
Parámetros:
- x: valor (o arreglo) sobre el que se evalúa la función
Retorna:
- Valor de (x - 3)^2, que tiene un mínimo en x = 3
"""
return (x - 3)**2
# === Minimización numérica con SciPy ===
# Usamos un valor inicial arbitrario, como x = 0
resultado = minimize(funcion_objetivo, x0=0)
# Extraemos los resultados de la optimización
x_min_numerico = resultado.x[0] # Valor de x donde se alcanza el mínimo
f_min_numerico = resultado.fun # Valor mínimo de la función
# === Mostramos los resultados simbólicos y numéricos de forma elegante ===
display(Math(r"\text{Resultado simbólico:}"))
display(Math(rf"x = {punto_critico_simbolico},\quad f(x) = {valor_minimo_simbolico}"))
display(Math(r"\text{Resultado numérico con SciPy:}"))
display(Math(rf"x \approx {x_min_numerico:.6f},\quad f(x) \approx {f_min_numerico:.6f}"))
# También mostramos los resultados en consola para revisión rápida
print("")
print("Comparación de resultados")
print("Simbólico:", punto_critico_simbolico, "| Numérico:", x_min_numerico)
Comparación de resultados Simbólico: 3.0 | Numérico: 2.9999999840660854
✅ Comparación y Verificación (Punto 3)¶
En esta sección se realiza la comparación del resultado simbólico y el numérico obtenidos para la función:
$$ f(x) = (x - 3)^2 $$
🔢 Resultados¶
Resultado simbólico (derivación exacta):
$x = 3.0$, $f(x) = 0.0$Resultado numérico (SciPy
minimize
):
$x \approx 2.9999999840660854$, $f(x) \approx 0.000000$
✔️ Verificación¶
Ambos métodos coinciden con una diferencia menor a $1 \times 10^{-7}$, lo que confirma que:
- La solución numérica converge con alta precisión al resultado exacto.
- La función es convexa y el mínimo global se encuentra correctamente por ambos caminos.
- El método numérico es fiable incluso partiendo desde $x_0 = 0$, lejos del mínimo.
Este paso valida no solo el código, sino la confianza en los métodos de optimización que usamos día a día para entrenar modelos, lo que permite un grado de indeferencia en la elección del metodo a seguir.
4. Documentación y Evidencias¶
🧠 Proyecto: Optimización Simbólica y Numérica en Python¶
📌 Resumen¶
Este proyecto tiene como objetivo ilustrar y comparar dos enfoques para encontrar el mínimo de una función cuadrática simple:
- Optimización simbólica, usando derivadas exactas con
SymPy
. - Optimización numérica, usando el método
minimize
deSciPy
.
Ambos métodos convergen al mismo punto mínimo, permitiendo visualizar el puente entre la matemática analítica y las herramientas prácticas utilizadas en ciencia de datos y machine learning.
📁 Estructura del proyecto¶
Definición simbólica de la función
Se utilizaSymPy
para construir la función $ f(x) = (x - 3)^2 $ y calcular su derivada.Visualización con LaTeX
Decidi crear una que permita mostrar la función y su derivada se simbólicamente para entender su comportamiento antes de resolverla, lo que enriquece la visualización matematica.Resolución simbólica del mínimo
Se obtiene el punto crítico resolviendo $ f'(x) = 0 $, y se evalúa el valor mínimo exacto.Transformación numérica con
lambdify
Se convierte la función simbólica en una versión compatible conNumPy
para graficar y comparar.Optimización numérica con
scipy.optimize.minimize
Se ejecuta un método de descenso para encontrar el mínimo desde un valor inicial arbitrario.Visualización gráfica
Se presenta un gráfico conjunto de la función y su derivada, con el punto mínimo marcado.
- Comparación final de resultados
Se muestran los valores obtenidos por ambos métodos, validando su consistencia.
⚙️ Decisiones de diseño¶
- Se eligió una función cuadrática simple para centrarse en la comprensión del proceso, no en la complejidad del modelo.
- La implementación se dividió en pasos claros y separados, para facilitar el aprendizaje y permitir reutilización modular.
- Se incluyó una visualización gráfica unificada, que es clave en machine learning para interpretar el comportamiento de funciones de costo.
- El uso de
lambdify
permite un flujo natural entre símbolos matemáticos y código computacional.
🤖 Relevancia en Machine Learning¶
- En ML, la optimización es el corazón del entrenamiento de modelos: todo algoritmo aprende minimizando una función de costo.
- Este ejemplo simula de forma didáctica lo que hacen los algoritmos de descenso de gradiente en redes neuronales, regresión lineal y otros modelos.
- Aprender a conectar derivadas simbólicas con métodos numéricos permite comprender por qué y cómo optimizamos modelos.