4 最优化实验

4.1 最小二乘法实现

4.1.1 算法介绍

最小二乘法(Least Square Method),做为分类回归算法的基础,有着悠久的历史。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的参数,并使得预测的数据与实际数据之间误差的平方和为最小。

4.1.2 代码实现

代码输入:

import numpy as np 
import scipy as sp
import pylab as pl
from scipy.optimize import leastsq # 引入最小二乘函数

n = 9 # 多项式次数

定义目标函数:

def real_func(x): 
#目标函数:sin(2*pi*x)
return np.sin(2 * np.pi * x)

定义多项式函数,用多项式去拟合数据:

def fit_func(p, x): 
f = np.poly1d(p)
return f(x)

定义残差函数,残差函数值为多项式拟合结果与真实值的差值:

def residuals_func(p, y, x): 
ret = fit_func(p, x) - y
return ret
x = np.linspace(0, 1, 9) # 随机选择 9 个点作为 x
x_points = np.linspace(0, 1, 1000) # 画图时需要的连续点
y0 = real_func(x) # 目标函数
y1 = [np.random.normal(0, 0.1) + y for y in y0] # 在目标函数上添加符合正态分布噪声后的函数
p_init = np.random.randn(n) # 随机初始化多项式参数
# 调用 scipy.optimize 中的 leastsq 函数,通过最小化误差的平方和来寻找最佳的匹配函数
# func 是一个残差函数,x0 是计算的初始参数值,把残差函数中除了初始化以外的参数打包到 args 中
plsq = leastsq(func=residuals_func, x0=p_init, args=(y1, x))

print('Fitting Parameters: ', plsq[0]) # 输出拟合参数

pl.plot(x_points, real_func(x_points), label='real')
pl.plot(x_points, fit_func(plsq[0], x_points), label='fitted curve')
pl.plot(x, y1, 'bo', label='with noise')
pl.legend()
pl.show()

结果输出:


可视化图像:
暂无

4.2 梯度下降法实现

4.2.1 算法介绍

梯度下降法(gradient descent),又名最速下降法,是求解无约束最优化问题最常用的方法,它是一种迭代方法,每一步主要的操作是求解目标函数的梯度向量,将当前位置的负梯度方向作为搜索方向(因为在该方向上目标函数下降最快,这也是最速下降法名称的由来)。
梯度下降法特点:越接近目标值,步长越小,下降速度越慢。

4.2.2 代码实现

训练集(x,y)共 5 个样本,每个样本点有 3 个分量 (x0,x1,x2)

代码输入:

x = [(1, 0., 3), (1, 1., 3), (1, 2., 3), (1, 3., 2), (1, 4., 4)] 
y = [95.364, 97.217205, 75.195834, 60.105519, 49.342380] y[i] 样本点对应的输出
epsilon = 0.0001 #迭代阀值,当两次迭代损失函数之差小于该阀值时停止迭代
alpha = 0.01 #学习率
diff = [0, 0]
max_itor = 1000
error1 = 0
error0 = 0
cnt = 0
m = len(x)
#初始化参数
theta0 = 0
theta1 = 0
theta2 = 0
while True:
cnt += 1

# 参数迭代计算
for i in range(m):
# 拟合函数为y = theta0 * x[0] + theta1 * x[1] +theta2 * x[2]
# 计算残差,即拟合函数值-真实值
diff[0] = (theta0** x[i][0] + theta1 * x[i][1] + theta2 * x[i][2]) - y[i]

# 梯度 = diff[0] * x[i][j]。根据步长*梯度更新参数