5

画像に示されているように、いくつかのデータ ポイントに直線的に適合させたいと考えています。切片 (この場合は 0.05) がわかっているので、この特定の切片を持つ線形領域にあるポイントのみを当てはめたいと思います。この場合、ポイントは 5:22 になります (22:30 ではありません)。この最適なポイント数を決定するための単純なアルゴリズムを探しています... うーん、それが問題です... R^2? それを行う方法はありますか?ポイント 1 から 2:30、2 から 3:30 などを使用して R^2 を調べようと考えていましたが、明確で単純な関数に含める方法がよくわかりません。私が使用している固定切片との適合のためにpolyfit0( http://www.mathworks.com/matlabcentral/fileexchange/272-polyfit0-m ) 。ご提案ありがとうございます。

編集: サンプル データ:

intercept = 0.043;
x = 0.01:0.01:0.3;
y = [0.0530642513911393,0.0600786706929529,0.0673485248329648,0.0794662409166333,0.0895915873196170,0.103837395346484,0.107224784565365,0.120300492775786,0.126318699218730,0.141508831492330,0.147135757370947,0.161734674733680,0.170982455701681,0.191799936622712,0.192312642057298,0.204771365716483,0.222689541632988,0.242582251060963,0.252582727297656,0.267390860166283,0.282890010610515,0.292381165948577,0.307990544720676,0.314264952297699,0.332344368808024,0.355781519885611,0.373277721489254,0.387722683944356,0.413648156978284,0.446500064130389;];

線形フィット

4

2 に答える 2

4

ここにあるのは、一般的な解決策を見つけるのがかなり難しい問題です。

1 つのアプローチは、すべての連続するポイントのペア間のすべての勾配/交点を計算し、交点でクラスター分析を行うことです。

slopes = diff(y)./diff(x);  
intersepts = y(1:end-1) - slopes.*x(1:end-1);

idx = kmeans(intersepts, 3);

x([idx; 3] == 2)  % the points with the intersepts closest to the linear one.

これには、統計ツールボックス ( 用kmeans) が必要です。これは私が試したすべての方法の中で最良のものですが、この方法で見つかったポイントの範囲には小さな穴がいくつかある可能性があります。たとえば、開始範囲と終了範囲の 2 点の勾配が直線の勾配に近い場合、これらの点は直線に属するものとして検出されます。これ (およびその他の要因) には、この方法で見つかったソリューションの後処理がもう少し必要になります。

別のアプローチ (私はうまく構築できませんでした) は、ループ内で線形フィットを実行し、そのたびに中間のあるポイントから両方のエンドポイントに向かってポイントの範囲を増やし、二乗誤差の合計が小さいままかどうかを確認することです。 . 「小さい」とは何かを定義することは非常に主観的であり、ヒューリスティックな方法で行う必要があるため、これはすぐにあきらめました。

上記のより体系的で堅牢なアプローチを試みました。

function test

    %% example data
    slope = 2;
    intercept = 1.5;

    x = linspace(0.1, 5, 100).';

    y         = slope*x + intercept;
    y(1:12)   = log(x(1:12)) + y(12)-log(x(12));
    y(74:100) = y(74:100) + (x(74:100)-x(74)).^8;

    y = y + 0.2*randn(size(y));


    %% simple algorithm

    [X,fn] = fminsearch(@(ii)P(ii, x,y,intercept), [0.5 0.5])

    [~,inds] = P(X, y,x,intercept)

end

function [C, inds] = P(ii, x,y,intercept)
% ii represents fraction of range from center to end,
% So ii lies between 0 and 1. 

    N = numel(x);
    n = round(N/2);  

    ii = round(ii*n);

    inds = min(max(1, n+(-ii(1):ii(2))), N);

    % Solve linear system with fixed intercept
    A = x(inds);
    b = y(inds) - intercept;

    % and return the sum of squared errors, divided by 
    % the number of points included in the set. This 
    % last step is required to prevent fminsearch from
    % reducing the set to 1 point (= minimum possible 
    % squared error). 
    C = sum(((A\b)*A - b).^2)/numel(inds);    

end

これは、目的のインデックス (この例では 12 と 74) の大まかな近似のみを見つけます。

fminsearchランダムな開始値 (実際にはちょうど ) で数十回実行されると、rand(1,2)信頼性が高まりますが、それでも自分の人生を賭けることはありません。

統計ツールボックスがある場合は、kmeansオプションを使用してください。

于 2012-11-12T05:23:40.157 に答える
1

データ値の数に応じて、データを比較的少数の重複するセグメントに分割し、各セグメントについて線形フィット、つまり1次係数を計算します(切片を知っていることを忘れないでください。すべてのセグメントで同じ)。

次に、各係数について、この仮説の線とデータセット全体の間のMSEを計算し、最小のMSEを生成する係数を選択します。

于 2012-11-12T09:05:01.897 に答える