机器学习算法与Python实践(1) - 最小二乘法

最小二乘法(Least Square Method) ·分类算法的基础。

原理:最小误差平方和
应用:

  • 求得未知的数据,并且使得这些数据与实际数据的平方和最小
  • 曲线拟合
  • 最小化能量,最大化熵来解决一些优化问题

那么什么是最小二乘法呢?

(“多线→一点”视角与“多点→一线”视角)视角描述:

  • 已知多条近似交汇于同一个点的直线,想求解出一个近似交点:寻找到一个距离所有直线距离平方和最小的点,该点即最小二乘解
  • 已知多个近似分布于同一直线上的点,想拟合出一个直线方程:设该直线方程为y=kx+b,调整参数k和b,使得所有点到该直线的距离平方之和最小,设此时满足要求的k=k0,b=b0,则直线方程为y=k0x+b0。

思维拓展实例:

  1. 有一个未知系数的二元二次函数 f(x,y)=w0x^2+w1y^2+w2xy+w3x+w4y+w5(w0~w5未知)为了确定下来这些参数,将会给定一些样本点(xi,yi,f(xi,yi)),然后通过调整这些参数,找到这样一组w0~w5,使得这些所有的样本点距离函数f(x,y)的距离平方之和最小。至于具体用何种方法来调整这些参数呢?有一种非常普遍的方法叫“梯度下降法”,它可以保证每一步调整参数,都使得f(x,y)朝比当前值更小的方向走,只要步长α选取合适,我们就可以达成这种目的。
  2. 假设我们现在有一系列的数据点 这里写图片描述 ,那么由我们给出的拟合函数h(x)得到的估计量就是 这里写图片描述 ,那么怎么评估我们给出的拟合函数与实际待求解的函数的拟合程度比较高呢?这里我们先定义一个概念:残差, 这里写图片描述 我们估计拟合程度都是在残差的基础上进行的。下面再介绍三种范数:
    • ∞-范数:残差绝对值的最大值 这里写图片描述 ,即所有数据点中残差距离的最大值
    • 1-范数:绝对残差和 这里写图片描述 ,即所有数据点残差距离之和
    • 2-范数:残差平方和 这里写图片描述
    前两种范数是最容易得到的,但是不利于进行微分运算,在数据量很大的情况下计算量太大,不具有可操作性。因此一般使用的是2-范数
    那么,范数拟合有什么关系呢?拟合程度,就是我们的拟合函数h(x)与待求解的函数y之间的相似性。那么2-范数越小,自然相似性就比较高

最小二乘法的定义:

对于给定的数据 这里写图片描述 ,在取定的假设空间H中,求解h(x)∈H,使得残差 这里写图片描述 的2-范数最小,即

这里写图片描述

从几何上讲,就是寻找与给定点 这里写图片描述 距离平方和最小的曲线y=h(x)。h(x)称为拟合函数或者最小二乘解,求解拟合函数h(x)的方法称为曲线拟合的最小二乘法。

那么这里的h(x)到底是什么样呢?一般情况下,这是一条多项式曲线:

这里写图片描述

这里h(x,w)是一个n次多项式,w是其参数。
也就是说,最小二乘法就是要找到这样一组 这里写图片描述 ,使得 这里写图片描述 最小。

那么如何找到这样的w?,使得其拟合函数h(x)与目标函数y具有最高拟合程度呢?即最小二乘法如何求解呢,这才是关键啊。
假设我们的拟合函数是一个线性函数,即:

这里写图片描述

(当然,也可以是二次函数,或者更高维的函数,这里仅仅是作为求解范例,所以采用了最简单的线性函数)
那么我们的目标就是找到这样的w,

这里写图片描述

这里令 这里写图片描述 为样本 这里写图片描述 的平方损失函数
这里的Q(w)即为我们要进行最优化的风险函数。
学过微积分的同学应该比较清楚,这是一个典型的求解极值的问题,只需要分别对 这里写图片描述 求偏导数,然后令偏导数为0,即可求解出极值点,即:

这里写图片描述

接下来只需要求解这个方程组即可解出w_i 的值

=====================================================================
上面讲解的是最小二乘法,以及如何求解最小二乘解
下面我们将通过Python来实现最小二乘法
(这里我们把目标函数选为y=sin(2πx),叠加上一个正态分布作为噪音干扰,然后使用多项式分布去拟合它)

代码:

'''最小二乘法'''
# _*_ coding: utf-8 _*_

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('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()

输出拟合参数:

这里写图片描述

拟合图像:

这里写图片描述

======================================================================
从图像上看,很明显我们的拟合函数过拟合了,下面我们尝试在风险函数的基础上加上正则化项,来降低过拟合的现象:

这里写图片描述

为此,我们只需要在残差函数中将lambda^(1/2)p加在了返回的array的后面,如下:

regularization = 0  # 正则化系数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  

输出拟合参数

这里写图片描述

拟合图像

这里写图片描述

很明显,在适当的正则化约束下,可以比较好的拟合目标函数。

======================================================================

注意:如果正则化项的系数太大,会导致欠拟合现象(此时的惩罚项权重特别高)
如:设置regularization=0.1时,图像如下

这里写图片描述

此时明显欠拟合。所以要慎重进行正则化参数的选择。

参考:

利用python搞机器学习-最小二乘法

机器学习经典算法之—–最小二乘法

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值