B站台湾大学郭彦甫|MATLAB 学习笔记|14 回归与内插 Curve_Fitting_&_Interpolation

MATLAB学习笔记(14 回归与内插 Curve_Fitting_&_Interpolation)

1. 提出问题

通过简单线性回归(Simple Linear Regression)引出问题:

  • 已知有一堆数据点 (xi,yi),现在假定 xy 线性相关,想通过 xy 之间的线性关系,如 y^i=β0+β1xi , 由 x 推算出预测值 yi^.

  • 真实值 yi 和预测值 yi^ 之间的差值为 ϵi

  • 定义残差平方和(sum of squared errors, SSE):

SSE=iϵi2=i(yiyi^)2

  • 代入回归模型:y^i=β0+β1xi 可得到:

SSE=i(yiβ0β1xi)2

  • 为了使预测值 yi^ 更加接近真实值 yi,需要找到两个参数 β0β1,使得残差平方和 SSE 需要最小;

下面为求解最小 SSE 问题:

  • SSE 分别对 β0β1 求导,且导数为零

iϵi2β0=2i(yiβ0β1xi)=0iϵi2β1=2i(yiβ0β1xi)xi=0

  • 现在假定数据点共有 N 个:

i=1Nyi=β0N+β1i=1Nxii=1Nyixi=β0i=1Nxi+β1i=1Nxi2[yiyixi]=[Nxixixi2][β0β1]

  • 问题转换为求解矩阵方程 A=Bx 的问题,其中 x=[β0; β1]

2. 多项式曲线拟合 (Polynomial Curve Fitting):polyfit()

example:

x =[-1.2 -0.5 0.3 0.9 1.8 2.6 3.0 3.5];
y =[-15.6 -8.5 2.2 4.5 6.6 8.2 8.9 10.0];
fit = polyfit(x,y,1);   % 1表示多项式的阶次,该函数得到 y=ax+b 中的 a和b,其中a是fit(1),b是fit(2)

%下面为画图,把离散的数据点和线性回归拟合出来的直线画出来
xfit = [x(1):0.1:x(end)];   % xfit为拟合线的x坐标范围
yfit = fit(1)*xfit + fit(2);    % a是fit(1),b是fit(2)
plot(x,y,'ro',xfit,yfit);  set(gca,'FontSize',14);
legend('data points','best-fit','Location','northwest');

exercise (P7)

题目:

给出下面表格:

  1. 找到回归线的 β0β1
  2. 画图
TC Output (mV) Temperature (^(@)C)
0.025 20
0.035 30
0.050 40
0.060 50
0.080 60

解:

clear
clc
clf
x=[20 30 40 50 60];
y=[0.025 0.035 0.05 0.06 0.08];
fit = polyfit(x,y,1);

xfit = x(1):0.1:x(end);
yfit = fit(1) * xfit + fit(2);
plot(x,y,'ro',xfit,yfit);
title('exercise');
legend('data points','curve fitting','Location','northwest');

3.1 求相关系数:corrcoef()

clear
clc
x =[-1.2 -0.5 0.3 0.9 1.8 2.6 3.0 3.5];
y =[-15.6 -8.5 2.2 4.5 6.6 8.2 8.9 10.0];
scatter(x,y);  
% scatter(x,y) 在向量 x 和 y 指定的位置创建一个包含圆形的散点图。该类型的图形也称为气泡图。
box on;  axis square;
corrcoef(x,y);  % 返回x,y之间的相关系数矩阵
ans =

    1.0000    0.9202
    0.9202    1.0000

3.2 高阶多项式曲线拟合

x =[-1.2 -0.5 0.3 0.9 1.8 2.6 3.0 3.5];
y =[-15.6 -8.5 2.2 4.5 6.6 8.2 8.9 10.0];
figure('Position', [50 50 1500 400]);
for i=1:3
subplot(1,3,i);  p = polyfit(x,y,i);    %i表示阶次
xfit = x(1):0.1:x(end);  yfit = polyval(p,xfit);
plot(x,y,'ro',xfit,yfit);  set(gca,'FontSize',14);
ylim([-17, 11]);  legend(4,'Data points','Fitted curve');
end

exercise (P10)

题目:

找到4阶、5阶、6阶 的多项式曲线拟合

x =[-1.2 -0.5 0.3 0.9 1.8 2.6 3.0 3.5];
y =[-15.6 -8.5 2.2 4.5 6.6 8.2 8.9 10.0];

解:

clear
clc
clf
x =[-1.2 -0.5 0.3 0.9 1.8 2.6 3.0 3.5];
y =[-15.6 -8.5 2.2 4.5 6.6 8.2 8.9 10.0];
figure('Position', [50 50 1500 400]);
for i=1:3
subplot(1,3,i);  p = polyfit(x,y,i+3);      %i表示阶次
xfit = x(1):0.1:x(end);  yfit = polyval(p,xfit);
plot(x,y,'ro',xfit,yfit);  set(gca,'FontSize',14);
ylim([-17, 11]);  
legend('Data points','Fitted curve','Location','southeast');
end

3. 多元回归(Multiple Regression)

如果回归模型具有多个变量,如 x1,x2

y=β0+β1x1+β2x2

需要使用多元回归模型。

3.1 多元线性回归:regress()

example:

clea
load carsmall;
y = MPG;    %和英里有关
x1 = Weight; x2 = Horsepower;   %x1是重量,x2是马力
X = [ones(length(x1),1) x1 x2]; % ones(length(x1),1)为常数项,x1,x2表示带有未知数的项
b = regress(y,X);   % 返回的b中有,y=a+b*x1+c*x2 中的a,b和,c
x1fit = min(x1):100:max(x1);
x2fit = min(x2):10:max(x2);
[X1FIT,X2FIT]=meshgrid(x1fit,x2fit);
YFIT=b(1)+b(2)*X1FIT+b(3)*X2FIT;
scatter3(x1,x2,y,'filled'); hold on;
mesh(X1FIT,X2FIT,YFIT); hold off;
xlabel('Weight');
ylabel('Horsepower');
zlabel('MPG'); view(50,10);                             

exercise (P13)

题目:

使用下面的等式对数据进行拟合:

y=β0+β1x1+β2x2+β3x12+β4x22+β5x1x2

解:

clear
load carsmall;
y = MPG;    %和英里有关
x1 = Weight; x2 = Horsepower;   %x1是重量,x2是马力
X = [ones(length(x1),1) x1 x2 x1.^2 x2.^2 x1.*x2]; 
% ones(length(x1),1)为常数项,x1,x2, x1.^2, x2.^2, x1.*x2表示带有未知数的项
b = regress(y,X);  
x1fit = min(x1):100:max(x1);
x2fit = min(x2):10:max(x2);
[X1FIT,X2FIT]=meshgrid(x1fit,x2fit);
YFIT=b(1) + b(2)*X1FIT + b(3)*X2FIT + b(4)*X1FIT.^2 + b(5)*X2FIT.^2 + b(6).*X1FIT.*X2FIT;
scatter3(x1,x2,y,'filled'); hold on;
mesh(X1FIT,X2FIT,YFIT); hold off;
xlabel('Weight');
ylabel('Horsepower');
zlabel('MPG'); view(50,10);            
title('exercise');            

4. 非线性拟合方法

对于3. 4. 5. 这样的非线性等式,需要采用非线性拟合方法。

4.1 线性拟合工具箱:cftool()

example:

对于一个 DC 马达,其距离 s(t) 的关系式如下:

s(t)=αt+αeβtβ+γ

其中,v(t) 为速度,β 为时间常数

可以使用 MTALAB 曲线拟合工具箱:cftool() 对数据进行拟合。(具体的内容要看视频)

5. 内插(Interpolation)

内插找到的线段一定会连接各个点,回归拟合出来的曲线一般不会经过这些数据点。

一般都内插方法:

  • Piecewise linear interpolation(分段线性内插)
  • Piecewise cubic polynomial interpolation(三次多项式插值)
  • Cubic spline interpolation(三次样条插值)
函数 内容
interp1() 1-D data interpolation (table lookup)
pchip() Piecewise Cubic Hermite Interpolating Polynomial
spline() Cubic spline data interpolation
mkpp() Make piecewise polynomial

5.1 线性内插: interp1()

clear
x = linspace(0, 2*pi, 40);  x_m = x;
x_m([11:13, 28:30]) = NaN; % 删除x_m中的其中一部分点
y_m = sin(x_m);
plot(x_m, y_m,'ro', 'MarkerFaceColor', 'r'); 
xlim([0, 2*pi]);  ylim([-1.2, 1.2]);  box on;
set(gca, 'FontName', 'symbol', 'FontSize', 16);
set(gca, 'XTick', 0:pi/2:2*pi);
set(gca, 'XTickLabel', {'0', 'p/2', 'p', '3p/2', '2p'});

m_i = ~isnan(x_m);  % ~表示非,~isnan()表示将非NaN元素标记为1
y_i = interp1(x_m(m_i), y_m(m_i), x);   %x_m(m_i)表示x_m中非0的元素
% vq = interp1(x,v,xq) 使用线性插值返回一维函数在特定查询点的插入值。
% 向量 x 包含样本点,v 包含对应值 v(x)。向量 xq 包含查询点的坐标。
hold on;  
plot(x,y_i,'-b', ...
'LineWidth', 2);  
hold off;

5.2 三次样条插值(Spline Interpolation): spline()

m_i = ~isnan(x_m);  
y_i = spline(x_m(m_i), y_m(m_i), x);
hold on;  plot(x,y_i,'-g', 'LineWidth', 2);  hold off;
h = legend('Original', 'Linear', 'Spline');
set(h,'FontName', 'Times New Roman');
5.2.1 解释 Spilines
  1. 在第一个片段 (0,1) 之间画一个多项式曲线(蓝色),在第二个片段 (1,2) 画曲线(红色),第三个。。(绿色)

  2. 规定相邻两个多项式曲线的斜率在数据点处连续

  3. 删除曲线延长线

exercise (P20)(不一定正确)

题目:

使用线性三次样条拟合数据

x(ft) 0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25
y(ft) 1.2 1.18 1.1 1 0.92 0.8 0.7 0.55 0.35 0

解:

clc
clear
clf
hold on
x = [0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0 2.25];
y = [1.2 1.18 1.1 1 0.92 0.8 0.7 0.55 0.35 0];
x_i = linspace(0,2.25);
plot(x, y,'bo', 'MarkerFaceColor', 'r'); 

% 画linear lines
y1 = interp1(x,y,x_i);
plot(x_i,y1,'-r', 'LineWidth', 1); 

% 画cubic splines
y2 = spline(x, y, x_i);
plot(x_i,y2,'-g', 'LineWidth', 1);
hold off
5.2.2 埃尔米特多项式 (Hermite Polynomials)

Hermite Polynomial 相比 cubic Spline 在转折处更加平滑

x = -3:3;  y = [-1 -1 -1 0 1 1 1];  t = -3:.01:3;
s = spline(x,y,t);  p = pchip(x,y,t);  % pchip为使用hermite polynomial拟合
hold on;  plot(t,s,':g', 'LineWidth', 2);  
plot(t,p,'--b', 'LineWidth', 2);  
plot(x,y,'ro', 'MarkerFaceColor', 'r'); 
hold off;  box on;  set(gca, 'FontSize', 16);
h = legend('Original', 'Spline', 'Hermite','Location','northwest');

5.3 (二维)线性插值:interp2() 和 三次样条插值

5.3.1 二维线性插值:interp2()
clf
xx = -2:.5:2;  yy = -2:.5:3;
[X,Y] = meshgrid(xx,yy);
Z = X.*exp(-X.^2-Y.^2);
surf(X,Y,Z);  hold on;
plot3(X,Y,Z+0.01,'ok',...
'MarkerFaceColor','r')
%%
clf
xx_i = -2:.1:2;  yy_i = -2:.1:3;
[X_i,Y_i] = meshgrid(xx_i,yy_i);
Z_i = interp2(xx,yy,Z,X_i,Y_i);	% 点的坐标xx,yy,Z,和内插点x_i,y_i
surf(X_i,Y_i,Z_i);  hold on;
plot3(X,Y,Z+0.01,'ok',...
'MarkerFaceColor','r')
原图
16
线性内插处理后的图
5.3.2 使用二维样条插值
xx = -2:.5:2;  yy = -2:.5:3;  [X,Y] = meshgrid(xx,yy);
Z = X.*exp(-X.^2-Y.^2);  xx_i = -2:.1:2;  yy_i = -2:.1:3;  
[X_i,Y_i] = meshgrid(xx_i,yy_i);  
Z_c = interp2(xx,yy,Z,X_i,Y_i,'cubic');	% 区别在于cubic
surf(X_i,Y_i,Z_c);  hold on;  
plot3(X,Y,Z+0.01,'ok', 'MarkerFaceColor','r');  hold off;
三次样条插值处理后的图
posted @   一抹微瀾  阅读(373)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示