El método de Newton-Raphson es un método abierto que permite encontrar la raiz x de una función de tal manera que f(x)=0. En su forma simbólica se resume como:
xi+1 =xi-f(xi)/f'(xi) Ec. 1
Se utiliza un método similar para encontrar un valor óptimo de f(x) al definir una nueva función r(x) dada por r(x)=f'(x), así para decir que se ha encontrado un óptimo de nuestra función se tiene que tener r(x)=0, por lo tanto se puede emplear lo siguiente para encontrar una x que satisfaga r(x)=0, de manera simbólica nuestro modelo a iterar quedaría como:
xi+1 =xi-r(xi)/r'(xi) Ec. 2
Ahora veamos como aplicariamos ésto a un ejercicio práctico:
Queremos encontrar el óptimo de nuestra función con un x inicial de 2.5:
f(x)=2senx-x2/10
La gráfica de dicha ecuación quedaría como:
(https://i.imgur.com/PC5W7JM.png)
Escribiendo el código en Phyton 3.6.8 para aplicar la ecuación 2:
import math
#Funcion a optimizar f(x)=2*math.sin(x)-pow(x,2)/10 ----> (2sinX-X^2/10)
#funcion primer derivada
def f_p(x):
yp=2*math.cos(x)-x/5
return (yp)
# funcion segunda derivada
def f_pp(x):
ypp=-2*math.sin(x)-1/5
return (ypp)
#introduciomos el valor x de partida (Xo asi como el numero de iteraciones)
xi=float(input("Introduce X_o: "))
iteraciones=int(input("Introduce el numero de iteraciones: "))
raiz=[]
raiz.insert(0,0)
# inicializamos el contador de iteraciones
i=0
# Definimos un error inicial
error=1
# Aplicamos la formula Newton para optimos
while iteraciones>i:
xi_1=xi-(f_p(xi)/f_pp(xi))
raiz.append(xi_1)
i=i+1
xi=xi_1
error=(raiz[i]-raiz[i-1])/raiz[i]
print(xi)
print("Error final: " +str(error))
print("El optimo global aproximado es: " +str(2*math.sin(xi)-pow(xi,2)/10))
Finalmente, si ejecutamos el código para 5 iteraciones y con una x inicial de 2.5 obtendremos:
(https://i.imgur.com/5RGVeIT.png)
Si comparamos éste resultado con la gráfica anterior se puede notar que efectivamente el algoritmo converge a un óptimo global para un x inicial de 2.5
Nota: Estos métodos son de suma importancia para comenzar a entender el método de descenso por gradiente aplicado a las redes neuronales, el cual es similar pero en los gradientes se aplican constantes de aprendizaje que hacen que la convergencia (si es que existe) sea mas rápida o mas lenta según lo permita la función