logo

STLSQとは何か? 📂統計的分析

STLSQとは何か?

アルゴリズム

STLSQ

フルランクの行列 $X \in \mathbb{R}^{m \times p}$ と $Y \in \mathbb{R}^{m \times n}$ が与えられたとき、割と スパース な $B \in \mathbb{R}^{p \times n}$ を見つけるスパース回帰問題を考えよう。STLSQsequentially Thresholded Least-Squares Algorithm は、「SINDy」Algorithm を提案したブルントンが使っていた方法で、名前の通り、 最小二乗法 を繰り返し利用し、各成分の 絶対値 が与えられたしきい値 $\lambda$ より下がったら $0$ として扱い、その列(独立変数) を排除する仕組みになっている。

擬似コード

共通して、括弧で囲まれた上付きのテキスト $\cdot ^{(k)}$ は $k$ 番目を、 $[p] = \left\{ 1 , \cdots , p \right\} \subset \mathbb{N}$ は $1$ から $p$ までの 自然数集合 を示す。 $X^{\dagger}$ は行列 $X$ の 擬似逆行列 であり、最小二乗法 によって得られる。インデックス集合 $S$ に対して、 $\mathbf{x}_{S}$ はベクトル $\mathbf{x}$ の該当インデックスだけを残したベクトル、 $X_{S}$ は行列 $X$ の該当列だけを残した行列である。

アルゴリズム: STLSQ
入力しきい値 $\lambda \ge 0$ が与えられる。
1.実行回数 $k := 0$、 $B^{(0)} := X^{\dagger} Y$ および $S^{(-1)} = \emptyset$ を初期化する。
2.$S^{(0)} := \left\{ S_{j}^{(0)} = \left\{ i \in [p] : \left| \left( B^{(0)} \right)_{ij} \right| > \lambda \right\} : j \in [n] \right\}$# $i \in S_{j} \subset S$ は $(B)_{ij} \ne 0$ と同じ意味だ。
3.while $S^{(k)} \ne S^{(k-1)}$ do
4.   for $j \in [n]$ do
5.     $\widehat{X} = X_{S_{j}^{(k)}}$# 列 $B_{ij} = 0$ を削除
6.     $\left( B^{(k+1)} \right)_{S_{j}^{(k)}, \left\{ j \right\}} = \widehat{X}^{\dagger} Y_{\left\{ j \right\}}$# 列を一つずつ更新
7.     $S_{j}^{(k+1)} = \left\{ i \in [p] : \left| \left( B^{(k+1)} \right)_{ij} \right| > \lambda \right\}$
8.   end for
9.   $k = k+1$
10.end while
11.$i \in S_{j}^{(k)} \subset S^{(k)}$ を満たさない全ての $(i,j)$ に対して $B_{ij}^{(k)} = 0$ を適用する
出力各成分の 絶対値 の大きさが $\lambda$ より大きい行列 $B^{(k)} = \argmin_{B} \left\| XB - Y \right\|$ を得る。

説明

特に STLSQ動的系 $\dot{\mathbf{x}} = f \left( \mathbf{x} \right)$ の微分係数から作られた行列 $Y = \dot{X}$ とライブラリ行列 $X = \Theta (X)$ に対して行われる場合、我々はそれを「SINDy」と呼ぶ1。一見するとSTLSQ自体がSINDyのために出たと言えるが、アルゴリズムの観点からはSTLSQ自体が動的系と全く関係なくそのまま作動できるため、「SINDy」という名前の代わりに言及されることもままある。

アルゴリズムの擬似コードを読めば分かるように、STLSQは一種の グリーディアルゴリズム だ。アルゴリズムの収束性が証明されたこと2とは別に、回帰分析の統計的側面から言えば正直、意味がないが、実装が簡単で収束速度が非常に速く、何はともあれ スパース回帰 を行うという点では疑いようのない有用な方法と言える。

コード

Matlab

以下は、ブルントン教授が自分の研究で使っている実際の Matlab コードだ3

%% compute Sparse regression: sequential least squares
Xi = Theta\dXdt; % initial guess: Least-squares

% lambda is our sparsification knob.
for k=1:10
    smallinds = (abs(Xi)<lambda); % find small coefficients
    Xi(smallinds)=0; % and threshold
    for ind = 1:n % n is state dimension
        biginds = ˜smallinds(:,ind);
        % Regress dynamics onto remaining terms to find sparse Xi
        Xi(biginds,ind) = Theta(:,biginds)\dXdt(:,ind);
    end
end

Python

ブルントン教授の著書4 にある Python コードだ。

def sparsifyDynamics(Theta,dXdt,lamb,n):
    # Initial guess: Least-squares
    Xi = np.linalg.lstsq(Theta,dXdt,rcond=None)[0]

    for k in range(10):
        smallinds = np.abs(Xi) < lamb # Find small coeffs.
        Xi[smallinds]=0 # and threshold
        for ind in range(n): # n is state dimension
            biginds = smallinds[:,ind] == 0
            # Regress onto remaining terms to find sparse Xi
            Xi[biginds,ind] = np.linalg.lstsq(Theta[:,
                biginds],dXdt[:,ind],rcond=None)[0]
        return Xi

Julia

私が使っている Julia コードだ。

using SparseArrays

function STLSQ(Θ, dXdt, λ = 10^(-6))
    if Θ isa AbstractSparseMatrix
        Θ = Matrix(Θ)
    end
    Ξ = Θ \ dXdt
    dim = size(Ξ, 2)
    __🚫 = 0
    
    while true
        print(".")
        🚫 = abs.(Ξ) .< λ
        Ξ[🚫] .= 0
        for j in 1:dim
            i_ = .!🚫[:, j]
            Ξ[i_, j] = Θ[:,i_] \ dXdt[:,j]
        end
        if __🚫 == 🚫 println("Stopped!"); break end # Early stopping
        __🚫 = deepcopy(🚫)
    end
    println("MSE: ", sum(abs2, Θ * Ξ - dXdt) / length(dXdt))

    return Ξ
end

  1. Brunton. (2016). Discovering governing equations from data by sparse identification of nonlinear dynamical systems: https://doi.org/10.1073/pnas.1517384113 ↩︎

  2. Zhang, L., & Schaeffer, H. (2019). On the convergence of the SINDy algorithm. Multiscale Modeling & Simulation, 17(3), 948-972. https://doi.org/10.1137/18M1189828 ↩︎

  3. https://www.pnas.org/doi/suppl/10.1073/pnas.1517384113/suppl_file/pnas.1517384113.sapp.pdf ↩︎

  4. Brunton. (2022). Data-Driven Science and Engineering : Machine Learning, Dynamical Systems, and Control(2nd Edition): p276. ↩︎