ぽんのブログ -22ページ目

ぽんのブログ

自分用の備忘録ブログです。書いてある内容、とくにソースは、後で自分で要点が分かるよう、かなり簡略化してます(というか、いい加減)。あまり信用しないように(汗

停止条件も含めて計算手順をまとめます。またそれぞれの操作を octave でも書いてみました。

ここで、前回 1A ( = ones (length(A), 1) ) としていた部分を s ( = sign (βj) = sign (cj) ) で置き換えます。それに伴い XA の部分も変更します。こちらの方がすっきりします。

観測データベクトルを y 、説明変数を列に格納した行列を X
X のサイズを m、 n に格納

[m, n] = size(X);

入力データ Xy を基準化及び中心化

y = y - mean(y);
for i = 1:n
  Xi = X( : , i);
  Xi= Xi - mean(Xi);
  Xi = Xi / sqrt( Xi' * Xi);
end


1.初期値設定


停止フラグをリセット

mu = zeros(m, 1);    % μ = 0
beta = zeros(n , 1);  % β= 0
A = [];                  % A = φ
stop_flag = false;


2.correlationの更新



c = X' * (y - mu);

相関の絶対値の最大値を更新


A = φ ならその指標を記録


[ hat_c, c_amax_idx_tmp] = max( abs(c) );

if ( length(A) == 0 ),
  c_amax_idx = c_amax_idx_tmp;
end


3.アクティブセットを更新

 ならそれをアクティブセットに加える。



if c_amax_idx >= 0,
  A = [A, c_amax_idx];
end


4.等角ベクトルを更新













XA = X( : , A);                          % XA
GA = XA' * XA;                        % gA
invGA = inv(GA);
s = sign( c(A) );                       % s
absA = 1 / (s' * invGA * s);        % A_A
u = XA * wa;                           % uA


5.ステップサイズを更新



ここに

a = X' * u;
Ac = setdiff(1 : n, A);     % complement of A
for i = 1:length(Ac),
  j = Ac(i);
  e1 = (hat_C - c(j) ) / (absA - a(j) );
  e2 = (hat_C + c(j) ) / (absA + a(j) );
  if e1 <= 0., e1 = Inf; end
  if e2 <= 0., e2 = Inf; end
  gamma_hat_tmp(i) = min(e1, e2);
end

[ gamma_hat, idx ] = min( gamma_hat_tmp );
gamma_hat_idx = Ac(idx);




gamma_tilde_tmp = - beta (A) . / w;
gamma_tilde_tmp( gamma_tilde_tmp <= 0 ) = Inf;
[ gamma_tilde, gamma_tilde_idx ] = min(gamma_tilde_tmp);
if isnan(gamma_tilde),
  gamma_tilde = Inf;
end


なら
なら

if gamma_hat < gamma_tilde,
  step_size = gamma_hat;
else
  step_size = gamma_tilde;
end


6.βを更新



beta_new = zeros(n, 1);
beta_new(A) = beta(A) + step_size * w;


7.βのL1ノルムと閾値 t の比較



ならステップサイズを以下に更新


βを以下の線形補完値に更新しなおし、停止フラグを立てる。



nrm1_prev = sum( abs( beta ) );
nrm1_cur = sum( abs( beta_new ) );

if nrm1_prev <= t && t <= nrm1_cur,
  step_size = absA * (t - nrm1_prev);
  beta_new(A) = beta(A) + step_size * w;
  stop_flag = true;
end


8.β、μを更新

β = β'


beta = beta_new;
mu = mu + step_size * u;


9.ストップフラグが立っていなければアクティブセットを更新

 なら に対応する指標 j について とおく。
 なら に対応する指標をアクティブセットから除く。

if ~stop_flag,
  if gamma_hat < gamma_tilde,
    c_amax_idx = gamma_hat_idx;
  else
    A( gamma_tilde_idx ) = [];
    c_amax_idx = -1;
  end
end

以下 length(A) < n && !stop_flag の間 2~9 を繰り返す。