曲线拟合 #

一、多项式拟合 #

1.1 polyfit函数 #

matlab
% 生成数据
x = linspace(0, 10, 100)';
y = 2*x.^2 + 3*x + 1 + 5*randn(size(x));

% 多项式拟合
p = polyfit(x, y, 2);  % 二次多项式
% p = [a2, a1, a0] 对应 y = a2*x^2 + a1*x + a0

% 计算拟合值
y_fit = polyval(p, x);

% 绘图
scatter(x, y, 10, 'b', 'filled');
hold on;
plot(x, y_fit, 'r-', 'LineWidth', 2);
hold off;
legend('原始数据', '拟合曲线');

1.2 拟合评估 #

matlab
% 计算残差
residuals = y - y_fit;

% 计算R²
SS_res = sum(residuals.^2);
SS_tot = sum((y - mean(y)).^2);
R2 = 1 - SS_res / SS_tot;

% 计算RMSE
RMSE = sqrt(mean(residuals.^2));

fprintf('R² = %.4f\n', R2);
fprintf('RMSE = %.4f\n', RMSE);

1.3 不同阶数比较 #

matlab
x = linspace(0, 4*pi, 100)';
y = sin(x) + 0.1*randn(size(x));

degrees = [1, 3, 5, 9];
colors = ['r', 'g', 'b', 'm'];

figure;
scatter(x, y, 10, 'k', 'filled');
hold on;

for i = 1:length(degrees)
    p = polyfit(x, y, degrees(i));
    y_fit = polyval(p, x);
    plot(x, y_fit, colors(i), 'LineWidth', 1.5);
    
    % 计算R²
    R2 = 1 - sum((y - y_fit).^2) / sum((y - mean(y)).^2);
    fprintf('阶数%d: R² = %.4f\n', degrees(i), R2);
end

hold off;
legend(['原始数据', arrayfun(@(d) sprintf('%d阶', d), degrees, 'UniformOutput', false)]);

二、线性回归 #

2.1 简单线性回归 #

matlab
% 数据
x = (1:100)';
y = 2*x + 3 + 10*randn(size(x));

% 使用regress
X = [ones(size(x)), x];
[b, bint, r, rint, stats] = regress(y, X);

fprintf('截距: %.4f (%.4f, %.4f)\n', b(1), bint(1,1), bint(1,2));
fprintf('斜率: %.4f (%.4f, %.4f)\n', b(2), bint(2,1), bint(2,2));
fprintf('R²: %.4f\n', stats(1));
fprintf('p值: %.6f\n', stats(3));

% 绘图
y_fit = X * b;
scatter(x, y, 10, 'b', 'filled');
hold on;
plot(x, y_fit, 'r-', 'LineWidth', 2);
hold off;

2.2 多元线性回归 #

matlab
% 数据
X1 = randn(100, 1);
X2 = randn(100, 1);
y = 2*X1 + 3*X2 + 1 + 0.5*randn(100, 1);

% 回归
X = [ones(100, 1), X1, X2];
[b, bint, r, rint, stats] = regress(y, X);

fprintf('截距: %.4f\n', b(1));
fprintf('X1系数: %.4f\n', b(2));
fprintf('X2系数: %.4f\n', b(3));
fprintf('R²: %.4f\n', stats(1));

2.3 fitlm函数 #

matlab
% 数据
X = randn(100, 2);
y = 2*X(:,1) + 3*X(:,2) + 1 + 0.5*randn(100, 1);

% 线性模型
mdl = fitlm(X, y);
disp(mdl);

% 获取系数
coefficients = mdl.Coefficients.Estimate;

% 预测
y_pred = predict(mdl, X);

三、非线性拟合 #

3.1 nlinfit函数 #

matlab
% 数据
x = linspace(0, 10, 100)';
y = 2*exp(-0.5*x) + 0.1*randn(size(x));

% 定义模型函数
model = @(p, x) p(1) * exp(-p(2) * x);

% 初始参数
beta0 = [1, 1];

% 非线性拟合
beta = nlinfit(x, y, model, beta0);
fprintf('参数: a=%.4f, b=%.4f\n', beta(1), beta(2));

% 预测
y_fit = model(beta, x);

% 绘图
scatter(x, y, 10, 'b', 'filled');
hold on;
plot(x, y_fit, 'r-', 'LineWidth', 2);
hold off;

3.2 lsqcurvefit函数 #

matlab
% 数据
x = linspace(0, 10, 100)';
y = 2*sin(x + 0.5) + 0.2*randn(size(x));

% 定义模型函数
model = @(p, x) p(1) * sin(x + p(2));

% 初始参数
p0 = [1, 0];

% 拟合
options = optimset('Display', 'off');
p = lsqcurvefit(model, p0, x, y, [], [], options);

fprintf('参数: A=%.4f, phi=%.4f\n', p(1), p(2));

% 预测
y_fit = model(p, x);

3.3 fit函数 #

matlab
% 数据
x = linspace(0, 10, 100)';
y = 2*exp(-0.5*x) + 0.1*randn(size(x));

% 使用fit函数
f = fit(x, y, 'exp1');  % 单指数模型

% 查看拟合结果
disp(f);

% 预测
y_fit = f(x);

% 绘图
plot(f, x, y);

四、拟合类型 #

4.1 内置拟合类型 #

matlab
% 多项式拟合
f = fit(x, y, 'poly1');   % 一次多项式
f = fit(x, y, 'poly2');   % 二次多项式
f = fit(x, y, 'poly3');   % 三次多项式

% 指数拟合
f = fit(x, y, 'exp1');    % y = a*exp(b*x)
f = fit(x, y, 'exp2');    % y = a*exp(b*x) + c*exp(d*x)

% 对数拟合
f = fit(x, y, 'log');     % y = a + b*log(x)

% 幂函数拟合
f = fit(x, y, 'power1');  % y = a*x^b
f = fit(x, y, 'power2');  % y = a*x^b + c

% 高斯拟合
f = fit(x, y, 'gauss1');  % 单高斯
f = fit(x, y, 'gauss2');  % 双高斯

% 正弦拟合
f = fit(x, y, 'sin1');    % y = a*sin(b*x + c)
f = fit(x, y, 'sin2');    % y = a*sin(b*x + c) + d

4.2 自定义拟合 #

matlab
% 数据
x = linspace(0, 5, 100)';
y = 2*x./(1 + x) + 0.05*randn(size(x));

% 自定义模型
ft = fittype('a*x/(b + x)', 'independent', 'x', 'coefficients', {'a', 'b'});

% 拟合
f = fit(x, y, ft, 'StartPoint', [1, 1]);

% 查看结果
disp(f);

% 绘图
plot(f, x, y);

五、拟合选项 #

5.1 设置拟合选项 #

matlab
% 创建拟合选项
opts = fitoptions('Method', 'NonlinearLeastSquares');
opts.StartPoint = [1, 1];
opts.Lower = [0, 0];       % 参数下界
opts.Upper = [Inf, Inf];   % 参数上界
opts.MaxIter = 1000;
opts.TolFun = 1e-6;

% 使用选项拟合
f = fit(x, y, 'exp1', opts);

5.2 排除异常点 #

matlab
% 排除范围外的点
f = fit(x, y, 'poly2', 'Exclude', x < 0.5 | x > 9.5);

% 排除指定索引
outliers = [10, 25, 50];
f = fit(x, y, 'poly2', 'Exclude', outliers);

六、拟合评估 #

6.1 goodness属性 #

matlab
% 拟合
f = fit(x, y, 'poly2');

% 获取拟合优度
gof = goodness(f);

fprintf('SSE: %.4f\n', gof.sse);       % 误差平方和
fprintf('R²: %.4f\n', gof.rsquare);    % 决定系数
fprintf('RMSE: %.4f\n', gof.rmse);     % 均方根误差
fprintf('调整R²: %.4f\n', gof.adjrsquare);

6.2 置信区间 #

matlab
% 拟合并获取置信区间
[f, gof, output] = fit(x, y, 'poly2');

% 参数置信区间
ci = confint(f, 0.95);
fprintf('参数1: %.4f (%.4f, %.4f)\n', f.p1, ci(1,1), ci(1,2));
fprintf('参数2: %.4f (%.4f, %.4f)\n', f.p2, ci(2,1), ci(2,2));
fprintf('参数3: %.4f (%.4f, %.4f)\n', f.p3, ci(3,1), ci(3,2));

% 预测置信区间
[y_pred, delta] = predict(f, x, 0.95);
y_lower = y_pred - delta;
y_upper = y_pred + delta;

七、实用示例 #

7.1 自动选择最佳拟合 #

matlab
function [best_fit, best_type] = auto_fit(x, y)
% AUTO_FIT 自动选择最佳拟合类型
    
    fit_types = {'poly1', 'poly2', 'poly3', 'exp1', 'power1'};
    best_r2 = -Inf;
    
    for i = 1:length(fit_types)
        try
            f = fit(x, y, fit_types{i});
            gof = goodness(f);
            
            fprintf('%s: R² = %.4f\n', fit_types{i}, gof.rsquare);
            
            if gof.rsquare > best_r2
                best_r2 = gof.rsquare;
                best_fit = f;
                best_type = fit_types{i};
            end
        catch
            fprintf('%s: 拟合失败\n', fit_types{i});
        end
    end
    
    fprintf('\n最佳拟合: %s (R² = %.4f)\n', best_type, best_r2);
end

7.2 拟合报告 #

matlab
function fit_report(f, x, y)
% FIT_REPORT 生成拟合报告
    
    gof = goodness(f);
    ci = confint(f);
    
    fprintf('\n========== 拟合报告 ==========\n');
    fprintf('拟合类型: %s\n', formula(f));
    fprintf('\n参数估计:\n');
    
    coeffs = coeffnames(f);
    values = coeffvalues(f);
    
    for i = 1:length(coeffs)
        fprintf('  %s = %.6f (%.6f, %.6f)\n', ...
                coeffs{i}, values(i), ci(1,i), ci(2,i));
    end
    
    fprintf('\n拟合优度:\n');
    fprintf('  SSE: %.6f\n', gof.sse);
    fprintf('  R²: %.6f\n', gof.rsquare);
    fprintf('  调整R²: %.6f\n', gof.adjrsquare);
    fprintf('  RMSE: %.6f\n', gof.rmse);
    fprintf('==============================\n');
end

八、总结 #

本章学习了:

  1. 多项式拟合:polyfit、polyval
  2. 线性回归:regress、fitlm
  3. 非线性拟合:nlinfit、lsqcurvefit、fit
  4. 拟合类型:多项式、指数、对数、幂函数
  5. 拟合选项:初始值、边界、排除点
  6. 拟合评估:R²、RMSE、置信区间

下一章将学习高级主题。

最后更新:2026-03-27