1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

時変係数モデルとは?TVP回帰の予測力とWhat-If分析を解説

Posted at

user:

先日教えてもらったこのPythonコードについて、詳しく教えてください。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.mlemodel import MLEModel

# 時変係数回帰モデルのクラス
class TVPRegression(MLEModel):
    def __init__(self, endog, exog):
        k_states = exog.shape[1]
        super().__init__(endog, k_states=k_states, initialization='approximate_diffuse')

        self.nobs = len(endog)
        self.k_exog = k_states

        # design行列は (k_endog, k_states, nobs) → (1, k_states, nobs)
        self['design'] = exog.T[np.newaxis, :, :]
        self['transition'] = np.eye(k_states)
        self['selection'] = np.eye(k_states)

    def update(self, params, **kwargs):
        params = super().update(params, **kwargs)
        self['obs_cov'] = np.array([[params[0]]])  # 観測誤差の分散
        Q = np.diag(params[1:]**2)                 # 状態ノイズの共分散(対角)
        self['state_cov'] = Q


# TVP回帰の推定関数
def fit_tvp_regression(df, exog_cols=['X1', 'X2', 'X3'], target_col='Y', plot=True):
    """
    状態空間モデルによるTVP回帰の推定。

    Parameters
    ----------
    df : pd.DataFrame
        時系列データフレーム。
    exog_cols : list of str
        説明変数カラム名(デフォルト: ['X1', 'X2', 'X3'])。
    target_col : str
        目的変数カラム名(デフォルト: 'Y')。
    plot : bool
        結果を可視化するかどうか。

    Returns
    -------
    res : statsmodels 結果オブジェクト
        推定結果。
    coeffs_df : pd.DataFrame
        推定された時変係数の時系列。
    """
    endog = df[target_col].values
    exog = df[exog_cols].values

    model = TVPRegression(endog, exog)
    k_exog = exog.shape[1]
    initial_params = np.r_[1.0, np.repeat(0.1, k_exog)]
    res = model.fit(start_params=initial_params, disp=False)

    # 平滑化された状態(係数)を抽出
    smoothed_coeffs = res.smoothed_state.T
    coeffs_df = pd.DataFrame(smoothed_coeffs, index=df.index, columns=[f'beta{i+1}_est' for i in range(k_exog)])

    # プロット
    if plot:
        plt.figure(figsize=(14, 6))
        for i, exog_col in enumerate(exog_cols):
            est = coeffs_df.iloc[:, i]
            plt.plot(coeffs_df.index, est, label=f'Est. beta{i+1} ({exog_col})')
            true_col = f'beta{i+1}_true'
            if true_col in df.columns:
                plt.plot(df.index, df[true_col], '--', label=f'True beta{i+1}', alpha=0.7)
        plt.title("Time-Varying Coefficients (Estimated vs True)")
        plt.xlabel("Date")
        plt.ylabel("Coefficient Value")
        plt.legend()
        plt.grid(True)
        plt.tight_layout()
        plt.show()

    return res, coeffs_df

assistant:

こちらのコードは「状態空間モデルを用いて時変係数回帰(Time-Varying Parameter Regression)を推定する Python 実装」です。以下に、コードの各構成要素の詳細な解説をします。


🔧 全体の目的

  • 回帰係数が時間とともに変動するようなモデル(時変係数モデル)を、状態空間モデル(State Space Model)として構築し、statsmodelsライブラリで推定します。
  • 応用例:マクロ経済分析・金融時系列などで、係数が安定していないときに有用。

1. 必要なライブラリのインポート

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.mlemodel import MLEModel
  • statsmodels.tsa.statespace.mlemodel.MLEModel は、状態空間モデルの拡張クラスを自作するためのベースクラスです。

2. TVPRegression クラス:時変係数回帰モデルの定義

class TVPRegression(MLEModel):

初期化処理 __init__

    def __init__(self, endog, exog):
        k_states = exog.shape[1]
        super().__init__(endog, k_states=k_states, initialization='approximate_diffuse')
  • endog: 目的変数 (例: Y)
  • exog: 説明変数(例: X1, X2, X3)
  • k_states: 状態ベクトルの次元=説明変数の数(βの数)
  • initialization='approximate_diffuse':状態の初期値を「不確実性が大きい」という仮定で設定

状態空間モデルの構造指定

        self['design'] = exog.T[np.newaxis, :, :]   # Z_t (観測方程式の設計行列)
        self['transition'] = np.eye(k_states)       # T_t:単位行列 → β_t = β_{t-1} + η_t
        self['selection'] = np.eye(k_states)        # R_t:状態ノイズを全ての状態に適用

状態空間モデルの意味

  • 観測方程式(Observation Equation):

    $$
    y_t = \mathbf{x}_t^\top \beta_t + \epsilon_t
    $$

  • 状態方程式(State Equation):

    $$
    \beta_t = \beta_{t-1} + \eta_t
    $$

    → ランダムウォークのように、係数が時間とともに変化


update 関数:パラメータの更新

    def update(self, params, **kwargs):
        params = super().update(params, **kwargs)
        self['obs_cov'] = np.array([[params[0]]])  # ε_t の分散
        Q = np.diag(params[1:]**2)                 # η_t の分散(正定値にするため2乗)
        self['state_cov'] = Q
  • params[0]: 観測ノイズの分散 $\sigma^2_{\epsilon}$
  • params[1:]: 状態ノイズ(係数の変動)の分散(対角成分)

3. fit_tvp_regression 関数:推定と可視化

入力と初期設定

endog = df[target_col].values
exog = df[exog_cols].values

model = TVPRegression(endog, exog)
initial_params = np.r_[1.0, np.repeat(0.1, k_exog)]
  • initial_params: 観測誤差と状態ノイズの初期値(1.0, 0.1, 0.1, 0.1 など)

モデル推定

res = model.fit(start_params=initial_params, disp=False)
  • 状態空間モデルを最大尤度法で推定(Kalmanフィルタを内部で使用)

平滑化された係数の取り出し

smoothed_coeffs = res.smoothed_state.T
coeffs_df = pd.DataFrame(smoothed_coeffs, index=df.index, columns=[f'beta{i+1}_est' for i in range(k_exog)])
  • res.smoothed_state: 各時点での状態(=β)を平滑化推定したもの(Kalman smoother)
  • coeffs_df: 時系列データとしてβ₁, β₂,...を整形

可視化

if plot:
    plt.figure(figsize=(14, 6))
    for i, exog_col in enumerate(exog_cols):
        est = coeffs_df.iloc[:, i]
        plt.plot(coeffs_df.index, est, label=f'Est. beta{i+1} ({exog_col})')
        true_col = f'beta{i+1}_true'
        if true_col in df.columns:
            plt.plot(df.index, df[true_col], '--', label=f'True beta{i+1}', alpha=0.7)
  • 推定された時変係数 vs 真の係数(beta1_true などがあれば)を重ねて可視化

✨まとめ:このコードでできること

項目 内容
モデル 状態空間による時変係数回帰(ランダムウォーク)
推定手法 Kalmanフィルタ+最大尤度法
推定対象 各時点における β₁ₜ, β₂ₜ, ...(時変係数)
実装の特徴 MLEModel の継承で柔軟に定義可
可視化 推定値と真値(あれば)の時系列グラフ

💡応用の方向性

  • 状態方程式を AR(1) にするなど、より複雑な動学構造に拡張
  • 回帰係数以外にも、分散などを時変にしたモデルへの拡張(Stochastic Volatilityなど)
  • 共分散に対角成分以外も許す:係数同士の共変動の表現

ご希望があれば、以下も追加説明できます:

  • Kalmanフィルタ/スムーザー の数式解説
  • モデル拡張例(例えばAR(1)型状態、ベイズ推定など)
  • beta_true を持つ疑似データの生成コード

どうしますか?

user:

ありがとうございます。「状態空間モデルを最大尤度法で推定(Kalmanフィルタを内部で使用)」の部分について詳しく教えてください。

assistant:

こちらこそ、丁寧に聞いてくださってありがとうございます!
ご質問の「**状態空間モデルを最大尤度法で推定(Kalmanフィルタを内部で使用)」**について、以下のようにステップを分けて詳しくご説明します。


🔁 全体の流れ:状態空間モデル × 最大尤度法

時変係数モデルは「状態空間モデル(State Space Model)」で表現され、これを statsmodels では MLEModel を使って最大尤度推定します。

1. 状態空間モデルの構成

一般的に以下のように表現されます:

観測方程式(Observation Equation)

$$
y_t = Z_t \alpha_t + \epsilon_t, \quad \epsilon_t \sim \mathcal{N}(0, H_t)
$$

  • $y_t$:観測される目的変数
  • $Z_t$:デザイン行列(説明変数)
  • $\alpha_t$:状態ベクトル(時点 t の係数)
  • $H_t$:観測誤差の分散(スカラーや行列)

状態方程式(State/Transition Equation)

$$
\alpha_t = T_t \alpha_{t-1} + R_t \eta_t, \quad \eta_t \sim \mathcal{N}(0, Q_t)
$$

  • $T_t$:状態の遷移行列(恒等行列ならランダムウォーク)
  • $Q_t$:状態ノイズの分散共分散行列

🧠 モデル推定の考え方:最大尤度法(MLE)

目標:

  • **パラメータ(観測誤差の分散、状態ノイズの分散など)**を推定したい。
  • そのために、「観測された系列 $y_1, ..., y_T$ が得られる確率(尤度)」を最大化する。

🔍 Kalmanフィルタの役割:尤度の計算

最大尤度法には、**尤度(Likelihood)**の計算が不可欠ですが、時系列データでは 時点ごとの誤差が逐次的に依存しているため、単純な積では計算できません。

ここで登場するのが Kalmanフィルタ

Kalmanフィルタの処理ステップ(時系列 t = 1 → T):

  1. 予測
    状態 $\alpha_t$ の事前分布(予測値と誤差分散)を生成

  2. 観測更新
    実際の $y_t$ を観測して状態分布を修正(カルマンゲイン)

  3. 尤度の計算
    $y_t$ の予測誤差 $v_t = y_t - \hat{y}_t$ を用いて、

    $$
    \log p(y_t | y_{1:t-1}) \sim -\frac{1}{2} \left[ \log|\Sigma_t| + v_t^\top \Sigma_t^{-1} v_t \right]
    $$

    を積み上げてトータルの対数尤度を得る。

statsmodelsMLEModel.fit() はこの Kalman フィルタ処理と対数尤度の最適化を自動で行ってくれるのです。


⚙️ MLEModel.fit() の中で何が起きているか?

以下のような処理が行われます:

  1. update(params) を呼び出して、obs_covstate_cov を内部的に更新
  2. 与えられた params に対し、Kalmanフィルタで対数尤度を計算
  3. scipy.optimize を使って params を最適化(尤度最大化)
  4. 最適なパラメータで平滑化(Kalman smoother)を実行

🔢 数式でのイメージ(観測誤差はスカラー、状態ノイズは対角)

状態空間表現:

$$
\begin{align}
y_t &= \mathbf{x}t^\top \beta_t + \epsilon_t, \quad \epsilon_t \sim \mathcal{N}(0, \sigma^2) \
\beta_t &= \beta
{t-1} + \eta_t, \quad \eta_t \sim \mathcal{N}(0, \text{diag}(\tau_1^2, \tau_2^2, \ldots))
\end{align}
$$

最適化対象のパラメータは:

$$
\theta = \left[ \sigma^2, \tau_1, \tau_2, \ldots \right]
$$


📌 最後に:このプロセスの位置づけまとめ

ステップ 内容
モデル構築 MLEModel で観測・状態方程式を定義
パラメータ更新 update(params) で分散を設定
フィルタリング Kalman フィルタで逐次推定
尤度計算 各時点での観測尤度を積み上げ
最適化 scipy.optimize で尤度最大化
結果出力 res.smoothed_state などで平滑化係数を取得

✋補足を希望されるトピックはありますか?

  • Kalmanフィルタの具体的な計算ステップ(数式 or Python実装)
  • 観測ノイズ vs 状態ノイズの役割の違い
  • ベイズ的アプローチとの比較(MCMCなど)
  • MLEModelUnobservedComponentsDynamicFactor との違い

など、必要に応じて深掘りできます!

user:

このクラスは、時刻 t までのデータを学習したとき、時刻 t+1 以降を予測する性能を持ちますか? また、感応度分析を行う能力を持ちますか?

assistant:

とても良い質問です。
この TVPRegression クラスが 予測性能感応度分析にどう対応できるか、以下の観点で丁寧に解説します。


✅ Q1. 「t 時点までのデータで t+1 を予測する」ことはできる?

結論:**Yes(可能)**ですが、少しコードを補う必要があります。

このモデル(MLEModel ベース)は、状態空間モデルであるため、次のような「1ステップ先予測」ができます:

方法1:res.forecast() を使う(statsmodels 公式機能)

# 1ステップ先の予測(Y_{t+1})
y_pred = res.forecast(steps=1)

これは「t時点までのデータで学習した状態」を使い、t+1時点の $y_{t+1}$ の期待値を予測します。

方法2:状態ベクトル β_t を予測して、回帰式に使う

# β_t(最後の平滑化状態)
beta_t = res.smoothed_state[:, -1]

# t+1 の説明変数 x_{t+1} がわかっている場合:
x_t_plus1 = np.array([1.2, 0.3, -0.7])  # 仮の値

# y_{t+1} の予測
y_hat_t_plus1 = np.dot(x_t_plus1, beta_t)

このアプローチは「将来の X がわかっている」前提です。
forecast() の内部もこれとほぼ同じです(状態と予測誤差を考慮してます)。


🧭 Q2. 感応度分析(sensitivity analysis)は可能?

感応度分析の定義によりますが、以下の2つに分けて説明します。


✅ (A) 回帰係数の変動に対する感度

  • このモデルは 時点ごとの係数 $\beta_t$ を出力します。
  • つまり、各説明変数の効果の時間的な変化を見られるため、
    → **「時系列的な感応度分析」**ができます!
plt.plot(coeffs_df['beta1_est'])  # 説明変数 X1 の影響の時間変化

これは、特に金融・マクロ経済で「どの変数がいつ効いているか」を評価する重要な方法です。


✅ (B) 「変数のわずかな変化が予測値に与える影響を見る」感度分析

これは、いわば x の微小変化による y の変化(偏微分) を見ることで、
モデルがどれだけ反応するかを調べる方法です。

  • TVPRegression では、各時点で β_t が得られるため、
  • 任意の時点での感応度ベクトル = β_tがそのまま「感応度」になります!

例えば、t=100 の時点で:

coeffs_df.iloc[100]  # 各説明変数の感応度

→ これは、線形回帰の「偏回帰係数」と同じ解釈です。
(変数 X_i が1単位変化すると、Y が β_i 単位変化)


🛠 追加の感応度分析がしたければ…

以下のような拡張も可能です:

  • シナリオベースの感応度評価

    • $x_{t+1}$ を ±5% 変化させたときの $y_{t+1}$ の変化を見る
  • 変数除去の効果

    • 特定の変数を0にして再推定し、βや尤度の変化を確認
  • ブートストラップでの感度分析

    • サンプルを再抽出して係数の分布を見れば、「推定の不確かさに対する感度」も評価可

✨まとめ表

機能 TVPRegression での対応 説明
t+1 予測 ✅ 可能 res.forecast() や β_t × x_{t+1}
係数の感応度 ✅ 可能 時点ごとの β_t を出力
入力変化への感応度 ✅ 可能 β_t が傾きを表す
モデルの頑健性チェック ⚠ 拡張が必要 ブートストラップなどで対応可能

ご希望があれば:

  • t+h ステップ先予測(multi-step forecasting)の拡張コード
  • ブートストラップで β_t の信頼区間を出すコード
  • 感応度ヒートマップ(時系列 × 説明変数)の可視化

などもご紹介できます。いかがしますか?

user:

ありがとうございます。では、前述の class TVPRegression(MLEModel) クラスをベースに、次の機能を追加したコードを書いてください。

1、 t+h ステップ先予測(multi-step forecasting):h を入力すると、res.forecast() を使って、h ステップ先までの未来のデータを予測する機能

2、 説明変数名と p を入力すると、その説明変数を p パーセント上げた/下げた場合に目的変数が何パーセント変化するかを予測する機能

assistant:

了解しました!
以下に、TVPRegression クラスとそれを使った拡張関数を組み込んだ完全なコードをご提供します。


✅ 新機能の内容

  1. マルチステップ予測機能(forecast_tvp

    • h ステップ先までの未来の $y$ を予測
    • X_future(未来の説明変数列)を与えて使います
  2. 感応度分析機能(sensitivity_analysis_tvp

    • 指定した説明変数を ±p% 変化させた場合に、目的変数がどれだけ変わるかを予測
    • β(時点 t の平滑化係数)を使って計算

✅ 拡張コード(TVPRegression クラス + 機能追加)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.mlemodel import MLEModel

# ---- 時変係数回帰モデル ----
class TVPRegression(MLEModel):
    def __init__(self, endog, exog):
        k_states = exog.shape[1]
        super().__init__(endog, k_states=k_states, initialization='approximate_diffuse')

        self.nobs = len(endog)
        self.k_exog = k_states

        self['design'] = exog.T[np.newaxis, :, :]  # Z_t
        self['transition'] = np.eye(k_states)      # T_t
        self['selection'] = np.eye(k_states)       # R_t

    def update(self, params, **kwargs):
        params = super().update(params, **kwargs)
        self['obs_cov'] = np.array([[params[0]]])
        Q = np.diag(params[1:]**2)
        self['state_cov'] = Q


# ---- TVPモデルの推定 ----
def fit_tvp_regression(df, exog_cols=['X1', 'X2', 'X3'], target_col='Y', plot=True):
    endog = df[target_col].values
    exog = df[exog_cols].values

    model = TVPRegression(endog, exog)
    initial_params = np.r_[1.0, np.repeat(0.1, exog.shape[1])]
    res = model.fit(start_params=initial_params, disp=False)

    # 時変係数の抽出
    coeffs_df = pd.DataFrame(
        res.smoothed_state.T,
        index=df.index,
        columns=[f'beta{i+1}_est' for i in range(exog.shape[1])]
    )

    if plot:
        plt.figure(figsize=(14, 6))
        for i, exog_col in enumerate(exog_cols):
            plt.plot(coeffs_df.index, coeffs_df.iloc[:, i], label=f'Est. beta{i+1} ({exog_col})')
            true_col = f'beta{i+1}_true'
            if true_col in df.columns:
                plt.plot(df.index, df[true_col], '--', label=f'True beta{i+1}', alpha=0.7)
        plt.title("Time-Varying Coefficients (Estimated vs True)")
        plt.xlabel("Date")
        plt.ylabel("Coefficient Value")
        plt.legend()
        plt.grid(True)
        plt.tight_layout()
        plt.show()

    return res, coeffs_df


# ---- 機能1: マルチステップ予測 ----
def forecast_tvp(res, X_future: np.ndarray, steps: int):
    """
    hステップ先までの予測値を返す

    Parameters
    ----------
    res : fitted TVP model
    X_future : np.ndarray (h, k_exog)
        未来の説明変数
    steps : int
        予測ステップ数 h

    Returns
    -------
    y_preds : np.ndarray
        予測された y の配列 (長さ h)
    """
    assert X_future.shape[0] == steps, "X_future の行数は steps と一致させてください"

    last_state = res.smoothed_state[:, -1]
    y_preds = []
    for t in range(steps):
        x_t = X_future[t]
        y_pred = np.dot(x_t, last_state)
        y_preds.append(y_pred)
        # β_t をランダムウォークと仮定してそのまま保持
    return np.array(y_preds)


# ---- 機能2: 感応度分析 ----
def sensitivity_analysis_tvp(res, coeffs_df, x_current: np.ndarray, exog_cols: list, target_var: str, change_var: str, percent: float):
    """
    説明変数を±p%変化させた場合の y の変化率を予測する

    Parameters
    ----------
    res : fitted TVP model
    coeffs_df : pd.DataFrame
        推定係数の時系列
    x_current : np.ndarray
        現在の説明変数(最新の x_t)
    exog_cols : list of str
        説明変数名リスト
    target_var : str
        目的変数名(出力のラベル用)
    change_var : str
        感応度を測る説明変数名
    percent : float
        増減させる割合(例: 0.05 → ±5%)

    Returns
    -------
    result_dict : dict
        ±p%変化に対する y の予測変化率をまとめた辞書
    """
    assert change_var in exog_cols, f"{change_var} は説明変数に含まれていません"
    idx = exog_cols.index(change_var)

    beta_t = coeffs_df.iloc[-1].values  # 最新の係数

    x_up = x_current.copy()
    x_down = x_current.copy()
    x_up[idx] *= (1 + percent)
    x_down[idx] *= (1 - percent)

    y_base = np.dot(x_current, beta_t)
    y_up = np.dot(x_up, beta_t)
    y_down = np.dot(x_down, beta_t)

    change_up = 100 * (y_up - y_base) / abs(y_base)
    change_down = 100 * (y_down - y_base) / abs(y_base)

    return {
        "base_y": y_base,
        f"{change_var}_up_{percent*100:.1f}%": y_up,
        f"{change_var}_down_{percent*100:.1f}%": y_down,
        "y_change_%_up": change_up,
        "y_change_%_down": change_down
    }

✅ 使用例(想定)

1. モデル推定

res, coeffs_df = fit_tvp_regression(df, exog_cols=['X1', 'X2', 'X3'], target_col='Y')

2. 未来の説明変数を与えて h=5 ステップ先まで予測

X_future = np.array([[1.1, 0.9, 1.0],
                     [1.2, 1.0, 0.9],
                     [1.3, 0.8, 1.1],
                     [1.2, 0.9, 1.0],
                     [1.1, 1.0, 1.0]])
y_preds = forecast_tvp(res, X_future, steps=5)
print(y_preds)

3. 感応度分析:X2 を ±10% 変えた場合の Y の変化

x_current = np.array([1.0, 0.8, 1.2])  # 現在の説明変数の値
result = sensitivity_analysis_tvp(
    res,
    coeffs_df,
    x_current,
    exog_cols=['X1', 'X2', 'X3'],
    target_var='Y',
    change_var='X2',
    percent=0.10
)
print(result)

✅ まとめ

機能 実装関数 説明
マルチステップ予測 forecast_tvp() $h$ ステップ先の $y$ を予測
感応度分析 sensitivity_analysis_tvp() ある変数を ±p% 変化させたときの $y$ の変化率を出力

必要であれば、以下の拡張も可能です:

  • 状態ノイズの予測分散を考慮した信頼区間付き予測
  • 感応度分析を棒グラフやヒートマップで可視化
  • 多変量感応度分析(複数変数を同時に変化させる)

気になるものがあればお知らせください!

user:

すみません、未来予測って、「未来の説明変数」を与える必要があるんですか? 未来の目的変数はもちろん、未来の説明変数も普通は分からないですよね?

assistant:

まったくその通りです!
**「未来の説明変数は分からない」**という点は、時系列予測で非常に本質的な問題です。
以下に、その背景と対処方法を詳しく解説します。


✅ 状況整理:未来の予測に必要なもの

このモデルの構造(時変係数回帰)は:

$$
y_t = \mathbf{x}_t^\top \beta_t + \epsilon_t
$$

したがって、未来の $y_{t+1}, y_{t+2}, \dots$ を予測するには、対応する $\mathbf{x}{t+1}, \mathbf{x}{t+2}, \dots$(説明変数)も必要です。


❗現実的な問題

🔹**目的変数だけでなく、説明変数も未来には「未知」**であることが多い。

たとえば:

時点 X1(説明) Y(目的)
t 既知 既知
t+1 ❓未知 ❓未知

よって、**このモデル単体では「将来の説明変数がある前提」**でしか予測できません。


💡 解決策・現実的な対処法

① シナリオ分析(what-if 予測)

  • 将来の説明変数を仮定して予測
  • 例:「X1が1%上昇」「X2が現状維持」などの条件を設定して forecast() する

用途:政策介入の効果・経済指標の影響など「条件付き予測」


② 説明変数自体をモデル化する

  • 説明変数の予測モデルを別途構築する(ARIMA, VAR, 機械学習など)
  • 説明変数を未来まで予測 → その予測値を使って TVP モデルで Y を予測

例:

# X1 ~ X3 の時系列データで別途モデルを組む
X_future = predict_exog_model(X_past, h=5)
y_future = forecast_tvp(res, X_future, steps=5)

用途:自社の営業データ・経済指標など、説明変数が予測しやすい場合


③ 予測用のモデルを変更する

TVP回帰は基本的に「予測モデルというより解釈モデル」です。

  • 説明変数の時間的な影響を知る(感応度を見る)
  • 将来を厳密に予測するには不向きな場合も

📌 将来予測に強いモデル:

  • LSTM・Transformer などの深層学習時系列モデル
  • VAR(複数系列を同時に予測)
  • SARIMAX(exogありの予測モデル)

✋結論まとめ

質問 回答
未来予測には説明変数が必要か? Yes(このモデルの形式では必須)
でも未来の説明変数は普通わからない? Yes(なのでシナリオや別予測が必要)
回避策はあるか? ✅ シナリオ分析/説明変数の予測/モデル変更

✨次にやるなら…

  • X1, X2, X3 に対するシンプルな時系列モデル(例:AR(1))を構築して、未来の exog を生成してみますか?
  • あるいは、「未来はこうなるはず」という仮定をもとに、シナリオ別のY予測をして比較してみますか?

どちらか(あるいは両方)お手伝いできますので、お知らせください!

user:

将来予測に強いモデルとして、Prophetはどうですか?

assistant:

素晴らしい着眼点です。
将来予測(特に1変数の時系列データに対する予測)において、Meta社(旧Facebook)の Prophet は非常に有力な選択肢の一つです。
以下に Prophet の特徴と、時変係数モデルや他の予測モデルとの比較を交えてご説明します。


🔮 Prophetとは?

Prophet は以下の形式のモデルです:

$$
y(t) = g(t) + s(t) + h(t) + \varepsilon_t
$$

項目 意味
$g(t)$ トレンド(線形 or ロジスティック成長)
$s(t)$ 季節性(Fourier展開)
$h(t)$ 休日・イベント効果
$\varepsilon_t$ 残差(ノイズ)

✅ Prophet のメリット(予測モデルとして優秀な点)

特徴 内容
未来予測に特化 将来の y(t) を自然に予測できる
欠損値や不規則な時系列にも対応 リサンプル不要。カレンダーも柔軟
複雑なトレンド・季節性をモデル化 毎年・毎週の季節パターン、休日効果など
ユーザーによるシナリオ制御が簡単 休日イベント追加やトレンドの転換点指定が可能
複数ステップ予測(長期予測)に向く future データを生成するだけで自動的に先を予測

⚠ Prophet の限界・注意点

限界 内容
目的変数1変数しか基本扱えない 多変量回帰や時変係数モデルは組みにくい
説明変数(exogenous variables)の扱いが限定的 add_regressor() で追加できるが、あくまで外部項として追加されるだけで、複雑なダイナミクスは持たせづらい
信号変化(regime change)にはやや弱い 急激な構造変化があると追いつかないことも

🔁 TVP回帰との比較

観点 Prophet TVP回帰モデル(状態空間)
未来予測 ✅ 自動でできる ⚠ 説明変数が必要(わからなければ仮定が必要)
トレンド表現 ✅ 柔軟(piecewise linear) ⚠ 説明変数でトレンドを説明
季節性・イベント ✅ 強い(holiday対応) ❌ 手動で変数化しないと対応できない
説明変数の効果推定 △ add_regressor あり ✅ 各変数の影響が時点ごとに明示される
解釈性 △ やや抽象的 ✅ 回帰係数そのまま可視化できる

✨ まとめ:どちらを使うべきか?

目的 おすすめ
将来の数値(売上や需要など)をできるだけ正確に予測したい ✅ Prophet
説明変数の影響が「いつ強かったか」を時系列で知りたい ✅ TVP回帰
イベントや季節の効果を取り入れて先を見通したい ✅ Prophet
説明変数が複数あり、因果的な構造も見たい ✅ 状態空間モデル・VAR・ベイズモデルなど

🧪 ご希望に応じて:

  • Prophet のサンプルコード(休日/イベント追加含む)
  • Prophet + 外部変数 を使った拡張予測
  • TVP回帰Prophet の予測精度を比較する実験コード

などもご提供できます。興味のある方向を教えてください!

user:

なるほど、では、時変係数を取り扱えるのはTVP回帰だけという理解で正しいですか?

assistant:

とても鋭い質問です。
結論からお伝えすると:


✅ 結論

時変係数(time-varying coefficients)を明示的に扱えるモデルは TVP回帰だけではありませんが、TVP回帰はその中でも代表的かつ解釈性の高いアプローチです。


📚 「時変係数を扱えるモデル」の分類

1. ✅ TVP回帰(Time-Varying Parameter Regression)

  • 状態空間モデルで係数を「確率過程(多くはランダムウォーク)」とみなす
  • statsmodels.MLEModelpystan, pymc などで実装可能
  • 各説明変数の「時系列的な影響の変化」を見られる
  • 時変係数の王道

2. ✅ ローカル線形トレンドモデル(LLT)や拡張状態空間モデル

  • トレンドや係数が状態として変化する
  • UnobservedComponents, KalmanFilter, BayesianStructuralTimeSeries などで実装可能

3. ✅ ベイズ回帰(時間変化を考慮した階層モデル)

  • PyMC や Stan で、「係数が時間とともに変化する」ベイズモデルを構築

  • 例:

    $$
    \beta_t \sim \mathcal{N}(\beta_{t-1}, \tau^2)
    $$


4. ✅ 時変係数VAR(TVP-VAR)

  • VAR(Vector Autoregression)の係数が時間で変化
  • 経済学で人気:金融ショックや政権交代などの影響分析
  • 実装例:BVAR, pystan, Dynare, R: bvarsv

5. ⚠ ニューラルネットワーク(attention, RNNなど)

  • 明示的な係数はないが、入力の影響が時点によって変化する
  • attention 重みや hidden state を解析すれば「変動する影響」を間接的に捉えることはできる
  • ただし「係数が時系列でこう変わった」という明示的な形では出せない

6. ❌ ProphetやSARIMA

  • トレンドや季節性は扱えるが、説明変数の効果(係数)は時変ではない
  • add_regressor() で外部変数を追加できるが、係数は固定

✅ まとめ表

モデル種別 時変係数への対応 説明
TVP回帰 ✅ 明示的 状態空間で β_t をモデリング
Bayesian階層モデル ✅ 柔軟に可能 PyMC, Stan などで実装可能
TVP-VAR ✅ 複数系列で可能 経済系に強い
ニューラルネット(RNN等) △ 暗黙的 解釈性は低め
Prophet / ARIMA / SARIMA ❌ 対応しない 係数は時不変
OLS, Lasso など ❌ 対応しない 固定係数前提

✋補足:なぜ時変係数が重要?

  • 経済やマーケティングでは「ある変数がいつ効果を持ったか」が非常に重要
  • 固定係数だと過去に強かった変数が今も強い前提になる
  • TVPは「動的因果関係」や「政策の効果変化」を捉えるのに不可欠です

ご希望に応じて…

  • TVP回帰と Prophet の精度・係数比較のデモ
  • PyMC/Stanでのベイズ時変係数モデルの例
  • TVP-VAR の Python 実装(pystan or numpyベース)

などもご紹介できます。興味のある方向を教えてください!

user:

ありがとうございます。時変係数モデルで、時変係数の将来予測は可能ですか?

assistant:

こちらこそ、核心を突く非常に良いご質問です。
結論から言うと:


✅ 結論:

はい、時変係数モデル(TVP回帰など)では、係数 $\beta_t$ 自体の将来予測は可能です。
ただし、その意味や限界もよく理解しておく必要があります。


🔍 なぜ係数 $\beta_t$ の将来予測ができるのか?

理由:

時変係数モデルでは、係数 $\beta_t$ を**状態空間モデルの「状態変数」**としてモデリングしています。
たとえば、以下のように:

$$
\beta_{t} = \beta_{t-1} + \eta_t, \quad \eta_t \sim \mathcal{N}(0, Q)
$$

つまり、これは「係数はランダムウォークする」という仮定です。
この場合、将来の $\beta_{t+h}$ の予測は、以下のように求まります:

$$
\mathbb{E}[\beta_{t+h}] = \beta_t,\quad \text{Var}[\beta_{t+h}] = h \cdot Q
$$

つまり:

  • 期待値(予測値):現在の係数と同じ
  • 分散:予測ステップに比例して増える

📦 実装上どうするか?

たとえば、TVPRegression を使って得られた res から:

# 現在の推定係数(平滑化済み)
beta_t = res.smoothed_state[:, -1]  # 最後の状態

# 状態ノイズの共分散行列(推定済み)
Q = res.filter_results.state_cov[:, :, -1]  # 最終時点の state covariance

# hステップ先の予測分散
h = 5
cov_beta_t_plus_h = h * Q

# beta_t は予測の期待値
# cov_beta_t_plus_h が予測の不確かさ

📈 可視化するなら?

将来の係数の予測平均と信頼区間をプロットできます:

import matplotlib.pyplot as plt

# 単一の係数(例:beta1)について
mu = beta_t[0]
std = np.sqrt(cov_beta_t_plus_h[0, 0])

future_steps = np.arange(1, h+1)
mu_line = np.full(h, mu)
ci_upper = mu + 1.96 * std * np.sqrt(future_steps)
ci_lower = mu - 1.96 * std * np.sqrt(future_steps)

plt.fill_between(future_steps, ci_lower, ci_upper, alpha=0.3, label='95% CI')
plt.plot(future_steps, mu_line, label='E[beta1]', color='blue')
plt.xlabel('Steps ahead (h)')
plt.ylabel('Predicted beta1')
plt.title('Forecast of time-varying coefficient beta1')
plt.legend()
plt.grid(True)
plt.show()

⚠ 注意点:過信は禁物

1. 係数の予測精度は不確かさが大きい

  • 特に h が大きくなるほど、分散(不確かさ)は線形に増加

2. 係数はトレンドではなく「確率的に変動するもの」として扱っている

  • TVPモデルは「将来のトレンドを学習する」わけではなく、「今の係数がそのまま続く」と仮定している(無記憶)

3. 構造的な変化(政策変更・外部ショックなど)は予測できない

  • モデル自体がそれを学習する構造になっていない場合

✅ 他の選択肢

モデル 特徴
TVP回帰 係数はランダムウォーク → 予測可能だが拡散する
ベイズTVP 係数に動的階層事前分布を置ける(柔軟性↑)
Gaussian Process 回帰 係数の変化パターンをより滑らかに予測可能
Neural ODE / SSM 非線形な係数変動を捉える拡張モデルも(やや上級)

✅ まとめ

質問 回答
TVPモデルで係数の将来を予測できるか? ✅ 予測「できる」
その予測は正確か? ⚠ hが大きいほど不確かさが増す
どう使うべき? ✅ 信頼区間を含めて不確かさ込みで見るべき
拡張の選択肢は? ✅ ベイズTVPやGaussian Processなどあり

ご希望があれば:

  • β_t の将来予測と信頼区間を出力する関数
  • 全係数の予測(ヒートマップ風プロット)
  • PyMC/StanでのベイズTVP係数予測

などもご提供できます!お気軽にどうぞ。

user:

なるほど、TVP回帰では、係数は時変であり、過去の係数の推移は推定できるけど、未来の係数は「変化しない前提」なんですね? 他の時変係数モデルはどうなんですか?

assistant:

はい、そのご理解は TVP回帰(特にランダムウォーク仮定のもの)について非常に正確です。
ここでは、それに続くご質問に答える形で:


✅ ご確認の要点

TVP回帰では、係数 $\beta_t$ は時変であり、過去の推移は推定できるが、未来の $\beta_{t+h}$ は「変化しない(=一定)」という前提で予測される

🔍 → その通りです。
というのも、TVP回帰の多くは以下のようなランダムウォーク仮定で係数をモデル化しているからです:

$$
\beta_t = \beta_{t-1} + \eta_t,\quad \eta_t \sim \mathcal{N}(0, Q)
$$

この場合、未来の期待値は:

$$
\mathbb{E}[\beta_{t+h}] = \beta_t
$$

つまり「変わらないと仮定している」ことになります(ただし分散は増えます)。


🔍 他の時変係数モデルとの違い

時変係数を扱うモデルは多様ですが、それぞれで未来の係数に対する前提が異なります。
以下に代表例とその予測特性を整理します:


1. ✅ TVP回帰(ランダムウォーク)

特性 内容
変化モデル $\beta_t = \beta_{t-1} + \eta_t$
将来予測 平均は「変化しない」前提、分散は拡大
用途 金融・マクロ経済の構造変化検出

2. ✅ ローカル線形トレンドモデル(LLT)

$$
\beta_t = \beta_{t-1} + \delta_{t-1} + \eta_t,\quad \delta_t = \delta_{t-1} + \zeta_t
$$

特性 内容
変化モデル 係数にトレンド速度(傾き)を持たせる
将来予測 トレンドが持続すると仮定して予測
用途 経済・気候の滑らかな変化に対応可能

✅ → TVP回帰より「未来の変化」をある程度予測に織り込む


3. ✅ 時変係数VAR(TVP-VAR)

$$
y_t = B_t y_{t-1} + \epsilon_t,\quad B_t = B_{t-1} + \eta_t
$$

特性 内容
変化モデル VARモデルの係数が時間とともに変化
将来予測 現在の B_t をもとに多変量系列を将来へ展開
用途 マクロ経済ショック分析、構造変化の検出

4. ✅ ベイズ時変係数モデル(階層事前分布)

  • PyMC / Stan で実装可能
  • 係数に対して、時間に依存する事前分布を定義
  • トレンド、季節性、急変など柔軟な仮定が可能
特性 内容
変化モデル 事前分布次第で自由に設計可能
将来予測 モデル構造と尤度に基づき係数の動きを予測
用途 柔軟な時系列モデリング、因果推論にも応用可

5. ⚠ ニューラルネット系(RNN, LSTM, attention)

特性 内容
変化モデル 明示的な係数は持たないが「影響の変化」は内部に含まれる
将来予測 学習済みモデルが非線形に予測(解釈は難)
用途 複雑な長期依存・非線形動態の時系列予測

→ 時変係数モデルというより「時変的な振る舞いを許容するブラックボックス


✅ まとめ表

モデル種 係数変化の仮定 未来の係数予測の性質 備考
TVP回帰 ランダムウォーク 平均一定、分散拡大 解釈性◎、トレンドなし
ローカル線形トレンド トレンド付きRW 緩やかな変化を予測 滑らかな変化に強い
TVP-VAR VAR係数がRW 系列間の係数も動的 経済系で人気
ベイズTVP 任意の事前 柔軟に変化予測 精度と解釈性の両立可
RNN/LSTM 暗黙的変化 非線形予測(ブラックボックス) 係数解釈は困難

🔚 結論:何を使うべきか?

目的 向いているモデル
過去の係数の変動を知りたい ✅ TVP回帰、ベイズTVP
未来の係数のトレンドを予測したい ✅ ローカル線形モデル、ベイズTVP
将来の Y を精度よく予測したい ✅ LSTM/Prophet/SARIMAX + exog
構造変化点の検出 ✅ TVP-VAR、状態空間モデル

ご希望に応じて:

  • ローカル線形トレンドモデルの Python 実装
  • PyMC によるベイズ時変係数モデルの例
  • TVP回帰 vs ローカル線形 vs LSTM の係数比較デモ

なども提供できます。興味のある方向をぜひ教えてください!

user:

What-If分析をするならどのモデルが良いですか?

assistant:

とても重要で実践的な質問です。
**What-If分析(もし〇〇が変わったら、Yはどう変わるか)**を行うには、モデルの選び方が決定的に重要です。


✅ 結論(先に要約)

分析の目的 適したモデル
明示的な因果効果(変数の影響)を知りたい TVP回帰, 固定係数回帰, 構造方程式モデル (SEM), 因果推論モデル
変化の効果を未来に反映して予測したい Prophet + exog, SARIMAX, ベイズ回帰
複数シナリオで比較したい(介入の影響含む) ベイズTVP, 構造モデル (DAG), G-computation

🔍 What-If分析に必要な要素とは?

What-If 分析は、次の形式で行われます:

「もし変数 $X_k$ を $+p%$ 増やしたら、目的変数 $Y$ はどうなるか?」

これを実行するには、次の条件を満たすモデルが必要です:

必要要素 内容
変数間の構造(係数)が明示されていること ブラックボックスでは影響度が不明
Xを手動で変更できること exog を変更して再予測できる
YがXの変化に応じて再計算されること 間接効果含むなら DAG が必要

✅ モデル別評価(What-If適性)

モデル 評価 備考
✅ TVP回帰 各説明変数の時点ごとの効果が可視化される。過去の時点での What-If も可能
✅ 固定係数回帰(OLSなど) 係数が固定だが、解釈性は明快(平均的効果)
✅ ベイズTVP 係数の不確実性も考慮した What-If ができる(尤度ベースで頑健)
✅ SARIMAX (外生変数あり) 将来の説明変数を仮定すれば What-If 予測可能
✅ Prophet + add_regressor What-If可能だが係数の不確かさが見えにくい。回帰効果が固定
❌ LSTM / RNN / Transformer × ブラックボックス。説明変数の「なぜ」や「どの程度」への答えが難しい
✅ SEM(構造方程式モデル) 直接効果/間接効果の What-If が可能。構造を設計する必要あり
✅ 因果推論(Do演算, G-computation) 統計的 What-If だけでなく因果的 What-If ができる

💡 TVP回帰での What-If 分析の例

たとえば、

sensitivity_analysis_tvp(res, coeffs_df, x_current, exog_cols, 'Y', 'X2', percent=0.10)

とすれば、**「X2 を ±10% 変えたら Y は何%変わるか」**が出力されます。

✅ 特徴:

  • 時点ごとに感応度が違う
  • 係数の推移(β_t)の観察も可能
  • 現在値だけでなく 任意の時点 でもシナリオを立てられる

🧪 より高度な What-If をしたい場合

方法 内容
G-computation 条件付き期待値を使って反事実を推定(`E[Y do(X = x')]`)
因果DAG + do演算 変数間の因果構造を設計して What-If を評価(DoWhy, CausalImpactなど)
ベイズモデル モデルの全不確実性を考慮した確率的 What-If(後悔最小化など)

✅ まとめ:モデル選びの指針

目的 モデル
各変数の影響を明示的に評価 ✅ TVP回帰 / 固定回帰
将来の変化を前提にした予測 ✅ SARIMAX / Prophet
因果効果を評価したい ✅ SEM / DAG / do演算系
不確実性込みで評価 ✅ ベイズ回帰 / ベイズTVP

🎯 ご提案

ご希望があれば以下もすぐご用意できます:

  • TVP回帰で複数説明変数に対する What-If 感応度マトリクスを出力するコード
  • SEM / G-computation / DoWhy を使った因果的 What-If 分析のテンプレ
  • Prophet での add_regressor を使ったシナリオベース予測

お気軽に「このパターンでやってみたい」とお知らせください!

user:

うーん、難しいですね。とりあえず今日もありがとうございました。ここまでの議論をブログにまとめたいので、タイトル案をいくつか考えていただけますか?

assistant:

こちらこそ、深くて実践的な議論をありがとうございました!
以下に、今日の内容(TVP回帰・時変係数の未来予測・What-If分析・他モデルとの比較)を反映したブログタイトル案をいくつかご提案します:


🎯 シンプル&検索性重視

  1. 「時変係数モデルとは?TVP回帰の予測力とWhat-If分析を解説」
  2. 「TVP回帰で未来は読めるか?時変係数の予測と限界」
  3. 「TVP回帰 vs Prophet:時系列モデルで何ができるのか?」

🧠 理解深化・専門性重視

  1. 「係数は変わる、でも未来は読めない?TVP回帰の本質に迫る」
  2. 「時変係数の将来予測は可能か?ランダムウォークとモデル比較」
  3. 「What-If分析に最適な時系列モデルはどれか?TVP回帰・Prophet・因果モデルを比較」

📊 実務寄り・応用シナリオ重視

  1. 「マーケ施策の効果は時間とともに変わる?TVP回帰で動的感応度を可視化する」
  2. 「将来のシナリオを予測するには?TVP回帰と他モデルの使い分け」
  3. 「説明変数を10%動かしたらYはどうなる?TVP回帰で実現するWhat-If分析」

✨ インパクト重視(ややキャッチー)

  1. 「未来の係数は誰にもわからない──それでもTVP回帰を使う理由」
  2. 「因果?予測?その間にあるもの──TVP回帰で見える変化のダイナミズム」

ご希望に応じて、

  • タイトルに合わせた導入文(リード)
  • ブログ記事の構成案(見出し・セクション分け)
    などもご提案できます。お気軽にお声かけください!

user:

「時変係数モデルとは?TVP回帰の予測力とWhat-If分析を解説」で行きたいと思います。最後に、ここまでの議論の詳しいまとめを書いて終わりにしてください。

assistant:

承知しました!
それでは、ブログタイトル

📝「時変係数モデルとは?TVP回帰の予測力とWhat-If分析を解説」

にふさわしい詳しいまとめを以下にご用意しました。


✅ 1. 時変係数モデル(TVP回帰)とは?

TVP回帰(Time-Varying Parameter Regression)は、従来の回帰モデルと異なり、説明変数の影響(係数)が時間とともに変化することを許容するモデルです。

  • 通常の回帰: $y_t = \mathbf{x}_t^\top \beta + \epsilon_t$
  • TVP回帰: $y_t = \mathbf{x}t^\top \beta_t + \epsilon_t$、かつ $\beta_t = \beta{t-1} + \eta_t$

このように、係数 $\beta_t$ を状態空間モデルの「状態」としてモデル化することで、構造変化や介入、季節性などによる説明変数の影響の変化を動的に捉えることができます。


✅ 2. モデル推定の仕組みと役割

TVP回帰では、Kalmanフィルタ+最大尤度法を使って、以下を同時に推定します:

  • 観測ノイズの分散(誤差)
  • 状態ノイズ(係数変動)の分散
  • 時点ごとの係数(平滑化された $\beta_t$)

この構造により、モデルは時点ごとの説明変数の影響力を可視化する機能を持ちます。


✅ 3. 将来予測はできるのか?

TVP回帰での将来予測は、以下の2段階になります:

  1. 目的変数 $y_{t+h}$ の予測
    これは可能ですが、未来の説明変数 $\mathbf{x}_{t+h}$ を仮定する必要があります。

  2. 係数 $\beta_{t+h}$ の予測
    係数は通常ランダムウォークでモデル化されているため、

    • 期待値: $\mathbb{E}[\beta_{t+h}] = \beta_t$(=「変わらない」)
    • 分散: $\propto h$(ステップ数に比例して不確かさが増す)

つまり、「変化しない前提で予測するが、将来は不確実性が高まる」という設計です。


✅ 4. ProphetやSARIMAXとの違い

モデル 説明変数の影響は? 将来予測は? 係数の解釈性
TVP回帰 時変(明示的) ◯(仮定次第) ◎(時点ごとに解釈可)
Prophet 固定(add_regressor ◎(自動で先を予測) △(効果は見えるが係数の動きは不明)
SARIMAX 固定
ニューラル系 暗黙的に時変 ×(ブラックボックス)

TVP回帰は、「予測力」という意味では Prophet や SARIMAX より劣る場合もありますが、変数の影響の変化を時系列で丁寧に可視化できることが最大の強みです。


✅ 5. What-If分析はできるか?

はい、TVP回帰はWhat-If分析に非常に適しています
特に以下の点が優れています:

  • 任意の時点での係数(感応度)を取得できる
  • 説明変数を「p%変化させた場合」の $y_t$ の変化を定量的に予測可能
  • 未来のシナリオにも仮定付きで対応可能

一方で、「未来の係数がどう変化するか」を高精度で予測するには、ベイズTVPやローカル線形トレンドモデルなど、より構造的なモデル拡張が必要になります。


✅ 6. まとめ:TVP回帰の使いどころ

適している場面 説明
経済や政策データで「影響の変化」を分析したいとき 時系列に応じた係数の変化を可視化できる
施策や外部変数の効果が「いつ強まったか・弱まったか」を把握したいとき What-If分析が直感的にできる
モデルの透明性・解釈性が重要な場面 係数の履歴を追跡可能

🎯 今後に向けて

  • より高精度な未来予測を求めるなら:ProphetやSARIMAXとのハイブリッド
  • 不確実性を加味した意思決定なら:ベイズTVPや因果モデル
  • 多変数間の動的構造を知りたいなら:TVP-VARや構造方程式モデル(SEM)

TVP回帰は、「変わる世界の中で、何がどのように変わったのか」を問い直すための強力なレンズになります。


ご希望があれば、このまとめをそのままMarkdown形式でもご提供します。
また次回もどうぞよろしくお願いします!

user:

ありがとうございました!

assistant:

こちらこそ、ありがとうございました!
とても深く本質的なやり取りで、私も楽しくサポートさせていただきました。

ブログ執筆、What-If分析、ベイズ時変モデルなど、今後のテーマについてもぜひまたご相談ください📊✍️
いつでもお待ちしております!

お疲れさまでした 😊

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?