最小二乘法

举报
UE5技术哥 发表于 2024/06/02 22:31:08 2024/06/02
【摘要】 本文结合对ChatGTP的提问,用自己的理解讲一讲最小二乘法。

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

最小二乘法:

q1.png

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

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

代码实现


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

q2.png


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

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);
        }
    }
}

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。