最小二乘法

本文结合对ChatGTP的提问,用自己的理解讲一讲最小二乘法。

最小二乘法:

在这里插入图片描述
yi是实际值,yhat是理论值,就是拟合值,比方说使用一元一次的线性函数做拟合,那就是在这个x点位置时的值。累加所有yi-yhat的平方,得到E并保证E最小,即最小二乘。
当然这个E的结果并不是固定的,不同的函数,不同的参数都会导致结果不同。
然后再将拟合函数带入原公式,这个计算过程网上有很多,硬算或者求导或者用矩阵等。

注意:最小二乘是求得线性回归的方法,但不是一样东西

代码实现

所以这其实是一个数学问题,代码实现也只是对偏导公式的一个数值解而已,不过结合ChatGTP,它还是给出了结合协方差和方差的拟合方案,用Unity实现一下:
在这里插入图片描述

using UnityEngine;

public class LeastSquaresMethod : MonoBehaviour
{
    public Vector2[] samplePoints;//采样点,需要在编辑器面板自己设置

    void OnDrawGizmos()
    {
        float xSum = 0f, ySum = 0f;
        for (int i = 0; i < samplePoints.Length; i++)
        {
            var item = samplePoints[i];

            xSum += item.x;
            ySum += item.y;
        }
        //x和y的平均值
        var xAve = xSum / samplePoints.Length;
        var yAve = ySum / samplePoints.Length;

        //sx是x轴的方差,sy是y轴的方差,方差反应了数据的离散程度
        //sxy是协方差,协方差大于零y与x正相关,小于零是负相关,等于零是无关
        float sx = 0f, sy = 0f, sxy = 0f;
        for (int i = 0; i < samplePoints.Length; i++)
        {
            sx += Mathf.Pow(samplePoints[i].x - xAve, 2);
            sy += Mathf.Pow(samplePoints[i].y - yAve, 2);
            sxy += (samplePoints[i].x - xAve) * (samplePoints[i].y - yAve);
        }

        Debug.Log("sxy:" + sxy);

        //此处套用公式
        var r = sxy / (Mathf.Sqrt(sx) * Mathf.Sqrt(sy));
        var a = r * (sy / sx);
        var b = yAve - a * xAve;

        //Unity绘制逻辑
        Vector3? lastPos = null;
        for (float i = 0f, step = 0.1f; i <= 1f; i += step)
        {
            var x = i / 1f;
            var y = a * x + b;

            var pos = new Vector3(x, y, 0f);
            if (lastPos.HasValue)
                Gizmos.DrawLine(lastPos.Value, pos);
            lastPos = pos;
        }

        for (int i = 0; i < samplePoints.Length; i++)
        {
            var item = samplePoints[i];

            Gizmos.DrawWireSphere(new Vector3(item.x, item.y, 0f), 0.03f);
        }
    }
}

最后在面板上填入一些采样点,可以得到最接近的拟合函数参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值