最小二乘法的数学原理推导及python代码

1. 什么是最小二乘法?

最小二乘法(Ordinary Least Squares)是一种常用的数据拟合方法,它通过最小误差的平方和来找到一组数据的最佳函数匹配。

很多软件中都包含最小二乘法功能的模块,比如python里scipy库中的leastsq方法。但是本着应用之前知晓其原理的理念,我们来简单了解一下最小二乘法背后的数学设计。

这里暂时考虑最线性的拟合情况。

2. 线性拟合数学原理

假设在一个二维平面内,我们有一堆无序且有一定趋势的散点 [(x1,y1), (x2,y2),…,(xn,yn)],若想通过一条直线来描述这些散点的分布情况,那我们的期望是每个散点离直线的距离加起来应该是最短的。那么,我们期望的效果是下图中的哪一种描述呢?
在这里插入图片描述

如果想要更方便地从数学角度研究这个问题,选择第二个方法无疑是更加取巧的。因为第一种情况下算点到直线距离的公式相对复杂。同时,由于点相对与直线的位置有上有下,d 值有正有负,因此只能用 delta y 的绝对值来代表距离d。那么干脆将距离进行平方,去除绝对值,简化数学表达。

假设需要拟合的直线函数表达式为: y=ax+b
那么距离的平方和可以表示为:
在这里插入图片描述
为了找到最合适的a, b值,使得上式结果最小,因此需要将上式对参数a, b求偏导,找出偏置数为0对应的 a, b值。

在这里插入图片描述
在这里插入图片描述
令两式均等于0,求得:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 代码实现

import matplotlib.pyplot as plt

def ordinary_least_square(list1,list2):

    x_sum = sum(list1)
    y_sum = sum(list2)

    x_mean = sum(list1)/len(list1)
    y_mean = sum(list2)/len(list2)

    x_square_sum = sum(x**2 for x in list1) 
    x_sum_square = (sum(x for x in list1))**2

    mul = [m*n for m,n in zip(list1,list2)]
    mul_sum = sum(mul)

    # 求解线性方程的系数
    a = (len(list1)*mul_sum-x_sum*y_sum)/(len(list1)*x_square_sum-x_sum_square)
    b = y_mean - a*x_mean

    # 拟合直线开始和结束的y值
    line_str_y = a*list1[0] + b
    line_end_y = a*list1[-1] + b

    fit_x = [list1[0],list1[-1]]
    fit_y = [line_str_y,line_end_y]

    plt.scatter(list1,list2)
    plt.plot(fit_x,fit_y)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
    

if __name__ == "__main__":
    list1 = [1,2,3,4,5,6,7,8]
    list2 = [2,3,8,8,11,15,30,25]
    ordinary_least_square(list1,list2)

这里用了两个List来观察最小二乘法的拟合情况,效果如下。
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值