logo

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

STLSQとは何か?

アルゴリズム

STLSQ

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

擬似コード

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

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

説明

特に STLSQ動的系 x˙=f(x)\dot{\mathbf{x}} = f \left( \mathbf{x} \right) の微分係数から作られた行列 Y=X˙Y = \dot{X} とライブラリ行列 X=Θ(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. ↩︎