最小二乗法、重み付け最小二乗法、反復再重み付け最小二乗法(コード含む)【最小二乗線形解】



元のリンク:住所

個人的なメモ:
最小二乗法、加重最小二乗法、反復再加重最小二乗法。機能を実現する目的と合わせて、以下では主に導出結果、コード実装、およびいくつかの実用的なアプリケーションを示します。導出プロセスの最後には、個人的な参考のためのいくつかの記事や資料が配置されます。

推奨されるビデオ導出プロセスは次のとおりです。行列を使用して部分導出を見つけ、xxを取得します。x =( ATA ) − 1 ATB (A^TA)^{-1}A^TB( ATA_1A _T B行列乗算導出ビデオ

1: 最小二乗法 (OLS)

1。概要

最小二乗法 (最小二乗法とも呼ばれます) は、数学的最適化手法です。二乗誤差の合計を最小限に抑えることで、データに最適な関数を見つけます。最小二乗法を用いることで未知データを容易に求めることができ、得られたデータと実際のデータとの誤差の二乗和を最小化することができる。これは例です。たとえば、目的関数y = a 0 + a 1 x + a 2 x 2 y=a_0+a_1x+a_2x^2 が
決定されました。y=ある0+ある1バツ+ある2バツ2x と yx と yxyは決定された実際の値、xxxは独立変数yyyは従属変数です。0 、 a 1 、 a 2 a_0、a_1、a_2 がある0ある1ある23 つの未知パラメータ: 現時点では、3 つの未知パラメータを解き、唯一の解を決定するための連立方程式を形成するには、一般に 3 つの方程式が必要です。実際には、過剰決定方程式系で未知のパラメータが 3 つ存在することがよくあります (方程式の数が未知のパラメータよりも多い) この問題を解決するには、最小二乗法を使用して最適解を見つける必要があります。代数解と行列解を以下に示します。マトリックス溶液を使用することをお勧めします(非常に便利です)。

2: 代数式

最小二乗法の考え方は、理論値と予測値の間の距離の二乗和を最小化することです。
ここに画像の説明を挿入
例: 曲線近似で最も基本的で一般的に使用されるのは直線近似です。xxを設定しますxyyy間の関数関係は次のとおりです。 単項線形関数y = f ( a 0 , a 1 ) = a 0 + a 1 xy = f(a_0,a_1) = a_0+a_1xy f ( a0ある1) a0+ある1xの代数導出:
ここに画像の説明を挿入

0 と 1の場合、それぞれ a_0 と a_1ある0そして_1偏導関数を求めます。ここでは、a 0 と a 1、a_0 と a_1ある0そして_1未知のパラメータです
ここに画像の説明を挿入

方程式系に整理する
ここに画像の説明を挿入

次に、次のように単純化します。
ここに画像の説明を挿入

3: マトリックス (推奨)

例: 曲線近似で最も基本的で一般的に使用されるのは直線近似です。xxを設定しますxyyy間の関数関係は次のとおりです。 単項線形関数y = f ( a 0 , a 1 ) = a 0 + a 1 xy = f(a_0,a_1) = a_0+a_1xy f ( a0ある1) a0+ある1xは行列で表されます:A x = B Ax = B×=Bxxxベクトルパラメータ
ここに画像の説明を挿入

導出プロセスの最後にリンクを貼ります。それで:

ここに画像の説明を挿入

1 変数の多項式関数の場合:
ここに画像の説明を挿入
m は多項式の次数を表し、離散点と多項式の二乗の和はF ( a 0 , a 1 , . . . , am ) F(a_0, a_1、...、a_m )F ( _0ある1... あるメートルここで、nn はサンプリング ポイントの数を表します。

ここに画像の説明を挿入

1 変量多項式行列式は、1 変量線形項行列式と同じです: A x = B Ax = B×=B

ここに画像の説明を挿入
ここに画像の説明を挿入

3.1: 実装コード

/* 普通最小二乘 Ax = B
 * (A^T * A) * x = A^T * B
 * x = (A^T * A)^-1 * A^T * B
 */
Array<double,Dynamic,1> GlobleFunction::leastSquares(Matrix<double,Dynamic,Dynamic> A, Matrix<double,Dynamic,1> B)
{
    
    
    //获取矩阵的行数和列数
    int rows =  A.rows();
    int col = A.cols();
    //A的转置矩阵
    Matrix<double,Dynamic,Dynamic> AT;
    AT.resize(col,rows);

    //x矩阵
    Array<double,Dynamic,1> x;
    x.resize(col,1);

    //转置 AT
    AT = A.transpose();

    //x = (A^T * A)^-1 * A^T * B
    x = ((AT * A).inverse()) * (AT * B);
    return x;

}

Matrix は、Eigen ライブラリの行列クラスであり、代数演算を容易にするために、Eigen ライブラリがここで導入されています。

2: 加重最小二乗法 (WLS)

加重最小二乗法は、元のモデルに重みを付けて不均一分散性のない新しいモデルを作成し、通常の最小二乗法を使用してそのパラメーターを推定する数学的最適化手法です。百度百科事典

1: 対角行列 W を増やす

最小二乗法に基づいて対角行列WWを追加します。W、データの各セットに異なる重みを与えます。

ここに画像の説明を挿入
WT * WW^T * WWTW対角行列の各データの 2 乗により、負の数が削除されます。

ここに画像の説明を挿入

1.1: 実装コード

/* 加权最小二乘(WLS)  W为对角线矩阵
 * W²(Ax - B) = 0
 * W²Ax = W²B
 * (A^T * W^T * W * A) * x = A^T * W^T * W * B
 * x = (A^T * W^T * W * A)^-1 * A^T * W^T * W * B
 */
Array<double,Dynamic,1> GlobleFunction::reweightedLeastSquares(Matrix<double,Dynamic,Dynamic> A, Matrix<double,Dynamic,1> B,Array<double,Dynamic,1> vectorW)
{
    
    
    //获取矩阵的行数和列数
    int rows =  A.rows();
    int col = A.cols();
    //vectorW为空,默认构建对角线矩阵1
    if(vectorW.isZero())
    {
    
    
        vectorW.resize(rows,1);
        for(int i=0;i<rows;++i)
        {
    
    
            vectorW(i,0) = 1;
        }
    }
    
    //A的转置矩阵
    Matrix<double,Dynamic,Dynamic> AT;
    AT.resize(col,rows);

    //x矩阵
    Array<double,Dynamic,1> x;
    x.resize(col,1);

    //W的转置矩阵
    Matrix<double,Dynamic,Dynamic> WT,W;
    W.resize(rows,rows);
    WT.resize(rows,rows);

    //生成对角线矩阵
    W = vectorW.matrix().asDiagonal();
    //转置
    WT = W.transpose();
    //转置 AT
    AT = A.transpose();

    // x = (A^T * W^T * W * A)^-1 * A^T * W^T * W * B
    x = ((AT * WT * W * A).inverse()) * (AT * WT * W * B);
    return x;
}

Matrix は、Eigen ライブラリの行列クラスであり、代数演算を容易にするために、Eigen ライブラリがここで導入されています。

3: 反復再重み付け最小二乗法 (IRLS)

1: 反復再重み付け最小二乗法 (反復重み付け最小二乗法とも呼ばれる) (IRLS) は、pp の問題を解決するために使用されます。pノルム形式の目的関数に関する特定の最適化問題:Wikipedia反復重み付けは目的関数と既知のデータを適合させることができますが、現時点では一部のデータが全体の目的関数から遠く離れており、最小二乗法に参加すると、推定パラメータに大きな影響を与えます。パラメータを最適化し、遠くにあるデータの重みを低くし (あまり重要であるように見せないため、影響は比較的小さい)、近くのデータに大きな重みを与えます (影響が大きい) ために必要です。反復加重最小二乗法では、加重最小二乗法を確立して反復を実行し、最適値を推定します。
ここに画像の説明を挿入

反復アプローチにより、各ステップには次の形式の重み付き最小二乗問題を解くことが含まれます。
ここに画像の説明を挿入ここに画像の説明を挿入

2: 以下は、論文アドレスを解決するための論文の反復法です: Burrus, CS (2014). 反復再重み付け最小二乗法 ∗。

ここに画像の説明を挿入ここに画像の説明を挿入
MATLAB コード 1:

% m-file IRLS0.m to find the optimal solution to Ax=b
% minimizing the L_p norm ||Ax-b||_p, using basic IRLS.
% csb 11/10/2012
function x = IRLS0(A,b,p,KK)
if nargin < 4, KK=10; end;
x = pinv(A)*b; 					% Initial L_2 solution
E = [];
for k = 1:KK 					% Iterate
	e = A*x - b; 				% Error vector
	w = abs(e).^((p-2)/2); 		% Error weights for IRLS
	W = diag(w/sum(w)); 		% Normalize weight matrix
	WA = W*A; 					% apply weights
	x = (WA'*WA)\(WA'*W)*b; 	% weighted L_2 sol.
	ee = norm(e,p); E = [E ee]; % Error at each iteration
end
plot(E)

MATLAB コード 2:

% m-file IRLS1.m to find the optimal solution to Ax=b
% minimizing the L_p norm ||Ax-b||_p, using IRLS.
% Newton iterative update of solution, x, for M > N.
% For 2<p<infty, use homotopy parameter K = 1.01 to 2
% For 0<p<2, use K = approx 0.7 - 0.9
% csb 10/20/2012
function x = IRLS1(A,b,p,K,KK)
if nargin < 5, KK=10; end;
if nargin < 4, K = 1.5; end;
if nargin < 3, p = 10; end;
pk = 2; % Initial homotopy value
x = pinv(A)*b; 						% Initial L_2 solution
E = [];
for k = 1:KK 						% Iterate
	if p >= 2, pk = min([p, K*pk]);	    % Homotopy change of p
	else pk = max([p, K*pk]); end
	e = A*x - b; 						% Error vector
	w = abs(e).^((pk-2)/2); 			% Error weights for IRLS
	W = diag(w/sum(w)); 				% Normalize weight matrix
	WA = W*A; 							% apply weights
	x1 = (WA'*WA)\(WA'*W)*b;		    % weighted L_2 sol.
	q = 1/(pk-1); 						% Newton's parameter
	if p > 2, x = q*x1 + (1-q)*x; nn=p; % partial update for p>2
	else x = x1; nn=2; end 				% no partial update for p<2
	ee = norm(e,nn); E = [E ee]; 		% Error at each iteration
end
plot(E)

C++ コード:


/* 迭代重加权最小二乘(IRLS)  W为权重,p为范数
 * e = Ax - B
 * W = e^(p−2)/2
 * W²(Ax - B) = 0
 * W²Ax = W²B
 * (A^T * W^T * W * A) * x = A^T * W^T * W * B
 * x = (A^T * W^T * W * A)^-1 * A^T * W^T * W * B
 * 参考论文地址:https://www.semanticscholar.org/paper/Iterative-Reweighted-Least-Squares-%E2%88%97-Burrus/9b9218e7233f4d0b491e1582c893c9a099470a73
 */
Array<double,Dynamic,1> GlobleFunction::iterativeReweightedLeastSquares(Matrix<double,Dynamic,Dynamic> A, Matrix<double,Dynamic,1> B,double p,int kk)
{
    
    
    /* x(k) = q x1(k) + (1-q)x(k-1)
     * q = 1 / (p-1)
     */
    //获取矩阵的行数和列数
    int rows =  A.rows();
    int col = A.cols();

    double pk = 2;//初始同伦值
    double K = 1.5;

    double epsilong = 10e-9; // ε
    double delta = 10e-15; // δ
    Array<double,Dynamic,1> x,_x,x1,e,w;
    x.resize(col,1);
    _x.resize(col,1);
    x1.resize(col,1);
    e.resize(rows,1);
    w.resize(rows,1);
    //初始x  对角矩阵w=1
    x = reweightedLeastSquares(A,B);

    //迭代  最大迭代次数kk
    for(int i=0;i<kk;++i)
    {
    
    
        //保留前一个x值,用作最后比较确定收敛
        _x = x;

        if(p>=2)
        {
    
    
            pk = qMin(p,K*pk);
        }
        else
        {
    
    
            pk = qMax(p,K*pk);
        }
        //偏差
        e = (A * x.matrix()) - B;
        //偏差的绝对值//  求矩阵绝对值 :e = e.cwiseAbs(); 或 e.array().abs().matrix()
        e = e.abs();
        //对每个偏差值小于delta,用delta赋值给它
        for(int i=0;i<e.rows();++i)
        {
    
    
            e(i,0) = qMax(delta,e(i,0));
        }
        //对每个偏差值进行幂操作
        w = e.pow(p/2.0-1);
        w = w / w.sum();

        x1 = reweightedLeastSquares(A,B,w);

        double q = 1 / (pk-1);
        if(p>2)
        {
    
    
            x = x1*q + x*(1-q);
        }
        else
        {
    
    
            x = x1;
        }
        //达到精度,结束
        if((x-_x).abs().sum()<epsilong)
        {
    
    
            return x;
        }
    }
    return x;
}

C++ 実装コードは基本的に MATLAB と同じですが、WikipediaおよびBurrus, CS (2014) を参照してわずかに改良されています。

4: アプリケーション

以下は過剰決定方程式について解かれます。データ数が不明パラメータを超えています。

1: 円のフィッティング (アルゴリズム: 反復的に再重み付けされた最小二乗法)

1: 最小二乗効果を使用すると、外部ノイズの干渉がまだ比較的大きいことがわかります。以下は、反復再重み付け最小二乗アルゴリズムを使用して最適化します。
ここに画像の説明を挿入2: 反復再重み付け最小二乗法
1 回目の反復
ここに画像の説明を挿入
2 回目の反復 3 回目の
ここに画像の説明を挿入反復
ここに画像の説明を挿入4 回目の反復
ここに画像の説明を挿入...
20 回目の反復
ここに画像の説明を挿入

2: 直線フィッティング (アルゴリズム: 反復的に再重み付けされた最小二乗法)

1:y = a 0 + a 1 xy = a_0 + a_1xy=ある0+ある1x
の下の図では最小二乗法が使用されており、はるか下にあるデータ ノイズが全体の密なデータに大きな影響を与えていることがわかります。
ここに画像の説明を挿入1.2: 反復再重み付け最小二乗法を使用します
最初の反復nnまでの100 回目の反復です。
ここに画像の説明を挿入

ここに画像の説明を挿入n回の反復後、基本的にノイズは全体に影響を与えず、この時点で得られたパラメーターは理想的なものになります。

3: カーブフィッティング (アルゴリズム: 最小二乗法)

1: 最小二乗曲線フィッティング、最適な部分関数の探索
最小二乗法は曲線フィッティングの一般的な方法であり、この方法を使用することは、マッチング関数の選択において非常に重要です。いわゆるマッチング関数は、グラフ内の点で最適な一致を達成するために関数が通過するルートです。
そうしないと、オーバーフィッティングやアンダーフィッティングが発生します。
ここに画像の説明を挿入ここに画像の説明を挿入

ここに画像の説明を挿入ここに画像の説明を挿入
一次関数フィッティング:
ここに画像の説明を挿入
二次関数フィッティング:

ここに画像の説明を挿入
3次関数のフィッティング:
ここに画像の説明を挿入
4次関数のフィッティング:
ここに画像の説明を挿入
5次関数のフィッティング:

ここに画像の説明を挿入
六芒星のフィット:

ここに画像の説明を挿入
七角関数のフィッティング:
ここに画像の説明を挿入
八角関数のフィッティング:

ここに画像の説明を挿入

9 つの関数の適合:
ここに画像の説明を挿入
関数は 5 番目の関数で非常によく適合し、関数が進むにつれて過適合になっていくことがわかります。

4:N点校正(9点校正含む)(アルゴリズム:最小二乗法)

9 点キャリブレーションは、ビジョン内のピクセル座標と世界座標の間の関係を見つけることです。
ここに画像の説明を挿入halcon 演算子ブロック Vector_to_hom_mat2d が最小二乗法を使用して行列を計算していることがわかります。図の外部アルゴリズム [2] は、実際にはこの記事の最小二乗アルゴリズムによって実現されます。内部アルゴリズム [1] は偏導関数を計算することで実現されており、本記事ではN 点キャリブレーションを実装します。

5: まとめ

1: ツール: メイン Qt + Eigen ライブラリ+ QCustomPlot クラス
Eigen ライブラリは行列計算に使用され、代数計算ライブラリ
QCustomPlot クラスは描画とデータ視覚化に使用されます

2: 上記の完全なコードはGitHubにアップロードされています

3: 参照
最小二乗、代数導出、
最小二乗、行列導出、
最小二乗?
Shenma の絶対値正則化
ロバスト学習アルゴリズム最小二乗法の原理理解は悪くありません

最尤の観点から最小二乗法を理解する
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43763292/article/details/127839786