【Matlab】最小二乘法拟合多项式

2023-05-16

前言

在最近的电机项目中,有遇到有传感器数据并不线性的问题,然后想要用最小二乘法做个曲线拟合,反过来去校准不线性的传感器的数据,因此记录一下使用最小二乘法来拟合多项式的曲线的步骤。本篇从最小二乘法的原始公式入手编写M文件,目的是方便使用单片机实现,或者说是方便用C来实现。

拟合一次函数:

我们先试着拟合一个简单一点的,从一元一次函数开始。最小二乘法拟合曲线需要首先知道曲线的通用公式。一次函数的通用公式为y = k * x + b,使用matlab编写很容易实现。这里我直接写入了几个点,随便编了一组数据。

%*************************************************************************%
                %最小二乘法
%**********************************************************************%

clc;
clear;

%假定拟合曲线的公式为:y = ax^2 +b^x + c;
x = [1 2 3 4 5 6 7 8 9];
y = [1.2  2.5  3.6  4.8  5.6  7.4  8.0  9.8  12.0];
[m , n] = size(x);
sumx = 0;
sumy = 0;
sumxx = 0;
sumxy = 0;
Xaver = 0;
Yaver = 0;
XYaver = 0;
XXaver = 0;

%求平均
for i = 1 : n
    sumx = sumx + x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxx = sumxx + x(i) * x(i);
end
Xaver = sumx / n;
Yaver = sumy / n;
XYaver = sumxy / n;
XXaver = sumxx / n;

k = (XYaver - Xaver * Yaver) / (XXaver - Xaver * Xaver);
b = Yaver - k * Xaver;

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 10];
y1 = k * x1 + b;

plot(x1,y1);

效果:

拟合二次函数:

之后开始拟合二次函数,可以从最小二乘法的原理上进行程序编写。

最小二乘法原理:

假设我们的多项式表达式为:

之后采集x与y的样本数据:

x = [1 2 3 4 5 6 7 8 9 10 11 12 13];
y = [1.2  2.5  3.6  4.8  5.6  6.6  7.4  8.0  9.8  12.0  12.5 13.1 14.6];

最小二乘法是要达到最优函数的各项系数使的误差平方和S取得最小值,即S对各项式的偏导为0:

整理上式可得:

将其转化为矩阵形式:

即,我们需要求取样本x的和,x^2的和,,,,,x^n的加和,以及y的加和,xy的加和。。。。。x^n*y的加和。

假定我们的曲线是二次多项式,那么这个XY矩阵都是一个3行3列的矩阵,那么只需要求到x^4的加和即可,程序如下:

sumx = 0;
sumxx = 0;
sumxxx = 0;
sumxxxx = 0;
sumy = 0;
sumxy = 0;
sumxxy = 0;

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
end

将x加和的相关项写成X矩阵,将y加和的相关项写成Y矩阵,之后:

多项式矩阵就可以通过X矩阵的逆 * Y矩阵求得:

%写出矩阵
U = [n  sumx  sumxx ; sumx  sumxx  sumxxx ; sumxx  sumxxx  sumxxxx];
W = [sumy ; sumxy ; sumxxy];

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);

之后就可以画出图形:

%画出拟合曲线
x1 = [0 : 0.1 : 15];
y1 = a + b .* x1 + c .* x1 .* x1;

plot(x1,y1);

注意:有一个点乘

结果图像如下:

完整代码如下:

%*************************************************************************%
                %最小二乘法拟合多项式
%**********************************************************************%

clc;
clear;

%假定拟合曲线的公式为:y = a +b^x + c * x^2;
x = [1 2 3 4 5 6 7 8 9 10 11 12 13];
y = [1.2  2.5  3.6  4.8  5.6  6.6  7.4  8.0  9.8  12.0  12.5 13.1 14.6];
[m , n] = size(x);
a = 0;
b = 0;
c = 0;
sumx = 0;
sumxx = 0;
sumxxx = 0;
sumxxxx = 0;
sumy = 0;
sumxy = 0;
sumxxy = 0;

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
end


%写出矩阵
U = [n  sumx  sumxx ; sumx  sumxx  sumxxx ; sumxx  sumxxx  sumxxxx];
W = [sumy ; sumxy ; sumxxy];

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 15];
y1 = a + b .* x1 + c .* x1 .* x1;

plot(x1,y1);

拟合多项式:

拟合多项式其实与拟合二次函数的方法是一样的,因为都是通用的矩阵。那就用一个4阶的举例,如果是4阶,那么拟合出来的多项式就是3次多项式。这里我们先随便编一个4次多项式,生成一个4次多项式的点:

for i = 1 : n
    y(i) = 0.3 + 0.04 * x(i) + 1.2 * x(i) * x(i) + 0.06 * x(i) * x(i) * x(i) + 0.003 * x(i) * x(i) * x(i) * x(i);
end

这里的y就是4次多项式了,生成了点之后,我们使用最小二乘法来拟合一个3次多项式,尽量与4次多项式的点接近。依旧是按照最小二乘法的矩阵公式,先求出需要的加和数据:

%求矩阵数据
for i = 1 : n
    sumx = sumx + x(i);
    sumxx = sumxx + x(i) * x(i);
    sumxxx = sumxxx + x(i) * x(i) * x(i);
    sumxxxx = sumxxxx + x(i) * x(i) * x(i) * x(i);
    sumxxxxx = sumxxxxx + x(i) * x(i) * x(i) * x(i) * x(i);
    sumxxxxxx = sumxxxxxx + x(i) * x(i) * x(i) * x(i) * x(i) * x(i);
    sumy = sumy + y(i);
    sumxy = sumxy + x(i) * y(i);
    sumxxy = sumxxy + x(i) * x(i) * y(i);
    sumxxxy = sumxxxy + x(i) * x(i) * x(i) * y(i);
    sumxxxxy = sumxxxxy + x(i) * x(i) * x(i) * x(i) * y(i);   
end

然后写出矩阵:

%写出矩阵
U = [n  sumx  sumxx  sumxxx; 
    sumx  sumxx  sumxxx  sumxxxx; 
    sumxx  sumxxx  sumxxxx  sumxxxxx;
    sumxxx  sumxxxx  sumxxxxx  sumxxxxxx];
W = [sumy ; sumxy ; sumxxy; sumxxxy];

求出逆矩阵之后求多项式:

%求出矩阵的逆,进而求出多项式矩阵
V =  pinv(U) * W;   % U * V = W    V = U(-1) * W
a = V(1,1); b = V(2,1); c = V(3,1);d = V(4,1);

之后将图像画出来,对比之前生成的点的图像:

plot(x,y,'s');   %画数据点不连线
hold on;  %不加此句,两个图形将显示在两张图像上

%画出拟合曲线
x1 = [0 : 0.1 : 40];
y1 = a + b .* x1 + c .* x1 .* x1 + d .* x1 .* x1 .* x1;

plot(x1,y1);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Matlab】最小二乘法拟合多项式 的相关文章

  • 继续在 Matlab 中一遍又一遍地播放声音?

    我正在尝试创建一个 MATLAB 程序来每隔几分钟一遍又一遍地播放声音 现在我将其设置为每隔几秒播放一次 只是为了消除系统中的一些错误 但是 当我的程序尝试重播声音时 我收到此错误 Error using gt audioplayer au
  • 对多个属性使用一种设置方法 MATLAB

    我有几个属性基本上使用相同的属性set method classdef MyClass properties A B end methods function mc MyClass a b Constructor mc A a mc B b
  • 如何在 MATLAB 中可视化球体的交集?

    似乎这个问题在一些地方被问过 包括SO https stackoverflow com questions 35130336 draws the intersecting volume of two spheres in matlab 我最
  • 如何在Matlab中自定义轮廓线?

    我正在准备一个等高线图 我应该在其中突出显示特定级别的等高线 例如 我的轮廓线值位于 1 和 1 之间 我想突出显示与值 0 相对应的线 我尝试使用以下过程来执行此操作 M c contourf longitude latitude del
  • 在 MATLAB 中使用 FFT 的频率响应

    这是场景 使用频谱分析仪 我有输入值和输出值 样本数是32000采样率为2000样本 秒 输入是正弦波50 hz 输入为电流 输出为压力 单位 psi 我如何使用 MATLAB 根据这些数据计算频率响应 使用 MATLAB 中的 FFT 函
  • 在 MATLAB 中检索 spfun、cellfun、arrayfun 等中的元素索引

    有什么办法可以找回index调用函数的元素的cellfun arrayfun or spfun行为 即检索函数范围内元素的索引 为了简单起见 假设我有以下玩具示例 S spdiags 1 4 0 4 4 f spfun x 2 x S 它构
  • Matlab:如何显示数组的“真实”值?

    我有一个在脚本中计算的向量 计算后 我将值显示到命令窗口 显示如下 finalResults 1 0e 05 0 0001 0 0 0005 0 0002 0 0001 0 0027 0 0033 0 0001 0 0000 0 0000
  • 按元素出现的频率对数组元素进行排序

    是否可以在 matlab octave 中使用sort函数根据元素的相对频率对数组进行排序 例如数组 m 4 4 4 10 10 10 4 4 5 应该产生这个数组 5 10 10 10 4 4 4 4 4 5是出现频率较低的元素 位于顶部
  • 将自动生成的 Matlab 文档导出为 html

    我想为我开发的 Matlab 工具箱生成完整的帮助 我已经看到如何显示自定义文档 http www mathworks fr fr help matlab matlab prog display custom documentation h
  • 两个 y 轴与相同的 x 轴[重复]

    这个问题在这里已经有答案了 可能的重复 在单个图中绘制 4 条曲线 具有 3 个 y 轴 https stackoverflow com questions 1719048 plotting 4 curves in a single plo
  • 使用mat2cell将MxN的矩阵划分为1xN大小的M矩阵

    我有一个大小为 MxN 的矩阵 比方说 1867x3 1867 行和 3 列 我想将其分成 1867 个大小为 1x3 的单元格 我使用了mat2cell X 1 1866 这里X是矩阵 1867x3 结果给出了两个单元格 一个单元格的大小
  • 不等间隔时间序列的移动平均线

    我有一个证券交易所股票价格的数据集 时间 价格 但数据点之间的间隔并不相等 从 1 到 2 分钟不等 在这种情况下计算移动平均值的最佳实践是什么 如何在Matlab中实现呢 我倾向于认为 点的权重应该取决于自上一个点以来的最后时间间隔 Ma
  • 如何找到在matlab中重复的矩阵的每一行的索引?

    我想找到矩阵中所有有重复项的行的索引 例如 A 1 2 3 4 1 2 3 4 2 3 4 5 1 2 3 4 6 5 4 3 要返回的向量将是 1 2 4 很多类似的问题建议使用unique函数 我已经尝试过 但我能得到的最接近我想要的功
  • MATLAB 特征函数

    我很好奇哪里可以找到完整的描述FEATURE功能 它接受哪些论点 没有找到文档 我只听说过memstats and getpid 还要别的吗 gt gt which feature built in undocumented 注意 更完整的
  • 有没有办法在matlab中进行隐式微分

    我经常使用 matlab 来帮助我解决数学问题 现在我正在寻找一种在 matlab 中进行隐式微分的方法 例如 我想区分y 3 sin x cos y exp x 0关于dy dx 我知道如何使用数学方法通常做到这一点 但我一直在努力寻找使
  • Matlab:如何更改矩阵的存储方式?从 1x1x3 到 1x3?

    我目前有 val 1 0 7216 val 2 0 7216 val 3 0 7216 但我想要 0 7216 0 716 0 721 我可以做什么样的操作来做到这一点 The reshape函数将在这里解决问题 Arrange the e
  • 如何在 matlab 中创建由多个 3d 图像数据数组组成的数组

    我正在阅读 15 张图片imagedata imread imagename jpg 它的大小总是320 by 320 by 3 如何将数据放入数组中 使用 for for 循环 以便在访问新数组的第一个元素时获得输入的第一个图像的 RGB
  • MATLAB - 冲浪图数据结构

    我用两种不同的方法进行了计算 对于这些计算 我改变了 2 个参数 x 和 y 最后 我计算了每种变体的两种方法之间的 误差 现在我想根据结果创建 3D 曲面图 x gt on x axis y gt on y axis Error gt o
  • MATLAB 中的霍夫变换

    有谁知道如何使用霍夫变换来检测二值图像中最强的线 A zeros 7 7 A 6 10 18 24 36 38 41 1 使用 rho theta 格式 其中 theta 以 45 为步长 从 45 到 90 以及如何在 MATLAB 中显
  • 给定协方差矩阵,在Matlab中生成高斯随机变量

    Given a M x M期望的协方差 R 以及所需数量的样本向量 N计算一个N x M高斯随机向量 X在普通 MATLAB 中 即不能使用r mvnrnd MU SIGMA cases 不太确定如何解决这个问题 通常你需要一个协方差并且意

随机推荐

  • 搬砖过程中常用的英文单词(代码命名规则)

    注册register用户名 用户userName user密码password pwd路径path成绩score服务器host图片img字符串str数字num
  • CAN 邮箱的理解

    对于CAN邮箱的理解 xff1a CAN总线有接收邮箱和发送邮箱 xff1a 发送邮箱 是用于CAN总线数据发送的 xff0c 总共有3个 xff0c 并且存在优先级关系 优先级越高表示其里面的数据会被优先发送 数据在发送前都会被送到优先级
  • 变量名前为什么要加_下划线

    简单来说 xff0c 含有两个下划线和下划线 43 大写字母开头的标识符是给编译器和标准库用的 xff0c 你不能用 xff0c 否则后果自负 一个下划线开头的随便用 xff0c 只要你不嫌麻烦 而我们一般在前面加 表示私有变量 一般来说
  • 23 张图细讲使用 Devtron 简化 K8S 中应用开发

    23 张图细讲使用 Devtron 简化 K8S 中应用开发 在本文中 xff0c 您将学习如何在多集群环境中使用 Devtron 在 K8S 上进行应用开发 https devtron ai Devtron 附带用于构建 部署和管理微服务
  • 企业级网关 Kong 部署 Spring Boot 项目实战

    企业级网关 Kong 部署 Spring Boot 项目实战 1 概述 在本教程中 xff0c 我们将演示使用 Kong Ingress Controller KIC 在 Kubernetes 上部署 Spring Boot 应用程序 通过
  • Linux Mint(Ubuntu)上 安装 效率神器 utools

    我的 Windows 系统的笔记本只有 256G 固态 xff0c 磁盘已经快用满了 xff0c 最近想装个 Linux 玩玩 xff0c 选择了 Linux Mint xff0c 然后就在闲置的移动硬盘上安装了 Linux Mint 21
  • 图文轻松说透 K8S Pod 各种驱逐场景

    图文轻松说透 K8S Pod 各种驱逐场景 Kubernetes Pod 被驱逐是什么意思 xff1f 它们被终止 xff0c 通常是没有足够资源的结果 但是为什么会这样呢 xff1f 驱逐是指派给节点的Pod 被终止的过程 Kuberne
  • CKA、CKAD、CKS、LFCS、LFCA、LFCE 60$ 刀优惠券

    CKA CKAD CKS LFCS LFCA LFCE 60 刀优惠券 CKA 地址 xff1a https trainingportal linuxfoundation org courses certified kubernetes a
  • 配置Docker CE 镜像

    Docker CE 是免费的 Docker 产品的新名称 xff0c Docker CE 包含了完整的 Docker 平台 xff0c 非常适合开发人员和运维团队构建容器 APP 参考阿里云官方镜像站 xff1a 阿里巴巴开源镜像站 OPS
  • ssh 连接错误 Too many authentication failures 解决方法

    ssh 连接错误 Too many authentication failures 解决方法 背景 有时候使用 ssh 登录 或者 git ssh 方式连接 时会遇到 xff1a Too many authentication failur
  • 报错解决 REMOTE HOST IDENTIFICATION HAS CHANGED

    REMOTE HOST IDENTIFICATION HAS CHANGED 报错 span class hljs meta style color 61aeee line height 26px span span class bash
  • 使用 Helm Cli 将 chart 推送到 Harbor

    使用 Helm Cli 将 chart 推送到 Harbor 背景问题 努力寻找适用于特定版本的 Harbor 和 Helm 的文档 我尝试添加我的仓库 xff08 repo xff09 helm repo span class token
  • 修改 Git 已经提交记录的 用户名 和邮箱

    修改 Git 已经提交记录的 用户名 和邮箱 有关 Git 和版本控制的常见问题 如何更改提交的作者姓名 电子邮件 xff1f 在我们进入解决方案之前 xff0c 让我们找出您到底想要完成什么 xff1a 在提交之前更改作者信息在提交后更改
  • Go 中模拟 Kubernetes 客户端进行单元测试

    是的 xff0c 我们可以模仿 K8s Client xff01 编写单元测试一直是开发人员的痛苦 这样做的主要原因是 xff0c 通常 xff0c 单元测试 xff08 功能单元测试 xff09 不得使用应用程序的任何物理组件 运行实例
  • Kubernetes 1.26 中的删除、弃用和主要更改

    Kubernetes 1 26 中的删除 弃用和主要更改 变化是 Kubernetes 生命周期不可或缺的一部分 xff1a 随着 Kubernetes 的成长和成熟 xff0c 功能可能会被弃用 删除或替换为项目健康的改进 对于 Kube
  • 提高 K8S 容器运行时的可观察性最佳方法之一

    当谈到云原生可观察性时 xff0c 可能每个人都会提到OpenTelemetry OTEL xff0c 因为社区需要依赖标准来将所有集群组件开发指向到同一方向 OpenTelemetry 使我们能够将日志 指标 xff08 metrics
  • 6 张配图通俗易懂说透 K8S 请求和限制

    6 张配图通俗易懂说透 K8S 请求和限制 在 Kubernetes 中使用容器时 xff0c 了解涉及的资源是什么以及为何需要它们很重要 有些进程比其他进程需要更多的 CPU 或内存 这很关键 xff0c 永远不应该让进程挨饿 知道了这一
  • Kubernetes 1.26 正式发布,变化重大,所有更改都在这里了!

    Kubernetes 1 26 正式发布 xff0c 变化重大 xff0c 所有更改都在这里了 xff01 Kubernetes 1 26 已经正式发布 xff0c 满载新奇 xff01 此版本带来了 37 项增强功能 xff0c 与 Ku
  • 如何修复错误:无法下载 metadata repo appstream

    如何修复错误 xff1a 无法下载 metadata repo appstream 如果您出于某种原因仍在积极使用CentOS 8 xff0c 您可能在尝试更新系统或只是安装软件包时遇到以下错误 Error Failed to downlo
  • 【Matlab】最小二乘法拟合多项式

    前言 在最近的电机项目中 xff0c 有遇到有传感器数据并不线性的问题 xff0c 然后想要用最小二乘法做个曲线拟合 xff0c 反过来去校准不线性的传感器的数据 xff0c 因此记录一下使用最小二乘法来拟合多项式的曲线的步骤 本篇从最小二