7

プロットすると次のように見えるデータの配列があります。

http://s12.postimg.org/7ja47a6b1/temp.jpg

polyfitコマンドを使用して、おおよそ と の間の時間に最適な指数を決定する必要が1.7あり2.3ます。また、この指数フィットを単純な線形フィットと比較する必要があります。

Temp(t) = Temp0 * exp(-(t-t0)/tau)ここで、t0は温度に対応する時間です(Temp0曲線フィッティングを開始する場所を選択できますが、おおよそ 1.7 から 2.3 の間の領域に限定する必要があります)。これが私の試みです。

% Arbitrarily defined starting point
t0 = 1.71;

%Exponential fit
p = polyfit(time, log(Temp), 1)
tau = -1./p(1)
Temp0 = exp(p(2))

tm = 1.8:0.01:2.3;
Temp_t = Temp0*exp(-(tm)/tau);
plot(time, Temp, tm, Temp_t)

figure(2)

%Linear fit
p2 = polyfit(time, Temp, 1);
Temp_p = p2(1)*tm + p2(2);
plot(time, Temp, tm, Temp_p)

私の指数関数的フィットは のようになり指数フィットます。私の線形フィットは次のようになり線形フィットます。(実質的に同一)。私は間違って何をしていますか? 2つのフィット感はとても似ているはずですか? 参考になるかもしれないと言われましたcircshiftが、ヘルプファイルを読んでもコマンドの適用範囲がわかりませんでした。

4

4 に答える 4

4

コメントで述べたように、対数空間での線形モデルのフィッティングと非線形モデルのフィッティングには違いがあります (両方とも最小二乗の意味で)。

Statistics ツールボックスには、状況を説明する素晴らしいデモがあります。私は以下のコードを適応させています:

%# sample data
x = [5.72 4.22 5.72 3.59 5.04 2.66 5.02 3.11 0.13 2.26 ...
     5.39 2.57 1.20 1.82 3.23 5.46 3.15 1.84 0.21 4.29 ...
     4.61 0.36 3.76 1.59 1.87 3.14 2.45 5.36 3.44 3.41]';
y = [2.66 2.91 0.94 4.28 1.76 4.08 1.11 4.33 8.94 5.25 ...
     0.02 3.88 6.43 4.08 4.90 1.33 3.63 5.49 7.23 0.88 ...
     3.08 8.12 1.22 4.24 6.21 5.48 4.89 2.30 4.13 2.17]';

xx = linspace(min(x), max(x), 100);

%# linear regression in log-space
%#           y = p2 * exp(p1*x)
%#   => log(y) = log(p2) + p1*x
p_exp = polyfit(x, log(y), 1);
yy1 = exp(p_exp(2)) .* exp(xx .* p_exp(1));

%# linear regression
p_lin = polyfit(x, y, 1);
yy2 = polyval(p_lin, xx);

%# non-linear regression (using previous result as initial coeff)
f = @(p,x) p(2)*exp(p(1)*x);
p_nonlin = nlinfit(x, y, f, [p_exp(1) exp(p_exp(2))]);
yy3 = f(p_nonlin, xx);

plot(x,y,'o', xx,yy1,'-', xx,yy2,'-', xx,yy3,'-')
legend({'data points','linear in log-space','linear','non-linear'})

回帰

于 2013-05-27T20:35:54.030 に答える
4

期待どおりに動作しています。問題は、当てはめようとしている関数がデータの適切な近似ではないことです。曲線を観察すると、曲線の指数部は 16 付近の値に漸近する傾向があるようです。しかし、使用している関数は最終的に温度が 0 になる傾向があります。したがって、22 から 16 になる部分にフィッティングすると、ほぼ線形の関係が得られます。これを説明するために、私はあなたが持っているデータポイントにほぼ一致する数行のコードを書きました - そしてそれは異なる関数 (0 になる傾向のあるものと 16 になる傾向のあるもの) がどのように非常に異なる形の曲線を与えるかを示しています. 最初の (元の関数) は、22 と 16 の T 値の間でほぼ線形です。したがって、線形適合のように見えます。

適合する関数の「正しい」形状について考えることをお勧めします。特定の形状を選択する基礎となる物理学は何ですか? それを正しくすることが不可欠です...

コードは次のとおりです。

time = linspace(1.5, 2.5, 200);
t0 = 1.7;
t1 = 2.3;
tau = 2.0;

% define three sections of the function:
s1 = find(time < t0);
s2 = find(time >= t0 & time < t1);
s3 = find(time > 2.3);

% compute a shape for the function in each section:
tData(s1) = 28 - 50*(time(s1)-1.5).^2;
tData(s2) = 22*exp(-(time(s2)-t0)/tau);
tData(s3) = tData(s2(end)) + (s3 - s3(1))*12 / numel(s3);

figure
plot(time, tData)

% modify the equation slightly: assume equilibrium temperature is 16
% with a bit of effort one could fit for this as a second parameter
Teq = 16;
tData2 = tData;
tau2 = tau / 8; % decay more strongly to get down to approx the same value by t1
tData2(s2) = (22 - Teq) * exp( - (time(s2) - t0) / tau2) + Teq;
tData2(s3) = tData2(s2(end)) + (s3 - s3(1))*12 / numel(s3);

hold on;
plot(time, tData2, 'r')

これにより、次のプロットが得られます。

ここに画像の説明を入力

このことから、プロットが非常に似ている主な理由は、近似しようとしている関数が、選択しているドメインでほぼ線形であるためであると結論付けています。関数の別の選択は、より適切に一致します。

于 2013-05-27T22:35:08.480 に答える
2

私が正しく理解していれば、polyfit で使用している変数 time と Temp にはすべての値 (1.5 から 2.5 まで) が含まれています。そのため、polyfit を計算する前に、time と Temp の値を 1.71 から 2.3 に制限することをお勧めします (現在、1.5 から 2.5 までの polyfit を計算しているため、線がデータ ポイントと整列していません)。

p = polyfit(time, log(Temp), 1)
于 2013-05-27T17:34:19.063 に答える
0

使用する

polyfit(x,y,n)

Matlab カーブ フィッティング ツールボックスの関数。

于 2013-11-22T21:57:17.850 に答える