互信息法确定时间序列最佳时延

1 代码实现

最近需要实现对时间序列的相空间重构,参考ChatGPT与相关论文,实现了基于互信息法确定时间序列最佳时延的程序,代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

N_ft = 1000

def delay_time(data, max_delay=10):
    # 1. 计算自信息和联合信息
    ts = pd.Series(data)
    delays = range(1, max_delay+1)
    # ics = [ts.autocorr(d) for d in delays]   # 自信息

    ics = [ts.shift(d).autocorr() for d in delays]
    jcs = []
    for d in delays:
        jcs.append(ts.corr(ts.shift(d)))     # 联合信息

    # 2. 计算互信息
    print(ics)
    print(jcs)
    mis = []
    for jc, ic in zip(jcs, ics):
        print(jc, ic)
        mi = -0.5*np.log(1-jc**2)+0.5*np.log(1-ic**2) # 互信息
        print(mi)
        mis.append(mi)

    # 3. 找到第一个局部极小值并返回其对应的时延
    diffs = np.diff(mis)
    print(diffs)
    i = np.where(diffs > 0)[0][0]
    delay = delays[i]

    # 可视化互信息函数
    plt.plot(delays[0:], mis, 'bo-')
    plt.xlabel('Delay(τ)')
    plt.ylabel('Mutual Information(I(τ))')
    plt.grid(axis='x')
    plt.grid(axis='y')
    plt.axvline(x=delay, color='r', linestyle='--')
    plt.show()

    return delay

t = []
f1 = 25
f2 = 30
for i in range(N_ft):
    t.append(i * 0.001)
t = np.array(t)
# yu = np.ones(M * N)
AEall = np.sin(t * 2 * np.pi * f1) + np.sin(t * 2 * np.pi * f2)  #在这里直接改信号

delay = delay_time(AEall, max_delay=30)
print('Delay time:', delay)

运行结果如图所示:
延时-互信息关系曲线根据论文《混沌时间序列预测研究及应用》,寻找第一个局部极小值点确定为最佳时延,即该序列最佳时延为9.

2 相关说明

程序中相关公式为chatGPT提供,其正确性可能有待进一步确定。使用过程中若有问题,欢迎大家一起讨论!另外,在完成最佳时延的确定后,需要完成最佳嵌入维数的确定,可参考博客,这里,对其中GP算法的实现作出略微修改,代码如下:

import numpy as np
from scipy.fftpack import fft
from scipy import fftpack
import matplotlib.pyplot as plt
import pandas as pd

N_ft = 1000

# GP算法求关联维数(时频域特征)
def GP(imf, tau):
    if (len(imf) != N_ft):
        print('请输入指定的数据长度!')  # 需要更改,比如弹出对话框
        return
    elif (isinstance(imf, np.ndarray) != True):
        print('数据格式错误!')
        return
    else:
        m_max = 10  # 最大嵌入维数
        ss = 50  # r的步长
        fig = plt.figure(1)
        for m in range(1, m_max + 1):
            i_num = N_ft - (m - 1) * tau
            kj_m = np.zeros((i_num, m))  # m维重构相空间
            for i in range(i_num):
                for j in range(m):
                    kj_m[i][j] = imf[i + j * tau]
            dist_min, dist_max = np.linalg.norm(kj_m[0] - kj_m[1]), np.linalg.norm(kj_m[0] - kj_m[1])
            Dist_m = np.zeros((i_num, i_num))  # 两向量之间的距离
            for i in range(i_num):
                for k in range(i_num):
                    D = np.linalg.norm(kj_m[i] - kj_m[k])
                    if (D > dist_max):
                        dist_max = D
                    elif (D > 0 and D < dist_min):
                        dist_min = D
                    Dist_m[i][k] = D
            dr = (dist_max - dist_min) / (ss - 1)  # r的间距
            r_m = []
            Cr_m = []
            for r_index in range(ss):
                r = dist_min + r_index * dr
                r_m.append(r)
                Temp = np.heaviside(r - Dist_m, 1)
                for i in range(i_num):
                    Temp[i][i] = 0
                Cr_m.append(np.sum(Temp))
            r_m = np.log(np.array((r_m)))
            print(r_m)
            Cr_m = np.log(np.array((Cr_m)) / (i_num * (i_num - 1)))
            print(Cr_m)
            plt.plot(r_m, Cr_m, label = str(m))
        plt.xlabel('ln(r)', fontsize=18)
        plt.ylabel('ln(C)', fontsize=18)
        plt.xticks(fontsize=16)
        plt.yticks(fontsize=16)
        plt.legend(fontsize=15)
        plt.show()

if __name__=='__main__':
    # 检验关联维数程序
    t = []
    f1 = 25
    f2 = 30
    for i in range(N_ft):
        t.append(i * 0.001)
    t = np.array(t)

    # yu = np.ones(M * N)
    AEall = np.sin(t * 2 * np.pi * f1) + np.sin(t * 2 * np.pi * f2)  #在这里直接改信号
    GP(AEall, 1)

代码运行结果如下:
在这里插入图片描述同样,结合论文中对GP算法确定最佳嵌入维数的介绍,曲线中线性部分的斜率一般会随着m的增大而增大,当斜率不再增大而趋于稳定时,即为饱和关联维,此时对应的m即为最佳嵌入维。至此,完成对最佳时延与嵌入维数的确定,基于这两个参数完成对时序的相空间重构。

3 参考资料

[1] 高俊杰. 混沌时间序列预测研究及应用[D].上海交通大学,2013.
[2] Python实现相空间重构求关联维数:https://blog.csdn.net/Lwwwwwwwl/article/details/111410179.

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
计算互信息的最大时延需要使用到嵌入维数和时延两个参数,具体的计算过程可以使用以下 Matlab 代码实现: ```matlab % 假设有两个时间序列 x 和 y,长度为 n % 嵌入维数为 m,时延范围为 tau_min 到 tau_max m = 3; tau_min = 1; tau_max = 10; % 构造嵌入向量矩阵 X 和 Y X = zeros(n - (m - 1) * tau_max, m); Y = zeros(n - (m - 1) * tau_max, m); for i = 1:m X(:, i) = x((m - i) * tau_max + 1:end - (i - 1) * tau_max); Y(:, i) = y((m - i) * tau_max + 1:end - (i - 1) * tau_max); end % 计算 X 和 Y 的互信息 max_delay = 0; max_mi = -inf; for delay = tau_min:tau_max mi = mutual_information(X, Y, delay); if mi > max_mi max_mi = mi; max_delay = delay; end end % 输出最大互信息和对应的时延 fprintf('Max mutual information: %f\n', max_mi); fprintf('Delay corresponding to max mutual information: %d\n', max_delay); ``` 其中 `mutual_information` 函数是计算两个时间序列互信息的函数,需要自己实现。这里简单给出一个代码示例: ```matlab function mi = mutual_information(X, Y, delay) % 计算 X 和 Y 的互信息时延为 delay n = size(X, 1); m = size(X, 2); % 构造延迟后的嵌入向量矩阵 Y_delayed Y_delayed = zeros(n, m); for i = 1:m Y_delayed(:, i) = Y((m - i) * delay + 1:end - (i - 1) * delay); end % 计算 X 和 Y_delayed 的联合分布 p_joint = zeros(m^2); for i = 1:n x_index = encode(X(i, :), m); y_index = encode(Y_delayed(i, :), m); p_joint(x_index, y_index) = p_joint(x_index, y_index) + 1; end p_joint = p_joint / n; % 计算 X 和 Y_delayed 的边缘分布 p_x = sum(p_joint, 2); p_y = sum(p_joint, 1); % 计算互信息 mi = 0; for i = 1:m^2 if p_joint(i) > 0 mi = mi + p_joint(i) * log2(p_joint(i) / (p_x(i % m + 1) * p_y(floor((i - 1) / m) + 1))); end end ``` 其中 `encode` 函数是将一个嵌入向量编码成一个整数的函数,可以使用以下代码实现: ```matlab function index = encode(embedding, m) % 将一个 m 维嵌入向量编码成一个整数 index = 0; for i = 1:m index = index + (embedding(i) - 1) * m^(m - i); end index = index + 1; ``` 这样就可以计算出互信息的最大时延了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值