我不想要积分的,可是不得不1分。。。。没办法。
最小二乘法曲线拟合以及Matlab实现
在实际工程中,我们常会遇到这种问题:已知一组点的横纵坐标,需要绘制出一条尽可能逼近这些点的曲线(或直线),以进行进一步进行加工或者分析两个变量之间的相互关系。而获取这个曲线方程的过程就是曲线拟合。
### 最小二乘法曲线拟合及其Matlab实现
#### 最小二乘法直线拟合原理
在实际的工程和数据分析场景中,我们经常会遇到这样的需求:通过一系列已知的数据点来寻找一条最佳拟合直线或者曲线,以便于进一步的研究和预测。这种技术通常被称为“曲线拟合”。最小二乘法是最常用的一种曲线拟合方法之一,其目标是找到一条使得所有数据点到该直线或曲线的距离平方和最小的线。
对于最简单的案例——直线拟合,假设有一组数据点 \((x_1, y_1), (x_2, y_2), ..., (x_n, y_n)\),我们需要找到一条直线 \(y = ax + b\) 来拟合这些点。其中 \(a\) 和 \(b\) 是未知参数,我们的目标是确定这两个参数的值,使得拟合误差最小。
假设 \(X_0\) 是一个包含所有 \(x\) 值的矩阵,\(Y\) 是一个包含所有 \(y\) 值的向量,那么可以通过矩阵的形式表示为 \(Y = X_0 A\),其中 \(A = [a, b]^T\)。理想情况下,如果 \(X_0\) 是一个方阵并且非奇异(即其行列式不为零),那么可以直接通过 \((X_0)^{-1} Y\) 来求解 \(A\)。然而,在实际情况中,\(X_0\) 往往不是一个方阵,因此我们使用 \(X_0\) 的转置矩阵 \(X^T_0\) 来构建一个新的方程,即 \(X^T_0 Y = X^T_0 X_0 A\),通过求解 \((X^T_0 X_0)^{-1} X^T_0 Y = A\) 来得到最优参数 \(A\)。
#### 曲线拟合
当数据点的分布不是简单的线性关系时,可能需要使用更高阶的多项式来拟合数据。例如,使用一个 \(n\) 阶多项式 \(y = \sum_{i=0}^{n} a_i x^i = a_n x^n + a_{n-1} x^{n-1} + ... + a_1 x + a_0\) 来拟合数据。这时,矩阵形式的表达式依然为 \(Y = X_0 A\),其中 \(A = [a_n, a_{n-1}, ..., a_1, a_0]^T\)。求解过程与直线拟合类似,同样利用 \(X^T_0 Y = X^T_0 X_0 A\) 和 \((X^T_0 X_0)^{-1} X^T_0 Y = A\) 来获得最优参数。
#### Matlab实现代码
下面是一段使用Matlab实现上述理论的示例代码:
```matlab
clear;
clc;
x = [2, 4, 5, 6, 6.8, 7.5, 9, 12, 13.3, 15];
y = [-10, -6.9, -4.2, -2, 0, 2.1, 3, 5.2, 6.4, 4.5];
[~, k] = size(x);
for n = 1:9
X0 = zeros(n + 1, k);
for k0 = 1:k
for n0 = 1:n + 1
X0(n0, k0) = x(k0)^(n + 1 - n0);
end
end
X = X0';
ANSS = (X' * X) \ (X' * y');
for i = 1:n + 1
answer(i, n) = ANSS(i);
end
x0 = 0:0.01:17;
y0 = ANSS(1) * x0.^n;
for num = 2:1:n + 1
y0 = y0 + ANSS(num) * x0.^(n + 1 - num);
end
subplot(3, 3, n);
plot(x, y, '*');
hold on;
plot(x0, y0);
end
suptitle('不同次数方程曲线拟合结果,从1到9阶');
```
#### 运行结果
通过上述代码,我们可以观察到不同阶数多项式拟合的结果。较低阶次的多项式可能无法很好地捕捉数据的变化趋势,而较高阶次的多项式可能会出现过拟合的现象,即过多地适应了数据中的噪声,导致模型泛化能力较差。
#### Matlab自带函数——`polyfit`
除了手动实现外,Matlab还提供了一个内置函数 `polyfit` 来简化最小二乘法曲线拟合的过程。该函数的基本格式为 `ans = polyfit(x, y, n)`,其中 `x` 和 `y` 分别为数据点的横纵坐标向量,`n` 表示拟合多项式的阶数。`polyfit` 函数同样基于最小二乘法原理实现,并返回一个向量,该向量包含了拟合多项式的系数。
下面是一个使用 `polyfit` 函数来进行曲线拟合的示例代码:
```matlab
clear;
clc;
x = [2, 4, 5, 6, 6.8, 7.5, 9, 12, 13.3, 15];
[~, k] = size(x);
y = [-10, -6.9, -4.2, -2, 0, 2.1, 3, 5.2, 6.4, 4.5];
n = 3; % 设定多项式阶数
ans = polyfit(x, y, n); % 使用polyfit函数进行拟合
x0 = 0:0.01:17;
y0 = ans(1) * x0.^n + ans(2) * x0.^(n-1) + ans(3) * x0.^(n-2) + ans(4);
plot(x, y, '*');
hold on;
plot(x0, y0);
title(['使用polyfit函数进行', num2str(n), '阶多项式拟合']);
```
通过对比手动实现和使用 `polyfit` 函数实现的结果,我们可以更加直观地理解最小二乘法曲线拟合的实际应用效果。
评论2
最新资源