雑感等

音楽,数学,語学,その他に関するメモを記す.

pythonで自己MIC(相互情報量)関数を計算

自己相関関数では,ある信号sig(t)とその信号を時間kだけ遅延させた信号sig(t+k)との相関係数を計算するが,
ここでは相関係数の代わりに相互情報量(MIC)を求める関数automicを示す.
MIC自体はminepyで計算する.

下記プログラムを実行すると,グラフが2つ表示される.

"""
「自己」相互情報量(MIC)関数を計算する.
自己相関関数において,遅延と相関係数の関係を求めるように,
本関数では,遅延とMICの関係を求める.
"""
from minepy import MINE  # MICの計算ライブラリをインポート
from typing import List  # 型表示における"List"を有効化


def automic(sig: List[float]) -> List[float]:
    """
    sig[0](遅延させていない信号)とsig[k](k点遅延させた信号)との相互情報量を求める.
    :rtype: List[float]
    :param sig: 1次元の数値配列.時系列信号など.
    :return: 1次元の数値配列mics.mics[k]は遅延kにおけるMIC.
    """
    mine = MINE()
    siglen = len(sig)
    mics = []
    for k in range(0, siglen - 1):
        mine.compute_score(sig[k:-1], sig[0:-k - 1])
        mics.append(mine.mic())
    return mics


if __name__ == "__main__":
    import numpy as np
    from matplotlib import pyplot as plt

    fs = 100  # サンプリング周波数
    f = 4  # 周波数
    tmax = 1  # 終了時刻[s]
    t = np.arange(0, tmax, 1 / fs)
    sig = np.sin(2 * np.pi * f * t)
    plt.plot(t, sig, marker=".")
    plt.xlabel("t [sample]")
    plt.ylabel("signal [a.u.]")
    plt.figure()
    mics = automic(sig)
    plt.plot(mics)
    plt.xlabel("delay k [sample]")
    plt.ylabel("MIC")
    plt.show()

f:id:kazmus:20190217232923p:plain
上記プログラムでの入力信号

f:id:kazmus:20190217233012p:plain
計算された自己MIC(相互情報量)関数.入力された信号と遅延させた信号が同位相と逆位相の場合でMICが1に近づいているため,8回ピークがある.ただし,最後のピークは入力波形が短くなりすぎたためノイズが生じている.