🧮 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¶

In [7]:
# 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$
In [11]:
# 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]}"))
$\displaystyle f(x) = \left(x - 3\right)^{2}$
$\displaystyle f'(x) = 2 x - 6$
Punto crítico donde f'(x) = 0: [3]
$\displaystyle x = 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].
In [13]:
# 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()
$\displaystyle f(x) = \left(x - 3\right)^{2}$
$\displaystyle f'(x) = 2 x - 6$
$\displaystyle x = 3.0,\quad f(x) = 0.0$

No description has been provided for this image

3. Optimización Numérica con SciPy:¶

In [10]:
# === 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)
$\displaystyle \text{Resultado simbólico:}$
$\displaystyle x = 3.0,\quad f(x) = 0.0$
$\displaystyle \text{Resultado numérico con SciPy:}$
$\displaystyle x \approx 3.000000,\quad f(x) \approx 0.000000$
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:

  1. Optimización simbólica, usando derivadas exactas con SymPy.
  2. Optimización numérica, usando el método minimize de SciPy.

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¶

  1. Definición simbólica de la función
    Se utiliza SymPy para construir la función $ f(x) = (x - 3)^2 $ y calcular su derivada.

  2. 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.

  3. 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.

  4. Transformación numérica con lambdify
    Se convierte la función simbólica en una versión compatible con NumPy para graficar y comparar.

  5. 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.

  6. Visualización gráfica
    Se presenta un gráfico conjunto de la función y su derivada, con el punto mínimo marcado.

image.png

  1. 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.