システム同定


```
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.optimize import minimize

# 1. ランダムバイナリー入力信号（PRBS）の生成
def generate_prbs(length, rate):
    """擬似ランダムバイナリシーケンスを生成する関数"""
    prbs = np.random.choice([1, -1], size=length)
    prbs = np.repeat(prbs, rate)  # サンプルを繰り返して出力を増やす（サンプリング周波数を上げる）
    return prbs

# 2. サンプルデータの作成
fs = 100  # サンプリング周波数
duration = 10  # シミュレーション時間 (秒)
time = np.arange(0, duration, 1/fs)  # 時間ベクトル

# ランダムバイナリー入力信号を生成（長さを時間に合わせて設定）
prbs_signal = generate_prbs(length=int(duration/0.1), rate=int(fs*0.1))

# 3. 実際のシステムの伝達関数を設定し、応答を生成
# 例: システムの伝達関数 G(s) = 1 / (s^2 + s + 1)
numerator = [1]
denominator = [1, 1, 1]
system = signal.TransferFunction(numerator, denominator)

# 入力信号に対するシステム応答を計算
_, output_signal, _ = signal.lsim(system, prbs_signal, time)

# 4. システム同定用の伝達関数モデルを定義
def transfer_function_model(params, u, t):
    """伝達関数モデルの応答を計算する関数"""
    # パラメータを伝達関数の係数として使用
    num = [params[0]]  # 分子の係数
    den = [1, params[1], params[2]]  # 分母の係数
    # 伝達関数モデルを生成
    system = signal.TransferFunction(num, den)
    _, y_model, _ = signal.lsim(system, u, t)
    return y_model

# 5. 目的関数（最小化したい誤差関数）を定義
def objective_function(params, u, y, t):
    """目的関数: 実データとモデル応答の二乗誤差を最小化"""
    y_model = transfer_function_model(params, u, t)
    error = np.sum((y - y_model) ** 2)
    return error

# 6. 最適化によるパラメータ推定
initial_guess = [1, 1, 1]  # 初期パラメータ（分子、分母係数）
result = minimize(objective_function, initial_guess, args=(prbs_signal, output_signal, time), method='BFGS')
estimated_params = result.x
print(f"推定された伝達関数の係数: 分子 {estimated_params[0]}, 分母 [1, {estimated_params[1]}, {estimated_params[2]}]")

# 7. 推定された伝達関数を用いて応答をシミュレーション
estimated_system = signal.TransferFunction([estimated_params[0]], [1, estimated_params[1], estimated_params[2]])
_, estimated_output_signal, _ = signal.lsim(estimated_system, prbs_signal, time)

# 8. 結果のプロット
plt.figure(figsize=(12, 6))

# 入力信号のプロット
plt.subplot(3, 1, 1)
plt.plot(time, prbs_signal, label='PRBS Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('PRBS Input Signal')
plt.grid(True)
plt.legend()

# 出力信号（実システム応答）のプロット
plt.subplot(3, 1, 2)
plt.plot(time, output_signal, label='Original System Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Original System Output')
plt.grid(True)
plt.legend()

# 推定されたモデルの出力をプロット
plt.subplot(3, 1, 3)
plt.plot(time, output_signal, label='Original System Output')
plt.plot(time, estimated_output_signal, '--', label='Estimated Model Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('System Identification: Original vs Estimated Model Output')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()
```

```
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from scipy.optimize import minimize

# 1. ホワイトノイズ入力信号の生成
def generate_white_noise(length, amplitude=1.0):
    """ホワイトノイズを生成する関数"""
    return amplitude * np.random.normal(size=length)

# 2. サンプルデータの作成
fs = 100  # サンプリング周波数 (Hz)
duration = 10  # シミュレーション時間 (秒)
time = np.arange(0, duration, 1/fs)  # 時間ベクトル

# ホワイトノイズ入力信号を生成
white_noise_signal = generate_white_noise(length=len(time), amplitude=1.0)

# 3. 実際のシステムの伝達関数を設定し、応答を生成
# 例: システムの伝達関数 G(s) = 1 / (s^2 + s + 1)
numerator = [1]
denominator = [1, 1, 1]
system = signal.TransferFunction(numerator, denominator)

# 入力信号に対するシステム応答を計算
_, output_signal, _ = signal.lsim(system, white_noise_signal, time)

# 4. システム同定用の伝達関数モデルを定義
def transfer_function_model(params, u, t):
    """伝達関数モデルの応答を計算する関数"""
    # パラメータを伝達関数の係数として使用
    num = [params[0]]  # 分子の係数
    den = [1, params[1], params[2]]  # 分母の係数
    # 伝達関数モデルを生成
    system = signal.TransferFunction(num, den)
    _, y_model, _ = signal.lsim(system, u, t)
    return y_model

# 5. 目的関数（最小化したい誤差関数）を定義
def objective_function(params, u, y, t):
    """目的関数: 実データとモデル応答の二乗誤差を最小化"""
    y_model = transfer_function_model(params, u, t)
    error = np.sum((y - y_model) ** 2)
    return error

# 6. 最適化によるパラメータ推定
initial_guess = [1, 1, 1]  # 初期パラメータ（分子、分母係数）
result = minimize(objective_function, initial_guess, args=(white_noise_signal, output_signal, time), method='BFGS')
estimated_params = result.x
print(f"推定された伝達関数の係数: 分子 {estimated_params[0]}, 分母 [1, {estimated_params[1]}, {estimated_params[2]}]")

# 7. 推定された伝達関数を用いて応答をシミュレーション
estimated_system = signal.TransferFunction([estimated_params[0]], [1, estimated_params[1], estimated_params[2]])
_, estimated_output_signal, _ = signal.lsim(estimated_system, white_noise_signal, time)

# 8. 結果のプロット
plt.figure(figsize=(12, 8))

# 入力信号のプロット
plt.subplot(3, 1, 1)
plt.plot(time, white_noise_signal, label='White Noise Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('White Noise Input Signal')
plt.grid(True)
plt.legend()

# 出力信号（実システム応答）のプロット
plt.subplot(3, 1, 2)
plt.plot(time, output_signal, label='Original System Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Original System Output')
plt.grid(True)
plt.legend()

# 推定されたモデルの出力をプロット
plt.subplot(3, 1, 3)
plt.plot(time, output_signal, label='Original System Output')
plt.plot(time, estimated_output_signal, '--', label='Estimated Model Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('System Identification: Original vs Estimated Model Output')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()

```


```
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal as scipy_signal  # scipy.signal を明示的に別名でインポート
from scipy.optimize import minimize

# 1. ホワイトノイズ入力信号の生成
def generate_white_noise(length, amplitude=1.0):
    """ホワイトノイズを生成する関数"""
    return amplitude * np.random.normal(size=length)

# 2. データの前処理関数の定義
def preprocess_data(data_signal, fs, cutoff_freq=10, filter_order=4):
    """データの前処理を行う関数（正規化、フィルタリング、平均値の除去）"""
    # ローパスフィルタの設計
    nyquist_freq = fs / 2.0
    normal_cutoff = cutoff_freq / nyquist_freq
    b, a = scipy_signal.butter(filter_order, normal_cutoff, btype='low', analog=False)

    # フィルタリングを行う
    filtered_signal = scipy_signal.filtfilt(b, a, data_signal)

    # 平均値を除去してドリフトを除去
    detrended_signal = filtered_signal - np.mean(filtered_signal)

    # 正規化（0-1範囲）
    normalized_signal = (detrended_signal - np.min(detrended_signal)) / (np.max(detrended_signal) - np.min(detrended_signal))

    return normalized_signal

# 3. サンプルデータの作成
fs = 100  # サンプリング周波数 (Hz)
duration = 10  # シミュレーション時間 (秒)
time = np.arange(0, duration, 1/fs)  # 時間ベクトル

# ホワイトノイズ入力信号を生成
white_noise_signal = generate_white_noise(length=len(time), amplitude=1.0)

# 4. 実際のシステムの伝達関数を設定し、応答を生成
# 例: システムの伝達関数 G(s) = 1 / (s^2 + s + 1)
numerator = [1]
denominator = [1, 1, 1]
system = scipy_signal.TransferFunction(numerator, denominator)

# 入力信号に対するシステム応答を計算
_, output_signal, _ = scipy_signal.lsim(system, white_noise_signal, time)

# 5. データの前処理
preprocessed_input_signal = preprocess_data(white_noise_signal, fs)
preprocessed_output_signal = preprocess_data(output_signal, fs)

# 6. システム同定用の伝達関数モデルを定義
def transfer_function_model(params, u, t):
    """伝達関数モデルの応答を計算する関数"""
    # パラメータを伝達関数の係数として使用
    num = [params[0]]  # 分子の係数
    den = [1, params[1], params[2]]  # 分母の係数
    # 伝達関数モデルを生成
    system = scipy_signal.TransferFunction(num, den)
    _, y_model, _ = scipy_signal.lsim(system, u, t)
    return y_model

# 7. 目的関数（最小化したい誤差関数）を定義
def objective_function(params, u, y, t):
    """目的関数: 実データとモデル応答の二乗誤差を最小化"""
    y_model = transfer_function_model(params, u, t)
    error = np.sum((y - y_model) ** 2)
    return error

# 8. 最適化によるパラメータ推定
initial_guess = [1, 1, 1]  # 初期パラメータ（分子、分母係数）
result = minimize(objective_function, initial_guess, args=(preprocessed_input_signal, preprocessed_output_signal, time), method='BFGS')
estimated_params = result.x
print(f"推定された伝達関数の係数: 分子 {estimated_params[0]}, 分母 [1, {estimated_params[1]}, {estimated_params[2]}]")

# 9. 推定された伝達関数を用いて応答をシミュレーション
estimated_system = scipy_signal.TransferFunction([estimated_params[0]], [1, estimated_params[1], estimated_params[2]])
_, estimated_output_signal, _ = scipy_signal.lsim(estimated_system, preprocessed_input_signal, time)

# 10. 結果のプロット
plt.figure(figsize=(12, 12))

# 元の入力信号のプロット
plt.subplot(4, 1, 1)
plt.plot(time, white_noise_signal, label='Original White Noise Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Original White Noise Input Signal')
plt.grid(True)
plt.legend()

# 前処理後の入力信号のプロット
plt.subplot(4, 1, 2)
plt.plot(time, preprocessed_input_signal, label='Preprocessed Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Preprocessed Input Signal')
plt.grid(True)
plt.legend()

# 出力信号（実システム応答）のプロット
plt.subplot(4, 1, 3)
plt.plot(time, preprocessed_output_signal, label='Preprocessed Original System Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Preprocessed Original System Output')
plt.grid(True)
plt.legend()

# 推定されたモデルの出力をプロット
plt.subplot(4, 1, 4)
plt.plot(time, preprocessed_output_signal, label='Preprocessed Original System Output')
plt.plot(time, estimated_output_signal, '--', label='Estimated Model Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('System Identification: Preprocessed Original vs Estimated Model Output')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()

```


```
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal as scipy_signal  # scipy.signal を明示的に別名でインポート
from scipy.optimize import minimize

# 1. ホワイトノイズ入力信号の生成
def generate_white_noise(length, amplitude=1.0):
    """ホワイトノイズを生成する関数"""
    return amplitude * np.random.normal(size=length)

# 2. データの前処理関数の定義
def preprocess_data(data_signal, fs, cutoff_freq=10, filter_order=4):
    """データの前処理を行う関数（正規化、フィルタリング、平均値の除去）"""
    # ローパスフィルタの設計
    nyquist_freq = fs / 2.0
    normal_cutoff = cutoff_freq / nyquist_freq
    b, a = scipy_signal.butter(filter_order, normal_cutoff, btype='low', analog=False)

    # フィルタリングを行う
    filtered_signal = scipy_signal.filtfilt(b, a, data_signal)

    # 平均値を除去してドリフトを除去
    detrended_signal = filtered_signal - np.mean(filtered_signal)

    # 正規化（0-1範囲）
    normalized_signal = (detrended_signal - np.min(detrended_signal)) / (np.max(detrended_signal) - np.min(detrended_signal))

    return normalized_signal

# 3. サンプルデータの作成
fs = 100  # サンプリング周波数 (Hz)
duration = 10  # シミュレーション時間 (秒)
time = np.arange(0, duration, 1/fs)  # 時間ベクトル

# ホワイトノイズ入力信号を生成
white_noise_signal = generate_white_noise(length=len(time), amplitude=1.0)

# 4. 実際のシステムの伝達関数を設定し、応答を生成
# 例: システムの伝達関数 G(s) = 1 / (s^2 + s + 1)
numerator = [1]
denominator = [1, 1, 1]
system = scipy_signal.TransferFunction(numerator, denominator)

# 入力信号に対するシステム応答を計算
_, output_signal, _ = scipy_signal.lsim(system, white_noise_signal, time)

# 5. データの前処理
preprocessed_input_signal = preprocess_data(white_noise_signal, fs)
preprocessed_output_signal = preprocess_data(output_signal, fs)

# 6. システム同定用の伝達関数モデルを定義
def transfer_function_model(params, u, t):
    """伝達関数モデルの応答を計算する関数"""
    # パラメータを伝達関数の係数として使用
    num = [params[0]]  # 分子の係数
    den = [1, params[1], params[2]]  # 分母の係数
    # 伝達関数モデルを生成
    system = scipy_signal.TransferFunction(num, den)
    _, y_model, _ = scipy_signal.lsim(system, u, t)
    return y_model

# 7. 目的関数（最小化したい誤差関数）を定義
def objective_function(params, u, y, t):
    """目的関数: 実データとモデル応答の二乗誤差を最小化"""
    y_model = transfer_function_model(params, u, t)
    error = np.sum((y - y_model) ** 2)
    return error

# 8. 最適化によるパラメータ推定
initial_guess = [1, 1, 1]  # 初期パラメータ（分子、分母係数）
result = minimize(objective_function, initial_guess, args=(preprocessed_input_signal, preprocessed_output_signal, time), method='BFGS')
estimated_params = result.x
print(f"推定された伝達関数の係数: 分子 {estimated_params[0]}, 分母 [1, {estimated_params[1]}, {estimated_params[2]}]")

# 9. 推定された伝達関数を用いて応答をシミュレーション
estimated_system = scipy_signal.TransferFunction([estimated_params[0]], [1, estimated_params[1], estimated_params[2]])
_, estimated_output_signal, _ = scipy_signal.lsim(estimated_system, preprocessed_input_signal, time)

# 10. 結果のプロット
plt.figure(figsize=(12, 12))

# 元の入力信号のプロット
plt.subplot(4, 1, 1)
plt.plot(time, white_noise_signal, label='Original White Noise Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Original White Noise Input Signal')
plt.grid(True)
plt.legend()

# 前処理後の入力信号のプロット
plt.subplot(4, 1, 2)
plt.plot(time, preprocessed_input_signal, label='Preprocessed Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Preprocessed Input Signal')
plt.grid(True)
plt.legend()

# 出力信号（実システム応答）のプロット
plt.subplot(4, 1, 3)
plt.plot(time, preprocessed_output_signal, label='Preprocessed Original System Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Preprocessed Original System Output')
plt.grid(True)
plt.legend()

# 推定されたモデルの出力をプロット
plt.subplot(4, 1, 4)
plt.plot(time, preprocessed_output_signal, label='Preprocessed Original System Output')
plt.plot(time, estimated_output_signal, '--', label='Estimated Model Output')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('System Identification: Preprocessed Original vs Estimated Model Output')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()
```

```
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from statsmodels.tsa.ar_model import AutoReg
from scipy.optimize import minimize

# 1. サンプルデータの生成
np.random.seed(0)  # 再現性のための乱数シード設定
fs = 100  # サンプリング周波数 (Hz)
duration = 10  # シミュレーション時間 (秒)
time = np.arange(0, duration, 1/fs)  # 時間ベクトル

# 入力信号（サイン波+ホワイトノイズ）
input_signal = 0.5 * np.sin(2 * np.pi * 1 * time) + 0.1 * np.random.normal(size=len(time))

# 実システムの伝達関数 G(s) = 1 / (s^2 + s + 1)
numerator = [1]
denominator = [1, 1, 1]
system = signal.TransferFunction(numerator, denominator)

# 入力信号に対するシステムの応答を計算
_, output_signal, _ = signal.lsim(system, input_signal, time)

# 出力信号にノイズを追加
output_signal += 0.05 * np.random.normal(size=len(time))

# 2. データの前処理（正規化）
def normalize(signal):
    return (signal - np.min(signal)) / (np.max(signal) - np.min(signal))

input_signal = normalize(input_signal)
output_signal = normalize(output_signal)

# 3. ARXモデルの定義とパラメータ推定
# ARXモデルの次数（ラグ項数）
na = 2  # 出力側のラグ
nb = 2  # 入力側のラグ
nk = 1  # 入力と出力の遅れ

# 入力と出力のラグ行列を作成
def create_lag_matrix(data, lag):
    """時系列データに基づくラグ行列を作成"""
    N = len(data)
    lag_matrix = np.zeros((N - lag, lag))
    for i in range(lag):
        lag_matrix[:, i] = data[lag - i - 1:N - i - 1]
    return lag_matrix

# ラグ行列の作成
y_lag_matrix = create_lag_matrix(output_signal, na)
u_lag_matrix = create_lag_matrix(input_signal, nb)

# データをそろえる（出力と入力の行数を合わせる）
lagged_output = output_signal[na:]
lagged_input = input_signal[na:]

# 回帰行列を作成（出力ラグ + 入力ラグ）
regression_matrix = np.hstack([y_lag_matrix, u_lag_matrix])

# 回帰係数の推定（最小二乗法）
theta = np.linalg.lstsq(regression_matrix, lagged_output, rcond=None)[0]

# 4. モデルの応答をシミュレーション
# 推定された係数を用いてモデル応答を計算
def simulate_arx_model(theta, u, na, nb, nk):
    """ARXモデルの係数を用いてシステム応答をシミュレーション"""
    N = len(u)
    y_model = np.zeros(N)
    for t in range(max(na, nb + nk), N):
        y_sum = 0
        # 出力側のラグの係数を計算
        for i in range(na):
            y_sum += -theta[i] * y_model[t - i - 1]

        # 入力側のラグの係数を計算
        for j in range(nb):
            y_sum += theta[na + j] * u[t - nk - j - 1]

        # モデルの出力を計算
        y_model[t] = y_sum
    return y_model

# ARXモデルの応答をシミュレーション
estimated_output = simulate_arx_model(theta, input_signal, na, nb, nk)

# 5. 結果のプロット
plt.figure(figsize=(12, 8))

# 入力信号のプロット
plt.subplot(3, 1, 1)
plt.plot(time, input_signal, label='Input Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Input Signal')
plt.grid(True)
plt.legend()

# 出力信号のプロット
plt.subplot(3, 1, 2)
plt.plot(time, output_signal, label='Original Output Signal')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Original Output Signal')
plt.grid(True)
plt.legend()

# モデル応答のプロット
plt.subplot(3, 1, 3)
plt.plot(time, output_signal, label='Original Output Signal')
plt.plot(time, estimated_output, '--', label='Estimated Output (ARX Model)')
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('System Identification: Original vs Estimated Output')
plt.grid(True)
plt.legend()

plt.tight_layout()
plt.show()

```


```
import numpy as np
import statsmodels.api as sm

# サンプルデータの生成
np.random.seed(0)
n = 100
X = np.random.normal(size=(n, 1))  # 外部入力
e = np.random.normal(size=n)  # ノイズ
y = 2 * X.squeeze() + 0.5 * np.roll(X.squeeze(), 1) + e  # ARXモデル生成

# データの準備
X_lagged = sm.add_constant(np.column_stack([X, np.roll(X, 1)]))  # 定数項と1ラグの追加
X_lagged = X_lagged[1:]  # ラグの影響を考慮して最初のデータを削除
y = y[1:]

# ARXモデルのフィッティング
model_arx = sm.OLS(y, X_lagged).fit()
print(model_arx.summary())

```


```
import statsmodels.api as sm
from statsmodels.tsa.arima.model import ARIMA

# サンプルデータの生成
np.random.seed(0)
n = 100
X = np.random.normal(size=(n, 1))
e = np.random.normal(size=n)
y = 2 * X.squeeze() + 0.5 * np.roll(X.squeeze(), 1) + 0.3 * np.roll(e, 1) + e

# ARMAXモデルのフィッティング（ARIMAの拡張）
model_armax = ARIMA(endog=y, exog=X, order=(1, 0, 1)).fit()
print(model_armax.summary())

```

```

import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX

# サンプルデータの生成
np.random.seed(0)
n = 100
X = np.random.normal(size=(n, 1))
y = 2 * X.squeeze() + 0.5 * np.roll(X.squeeze(), 1) + np.random.normal(size=n)

# 状態空間モデルの定義とフィッティング
model_ssm = SARIMAX(endog=y, exog=X, order=(1, 0, 1), trend='c').fit()
print(model_ssm.summary())

# 結果のプロット
model_ssm.plot_diagnostics(figsize=(10, 8))
plt.show()
```


```
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt

# サンプルデータの生成
np.random.seed(0)
n = 100
y = np.cumsum(np.random.normal(size=n))  # ARIMAプロセスの生成

# ボックス・ジェンキンス（ARIMA）モデルのフィッティング
model_bj = sm.tsa.ARIMA(y, order=(1, 1, 1)).fit()
print(model_bj.summary())

# プロット
model_bj.plot_diagnostics(figsize=(10, 8))
plt.show()

```


```
import numpy as np
import matplotlib.pyplot as plt

# データ生成（例: 入力 x とそれに対応する出力 y）
np.random.seed(0)  # 再現性のためのシード
x = np.linspace(0, 10, 20)  # 入力データ (0~10 の等間隔データ)
true_a, true_b = 2, 1  # 実際のパラメータ
y = true_a * x + true_b + np.random.normal(0, 1, len(x))  # 出力データ（ノイズを含む）

# 最小二乗法によるパラメータ推定
X = np.vstack([x, np.ones(len(x))]).T  # 入力データの行列 [x, 1]
a, b = np.linalg.lstsq(X, y, rcond=None)[0]  # 最小二乗法によるパラメータ推定

# 結果表示
print(f"推定されたパラメータ: a = {a:.2f}, b = {b:.2f}")
plt.scatter(x, y, label='Data (with noise)')  # 元データのプロット
plt.plot(x, a * x + b, color='red', label='Fitted Line')  # 推定されたモデルのプロット
plt.xlabel('Input x')
plt.ylabel('Output y')
plt.legend()
plt.title('Least Squares Method for System Identification')
plt.show()

```

```
import numpy as np
from scipy.linalg import hankel
from numpy.linalg import lstsq
import matplotlib.pyplot as plt

# サンプルデータの生成 (ARXモデル)
np.random.seed(0)
n = 100  # データ数
u = np.sin(np.linspace(0, 10, n)) + np.random.normal(0, 0.1, n)  # 外部入力 u(t)
y = np.zeros(n)
a1, a2 = -0.5, 0.25  # 出力の自己回帰係数
b1, b2 = 0.4, 0.2    # 外部入力の係数

# ARXモデルの生成
for t in range(2, n):
    y[t] = a1 * y[t-1] + a2 * y[t-2] + b1 * u[t-1] + b2 * u[t-2] + np.random.normal(0, 0.1)

# 同定用データ行列の構築
phi = np.column_stack([-y[1:n-1], -y[0:n-2], u[1:n-1], u[0:n-2]])
y_train = y[2:]

# 最小二乗法による係数推定
theta = lstsq(phi, y_train, rcond=None)[0]
print(f"推定された係数: {theta}")

# 結果のプロット
y_est = phi @ theta  # 推定出力
plt.plot(y_train, label='True Output')
plt.plot(y_est, '--', label='Estimated Output')
plt.legend()
plt.title('ARX Model Identification')
plt.show()

```


```
import statsmodels.api as sm

# サンプルデータ生成
np.random.seed(0)
n = 150
u = np.random.normal(0, 1, n)  # 外部入力
e = np.random.normal(0, 0.1, n)  # ノイズ
y = np.zeros(n)
a1, a2 = -0.5, 0.3
b1, b2 = 0.4, 0.2
c1 = 0.5  # 移動平均項

# ARMAXモデルの生成
for t in range(2, n):
    y[t] = a1 * y[t-1] + a2 * y[t-2] + b1 * u[t-1] + b2 * u[t-2] + c1 * e[t-1] + e[t]

# ARMAXモデルのフィッティング
model = sm.tsa.ARMA(y, order=(2, 1), exog=u)
model_fit = model.fit()
print(model_fit.summary())

# 結果プロット
plt.plot(y, label='True Output')
plt.plot(model_fit.fittedvalues, '--', label='Estimated Output')
plt.legend()
plt.title('ARMAX Model Identification')
plt.show()

```


```
from pykalman import KalmanFilter

# サンプルデータの生成
n_timesteps = 50
transition_matrix = [[1, 1], [0, 1]]  # 状態遷移行列
observation_matrix = [[1, 0]]         # 観測行列
initial_state_mean = [0, 0]           # 初期状態

# ノイズの生成
transition_covariance = np.eye(2) * 0.1  # 遷移ノイズの共分散行列
observation_covariance = np.eye(1) * 0.1  # 観測ノイズの共分散行列
initial_state_covariance = np.eye(2) * 0.1

kf = KalmanFilter(transition_matrices=transition_matrix,
                  observation_matrices=observation_matrix,
                  initial_state_mean=initial_state_mean,
                  initial_state_covariance=initial_state_covariance,
                  transition_covariance=transition_covariance,
                  observation_covariance=observation_covariance)

# 状態と観測データの生成
states, observations = kf.sample(n_timesteps)

# カルマンフィルタの適用
filtered_state_means, _ = kf.filter(observations)

# 結果表示
plt.plot(observations, 'o', label='Observations')
plt.plot(filtered_state_means[:, 0], label='Filtered State')
plt.legend()
plt.title('State-Space Model Identification using Kalman Filter')
plt.show()
```

```
import torch
import torch.nn as nn
import torch.optim as optim

# サンプルデータ生成
n = 100
x = np.linspace(-10, 10, n)
y = np.sin(x) + 0.1 * np.random.normal(size=n)

# ニューラルネットワークモデルの定義
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(1, 10)
        self.fc2 = nn.Linear(10, 1)
    
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# モデルのインスタンス化と最適化の設定
model = SimpleNN()
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# データの準備
x_tensor = torch.tensor(x, dtype=torch.float32).unsqueeze(1)
y_tensor = torch.tensor(y, dtype=torch.float32).unsqueeze(1)

# 学習プロセス
for epoch in range(1000):
    model.train()
    optimizer.zero_grad()
    output = model(x_tensor)
    loss = criterion(output, y_tensor)
    loss.backward()
    optimizer.step()

print(f"最終損失: {loss.item():.4f}")

# 結果表示
y_pred = model(x_tensor).detach().numpy()
plt.plot(x, y, 'o', label='True Output')
plt.plot(x, y_pred, '--', label='NN Estimated Output')
plt.legend()
plt.title('Neural Network Based Nonlinear Model Identification')
plt.show()
```


```

import numpy as np
import matplotlib.pyplot as plt

# シミュレーションデータを生成
np.random.seed(0)
true_params = [2, 3]  # 真のパラメータ
x = np.linspace(0, 10, 100)
y = true_params[0] * x + true_params[1] + np.random.normal(0, 1, x.shape)  # ノイズを追加

# 最小二乗法を用いてパラメータ推定
X = np.vstack([x, np.ones(len(x))]).T  # デザイン行列
estimated_params, _, _, _ = np.linalg.lstsq(X, y, rcond=None)

# 結果の表示
print(f"真のパラメータ: {true_params}")
print(f"推定されたパラメータ: {estimated_params}")

# プロット
plt.scatter(x, y, label='Noisy data')
plt.plot(x, estimated_params[0] * x + estimated_params[1], color='red', label='Fitted line')
plt.legend()
plt.show()
```


```
from scipy.optimize import minimize

# 尤度関数（ガウス分布を仮定）
def negative_log_likelihood(params, x, y):
    a, b, sigma = params
    predicted = a * x + b
    likelihood = -np.sum(-0.5 * np.log(2 * np.pi * sigma**2) - ((y - predicted)**2) / (2 * sigma**2))
    return -likelihood

# 初期パラメータの設定
initial_params = [1, 1, 1]

# 尤度関数を最小化（負の対数尤度を最小化）
result = minimize(negative_log_likelihood, initial_params, args=(x, y), method='L-BFGS-B', bounds=[(-10, 10), (-10, 10), (1e-5, 10)])
mle_params = result.x

print(f"推定されたパラメータ（MLE）: {mle_params}")

# プロット
plt.scatter(x, y, label='Noisy data')
plt.plot(x, mle_params[0] * x + mle_params[1], color='green', label='MLE Fitted line')
plt.legend()
plt.show()

```

```
from scipy.stats import norm

# 事前分布（パラメータの先験情報）
prior_mean = [0, 0]  # パラメータの平均
prior_var = [1, 1]   # パラメータの分散

# 負の対数事後確率関数
def negative_log_posterior(params, x, y):
    a, b, sigma = params
    # 負の対数尤度
    predicted = a * x + b
    likelihood = -np.sum(-0.5 * np.log(2 * np.pi * sigma**2) - ((y - predicted)**2) / (2 * sigma**2))
    # 事前分布
    prior = -0.5 * np.sum(((params[:2] - prior_mean) ** 2) / prior_var)  # a, bの事前分布
    return -(likelihood + prior)

# 初期パラメータの設定
initial_params_map = [1, 1, 1]

# 負の対数事後確率を最小化
result_map = minimize(negative_log_posterior, initial_params_map, args=(x, y), method='L-BFGS-B', bounds=[(-10, 10), (-10, 10), (1e-5, 10)])
map_params = result_map.x

print(f"推定されたパラメータ（MAP）: {map_params}")

# プロット
plt.scatter(x, y, label='Noisy data')
plt.plot(x, map_params[0] * x + map_params[1], color='blue', label='MAP Fitted line')
plt.legend()
plt.show()
```


```
import numpy as np
from scipy.signal import welch, csd

# シミュレーションのためのデータを作成（サンプル数やサンプリング周波数の設定）
fs = 100  # サンプリング周波数
N = 1024  # データポイント数
t = np.linspace(0, N/fs, N, endpoint=False)

# 入力信号としてホワイトノイズを生成
np.random.seed(0)
u = np.random.randn(len(t))

# システムの伝達関数を用いて出力信号を生成
_, y, _ = lti(numerator, denominator).output(U=u, T=t)

# 入力信号と出力信号のパワースペクトル密度を計算
f, Puu = welch(u, fs, nperseg=256)
_, Pyy = welch(y, fs, nperseg=256)

# 入力信号と出力信号の相互パワースペクトル密度を計算
_, Puy = csd(u, y, fs, nperseg=256)

# 周波数応答を求める
G_hat = Puy / Puu  # 推定された周波数応答

# プロット
plt.figure(figsize=(12, 6))

# 周波数応答の振幅（Magnitude）をプロット
plt.subplot(2, 1, 1)
plt.semilogx(f, np.abs(G_hat))
plt.title('Estimated Frequency Response')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Magnitude')
plt.grid(True)

# 周波数応答の位相（Phase）をプロット
plt.subplot(2, 1, 2)
plt.semilogx(f, np.angle(G_hat, deg=True))
plt.xlabel('Frequency [Hz]')
plt.ylabel('Phase [degrees]')
plt.grid(True)

plt.show()

```


```
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# シミュレーション用に非線形システムを定義（例: 2次の非線形システム）
def true_system(input_signal):
    """非線形システム y = 2*u + 0.5*u^2 + 0.3*u^3 の例"""
    return 2 * input_signal + 0.5 * input_signal**2 + 0.3 * input_signal**3

# 入力データの生成（ホワイトノイズを使用）
np.random.seed(0)
N = 200
u = np.random.randn(N)

# システムに入力を加えたときの出力データを生成
y = true_system(u) + 0.1 * np.random.randn(N)  # ノイズを追加

# Volterra系列モデルの設計
def create_volterra_terms(input_signal, degree=3):
    """
    Volterra系列の項を作成する関数
    - input_signal: 入力信号
    - degree: Volterraモデルの次数（1次～指定した次数までの項を作成）
    """
    N = len(input_signal)
    terms = [np.ones(N)]  # 定数項

    # 1次～指定した次数までのVolterra項を作成
    for d in range(1, degree + 1):
        terms.append(input_signal**d)
    
    # (N, d)の行列として返す
    return np.vstack(terms).T

# Volterraモデルの次数を指定
degree = 3

# Volterra系列モデルの項を作成
X = create_volterra_terms(u, degree=degree)

# 線形回帰を用いてVolterraモデルの係数を推定
model = LinearRegression()
model.fit(X, y)

# 推定されたパラメータ
estimated_coefficients = model.coef_
print(f"推定されたVolterra系列モデルの係数: {estimated_coefficients}")

# モデルによる出力を計算
y_pred = model.predict(X)

# 結果のプロット
plt.figure(figsize=(10, 6))
plt.plot(y, label='True Output', color='blue')
plt.plot(y_pred, label='Volterra Model Output', color='red', linestyle='--')
plt.xlabel('Time step')
plt.ylabel('Output')
plt.title('Volterra Series Model Output vs True Output')
plt.legend()
plt.grid()
plt.show()

```


```
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.linear_model import LinearRegression

# 1. システム同定用のサンプルデータを生成（例: 1次遅れ系のシステム）
np.random.seed(0)
N = 200  # データポイント数
u = np.random.randn(N)  # 入力信号（ホワイトノイズ）
y = np.zeros(N)  # 出力信号を初期化

# 出力信号: y(t) = 0.5 * y(t-1) + 0.3 * u(t-1) + 0.1 * u(t-2) + ノイズ
for t in range(2, N):
    y[t] = 0.5 * y[t-1] + 0.3 * u[t-1] + 0.1 * u[t-2] + 0.1 * np.random.randn()

# データフレームを作成
data = pd.DataFrame({'y': y, 'u': u})

# 2. ARXモデルの遅延データを作成する関数
def create_arx_dataframe(data, output_col, input_col, y_lags, u_lags):
    """
    ARXモデル用の遅延データフレームを作成する関数。
    - data: 入力と出力のデータを含むデータフレーム
    - output_col: 出力データのカラム名（例: 'y'）
    - input_col: 入力データのカラム名（例: 'u'）
    - y_lags: 出力の遅延次数（例: 1, 2, 3）
    - u_lags: 入力の遅延次数（例: 1, 2, 3）
    """
    df = pd.DataFrame()
    # 出力の遅延データを追加
    for i in range(1, y_lags + 1):
        df[f'{output_col}(t-{i})'] = data[output_col].shift(i)
    # 入力の遅延データを追加
    for i in range(1, u_lags + 1):
        df[f'{input_col}(t-{i})'] = data[input_col].shift(i)
    df[output_col] = data[output_col]  # 現在の出力データを追加
    return df.dropna()  # 欠損値（NaN）を削除

# 3. 遅延次数の設定
y_lags = 1  # 出力の遅延次数
u_lags = 2  # 入力の遅延次数

# ARXモデル用のデータフレームを作成
arx_data = create_arx_dataframe(data, 'y', 'u', y_lags, u_lags)

# 説明変数（X）と目的変数（y）に分離
X = arx_data.drop('y', axis=1)
y_arx = arx_data['y']

# 4. 線形回帰モデルを使用してARXモデルのパラメータを推定
model = LinearRegression()
model.fit(X, y_arx)

# 推定された係数を表示
coefficients = model.coef_
intercept = model.intercept_
print(f'推定されたARXモデルの係数: {coefficients}')
print(f'切片（定数項）: {intercept}')

# 5. 推定されたARXモデルによる予測
y_pred = model.predict(X)

# 6. 結果のプロット
plt.figure(figsize=(10, 6))
plt.plot(y_arx.values, label='True Output', color='blue')
plt.plot(y_pred, label='ARX Model Output', color='red', linestyle='--')
plt.xlabel('Time step')
plt.ylabel('Output')
plt.title('ARX Model Output vs True Output')
plt.legend()
plt.grid()
plt.show()
```


```


```


```


```


```

```


```


```


```


```