当前位置:   article > 正文

人工智能——利用Python编程,求解多元函数极值和回归问题的几种方法_python求多元函数极值

python求多元函数极值

人工智能实验————利用Python编程,求解多元函数极值和回归问题的几种方法

一、牛顿法

1.原理详解

高次方程没有通解,可以依靠牛顿迭代法来求解。没有根式解不意味着方程解不出来,数学家也提供了很多方法,牛顿迭代法就是其中一种。
首先,切线是曲线的线性逼近。可以通过研究简单切线的解来近似的逼近复杂曲线的解随便找一个曲线上的A点(为什么随便找,根据切线是切点附近的曲线的近似,应该在根点附近找,但是很显然我们现在还不知道根点在哪里),做一个切线,切线的根(就是和x轴的交点)与曲线的根,还有一定的距离。我们从这个切线的根出发,做一根垂线,和曲线相交于B点,继续重复刚才的工作;B点比之前A点更接近曲线的根点,我们继续重复刚才的工作;经过多次迭代后会越来越接近曲线的根,从数学的角度上说,切线收敛了,此时我们就得到了一个曲线近似的解。

2.题目实例——牛顿法解简单的一元函数

from sympy import *
# step为迭代步数,x0为初始位置,obj为要求极值的函数
def newtons(step, x0, obj):
    i = 1 # 记录迭代次数的变量
    x0 = float(x0) # 浮点数计算更快
    obj_deri = diff(obj, x) # 定义一阶导数,对应上述公式
    obj_sec_deri = diff(obj, x, 2) # 定义二阶导数,对应上述公式
    while i <= step:
        if i == 1:
            # 第一次迭代的更新公式
            xnew = x0 - (obj_deri.subs(x, x0)/obj_sec_deri.subs(x, x0))
            print('迭代第%d次:%.5f' %(i, xnew))
            i = i + 1
        else:
            #后续迭代的更新公式
            xnew = xnew - (obj_deri.subs(x, xnew)/obj_sec_deri.subs(x, xnew))
            print('迭代第%d次:%.5f' % (i, xnew))
            i = i + 1
    return xnew
x = symbols("x") # x为字符变量
result = newtons(50, 10, x**6+x)
print('最佳迭代的位置:%.5f' %result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
迭代第1次:8.00000
迭代第2次:6.39999
迭代第3次:5.11997
迭代第4次:4.09593
迭代第5次:3.27662
迭代第6次:2.62101
迭代第7次:2.09610
迭代第8次:1.67515
迭代第9次:1.33589
迭代第10次:1.05825
迭代第11次:0.82002
迭代第12次:0.58229
迭代第13次:0.17590
迭代第14次:-34.68063
迭代第15次:-27.74450
迭代第16次:-22.19560
迭代第17次:-17.75648
迭代第18次:-14.20519
迭代第19次:-11.36415
迭代第20次:-9.09132
迭代第21次:-7.27306
迭代第22次:-5.81846
迭代第23次:-4.65480
迭代第24次:-3.72391
迭代第25次:-2.97930
迭代第26次:-2.38386
迭代第27次:-1.90812
迭代第28次:-1.52901
迭代第29次:-1.22931
迭代第30次:-0.99804
迭代第31次:-0.83203
迭代第32次:-0.73518
迭代第33次:-0.70225
迭代第34次:-0.69886
迭代第35次:-0.69883
迭代第36次:-0.69883
迭代第37次:-0.69883
迭代第38次:-0.69883
迭代第39次:-0.69883
迭代第40次:-0.69883
迭代第41次:-0.69883
迭代第42次:-0.69883
迭代第43次:-0.69883
迭代第44次:-0.69883
迭代第45次:-0.69883
迭代第46次:-0.69883
迭代第47次:-0.69883
迭代第48次:-0.69883
迭代第49次:-0.69883
迭代第50次:-0.69883
最佳迭代的位置:-0.69883
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

二、梯度下降法

1.原理详解

关于梯度下降算法的直观理解,我们以一个人下山为例。比如刚开始的初始位置是山顶位置,那么现在的问题是该如何达到山底呢?按照梯度下降算法的思想,它将按如下操作达到最低点:
第一步,明确自己现在所处的位置
第二步,找到相对于该位置而言下降最快的方向
第三步, 沿着第二步找到的方向走一小步,到达一个新的位置,此时的位置肯定比原来低
第四部, 回到第一步
第五步,终止于最低点
按照以上5步,最终达到最低点,这就是梯度下降的完整流程。

梯度下降的基本过程就和下山的场景很类似。
首先,我们有一个可微分的函数。这个函数就代表着一座山。我们的目标就是找到这个函数的最小值,也就是山底。根据之前的场景假设,最快的下山的方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度 ,然后朝着梯度相反的方向,就能让函数值下降的最快!因为梯度的方向就是函数之变化最快的方向(在后面会详细解释)
所以,我们重复利用这个方法,反复求取梯度,最后就能到达局部的最小值,这就类似于我们下山的过程。而求取梯度就确定了最陡峭的方向,也就是场景中测量方向的手段

2.题目实例

实例一

在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import math
from mpl_toolkits.mplot3d import Axes3D
import warnings
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

导入一些必要的库特别是用于3D绘图的库

def f2(x1,x2):
    return x1*x1+2*x2*x2-4*x1-2*x1*x2
 
X1 = np.arange(-4,4,0.2)
X2 = np.arange(-4,4,0.2)
X1, X2 = np.meshgrid(X1, X2) # 生成xv、yv,将X1、X2变成n*m的矩阵,方便后面绘图
Y = np.array(list(map(lambda t : f2(t[0],t[1]),zip(X1.flatten(),X2.flatten()))))
Y.shape = X1.shape # 1600的Y图还原成原来的(40,40)
 
%matplotlib inline
#作图
fig = plt.figure(facecolor='w')
ax = Axes3D(fig)
ax.plot_surface(X1,X2,Y,rstride=1,cstride=1,cmap=plt.cm.jet)
ax.set_title
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/629899
推荐阅读
相关标签
  

闽ICP备14008679号