最小二乘法是一种相对来说比较简单而且易于理解的算法,在分类回归算法中经常使用。最近在学习Deep Learning这本书,遇到线性最小二乘,刚开始对于书本上的公式还不是很理解,后来经过查阅资料,对线性最小二乘的原理以及如何使用有了一定的理解,话不多说,直接步入正题。
一、最小二乘法
官方定义:最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。最小二乘法还可用于曲线拟合。其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达。
我的理解:最小二乘法就是最小化代价函数(损失函数),如果最后所求得的目标函数在图像上显示过拟合,则可以通过添加正则化项来进行降拟合
下面通过一个直观的栗子来介绍一下最小二乘法是怎么发挥作用的
由图1-->图2就是通过最小二乘法拟合出一条直线,这条直线表示所要求得的数据与真实数据之间误差平方和最小的目标函数
二、最小二乘法的原理
假设我们现在有一系列的数据点,由我们所给出的拟合函数h(x),所得到的估量就是
,那么如何评估我们所给出的拟合函数与实际待求解的函数的拟合程度呢?这里先引入一个概念:残差
,评估拟合程度就是在残差的基础之上进行的。
由以上的认知,我们就可以利用公式来表示最小二乘法了:对于给定的数据,在取定的假设空间中求解h(x)∈H,使得残差
的2-范式最小,也就是使得
的值最小。从几何上讲,就是寻找与给定点
距离平方和最小的函数y = h(x),在上面的两张图中很容易理解这句话。
那么最小二乘法如何求解呢?假设我们拟合一个线性函数h(x, w) = w0 + w1 * x(当然也可以是二次函数或者是更高维的函数),假设我们的目标就是要找这样的函数w,使得,这里的意思是寻找一个目标函数w,使得损失函数最小。这里令损失函数为Q(w),即
,可以用微积分的知识来求解
,这是一个典型的求极值的问题,分别对
求偏导数,然后令偏导数等于零,即
求解这个方程便可求解出
三、最小二乘法实例
这里我们把目标函数选为y=sin(2πx)
import numpy as np # 引入numpy
import scipy as sp
import pylab as pl
from scipy.optimize import leastsq # 引入最小二乘函数
n = 9 # 多项式次数
# 目标函数
def real_func(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) # 随机初始化多项式参数
plsq = leastsq(residuals_func, p_init, args=(y1, x))
print (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()
输出结果为:
由图可以看出我们拟合的函数过拟合了,下面我们尝试在损失函数的基础上加上正则化项,来降低过拟合的现象:
# 残差函数
regularization = 0.0001 # 正则化系数lambda
# 残差函数
def residuals_func(p, y, x):
ret = fit_func(p, x) - y
ret = np.append(ret, np.sqrt(regularization) * p) # 将lambda^(1/2)p加在了返回的array的后面
return ret
输出的图像为:
这里要注意如果正则化项的系数太大,会导致欠拟合现象(此时的惩罚项权重特别高)