曲线拟合强烈变化的数据
Curve fitting a strongly varying data
我正在使用 Matlab 曲线拟合工具 cftool
来拟合我的数据。问题是 y
的值相对于 x-axis
变化很大(急剧下降)。下面给出一个示例,
x y
0.1 237.98
1 25.836
10 3.785
30 1.740
100 0.804
300 0.431
1000 0.230
2000 0.180
拟合格式为:y=a/x^b+c/x^d
,其中 a、b、c 和 d 为常量。 matlab
的曲线拟合对于较大的 y-values
(在较低的 x 范围内)非常准确,偏差小于 0.1%。然而,在更高 x-values
时,拟合的准确性并不好(大约 11% 的偏差)。我还想在曲线拟合迭代中包含 % deviation
以确保准确捕获数据。该图用于拟合和数据参考。
谁能建议我更好的拟合数据的方法?
拟合曲线最常用的方法是进行最小二乘法拟合,它可以最小化数据与拟合之间的平方差之和。这就是当 y 较大时拟合更紧密的原因:值 0.18 的 11% 偏差仅为 0.000392 的平方误差,而值 240 的 0.1% 偏差是 0.0576 的平方误差,更重要。
如果您关心的是偏差而不是绝对(平方)误差,那么您可以重新制定拟合算法,或者以巧妙的方式转换您的数据。第二种方式是常用的好用的工具要知道。
在您的情况下,一种方法是适合 log(y)
而不是 y
。这将使小错误变得更加重要:
data = [0.1 237.98
1 25.836
10 3.785
30 1.740
100 0.804
300 0.431
1000 0.230
2000 0.180];
x = data(:,1);
y = data(:,2);
% Set up fittype and options.
ft = fittype( 'a/x^b + c/x^d', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.420712466925742 0.585539298834167 0.771799485946335 0.706046088019609];
%% Usual least-squares fit
[fitresult] = fit( x, y, ft, opts );
yhat = fitresult(x);
% Plot fit with data.
figure
semilogy( x, y );
hold on
semilogy( x, yhat);
deviation = abs((y-yhat))./y * 100
%% log-transformed fit
[fitresult] = fit( x, log(y), ft, opts );
yhat = exp(fitresult(x));
% Plot fit with data.
figure
semilogy( x, y );
hold on
semilogy( x, yhat );
deviation = abs((y-yhat))./y * 100
一种方法是拟合最低平方和相对误差,而不是最低平方和绝对误差。当我使用您问题中发布的数据时,拟合最低平方和相对误差会产生 +/- 4% 的误差 - 因此这可能是一个有用的选项。为了验证您是否想考虑这种方法,这里是我使用这种方法从您发布的数据中确定的系数:
a = 2.2254477037465399E+01
b = 1.0038013513610324E+00
c = 4.1544917994119190E+00
d = 4.2684956973959676E-01
我正在使用 Matlab 曲线拟合工具 cftool
来拟合我的数据。问题是 y
的值相对于 x-axis
变化很大(急剧下降)。下面给出一个示例,
x y
0.1 237.98
1 25.836
10 3.785
30 1.740
100 0.804
300 0.431
1000 0.230
2000 0.180
拟合格式为:y=a/x^b+c/x^d
,其中 a、b、c 和 d 为常量。 matlab
的曲线拟合对于较大的 y-values
(在较低的 x 范围内)非常准确,偏差小于 0.1%。然而,在更高 x-values
时,拟合的准确性并不好(大约 11% 的偏差)。我还想在曲线拟合迭代中包含 % deviation
以确保准确捕获数据。该图用于拟合和数据参考。
谁能建议我更好的拟合数据的方法?
拟合曲线最常用的方法是进行最小二乘法拟合,它可以最小化数据与拟合之间的平方差之和。这就是当 y 较大时拟合更紧密的原因:值 0.18 的 11% 偏差仅为 0.000392 的平方误差,而值 240 的 0.1% 偏差是 0.0576 的平方误差,更重要。
如果您关心的是偏差而不是绝对(平方)误差,那么您可以重新制定拟合算法,或者以巧妙的方式转换您的数据。第二种方式是常用的好用的工具要知道。
在您的情况下,一种方法是适合 log(y)
而不是 y
。这将使小错误变得更加重要:
data = [0.1 237.98
1 25.836
10 3.785
30 1.740
100 0.804
300 0.431
1000 0.230
2000 0.180];
x = data(:,1);
y = data(:,2);
% Set up fittype and options.
ft = fittype( 'a/x^b + c/x^d', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.420712466925742 0.585539298834167 0.771799485946335 0.706046088019609];
%% Usual least-squares fit
[fitresult] = fit( x, y, ft, opts );
yhat = fitresult(x);
% Plot fit with data.
figure
semilogy( x, y );
hold on
semilogy( x, yhat);
deviation = abs((y-yhat))./y * 100
%% log-transformed fit
[fitresult] = fit( x, log(y), ft, opts );
yhat = exp(fitresult(x));
% Plot fit with data.
figure
semilogy( x, y );
hold on
semilogy( x, yhat );
deviation = abs((y-yhat))./y * 100
一种方法是拟合最低平方和相对误差,而不是最低平方和绝对误差。当我使用您问题中发布的数据时,拟合最低平方和相对误差会产生 +/- 4% 的误差 - 因此这可能是一个有用的选项。为了验证您是否想考虑这种方法,这里是我使用这种方法从您发布的数据中确定的系数:
a = 2.2254477037465399E+01
b = 1.0038013513610324E+00
c = 4.1544917994119190E+00
d = 4.2684956973959676E-01