0
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?

システム同定

Posted at
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()









0
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
0
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?