Win11 WSL2 Ubuntu Python FFT & IFFT
豪ドル/円 大容量デ-タ FFT 解析
ここまでで、豪ドル/円 大容量デ-タ FFT 解析の前段階の準備が完了しました。
引き続き、大容量デ-タを FFT 解析して、豪ドル/円を予測して行きます。
- 仮の予測値と大容量データ合体
FFT 解析をする準備として、仮の予測値と大容量データ合体します。
np.hstack((a, b)) は ndarray 配列 a と b を結合してくれます。
hstack は結合したい複数の配列をタプルでまとめて引数に受け取ります。
リスト型の a, b を括弧で括りタプル型に変更、hstack( )内に引数として引き込み結合します。
raw_data_10 = np.hstack((raw_data, p(Idx10))) - 豪ドル/円 合体デ-タの表示
合体デ-タを表示します。
Y 軸デ-タはここまでで準備完了ですので、X 軸デ-タを作成します。
デ-タ数 fs は
fs = len(raw_data_10)
となり、サンプリング周波数を fs[Hz] とすれば、 デ-タ数 fs をサンプリングするには1秒を要することになります。
np.linspace(start, stop, 生成する ndarray 配列の要素数)
を利用して、線形に等間隔な数列 t を生成します。
t = np.linspace(0, fs-1, fs)
例えば、fs = 100 ならば
t = 0,1,2,3,・・・・・・,97,98,99
となります。
ここまでくれば、豪ドル/円 デ-タを表示するのは簡単です。
plt.plot(t, raw_data_10)
plt.show() - フーリエ変換(FFT)の実行
フーリエ変換(FFT)を実行します。
これは簡単です。
f = np.fft.fft(raw_data_10)
f_abs = np.abs(f)
plt.plot(f_abs[:int(fs/2)+1])
plt.show()
FFT の結果 f は複素数です。
実数部と虚数部を別々に分けて表示しても良いのですが、今回は絶対値を取り、 かつ、左右対称なので左半分のみを表示します。 - ロ-パスフィルタのカットオフを決める
フーリエ変換(FFT)の結果よりカットオフ fc が 800 以下の値で 主信号は構成されているとみて、 それ以上の周波数成分はノイズとみなすことにします。
ちなみに fc の最大値は fs 約5000 です。
fc は小さくしてなるべくノイズをカットするようにします。
今回は fc = 800 以上の周波数成分はノイズとみなします。
ここは異論があるとは思いますが、よしとさせてください。
よって、ロ-パスフィルタ処理を行うため、配列 f[800]~f[fs-1] の値を0でクリアします。
fc = 800 # cut off
f[fc:] = 0 # low pass filter
ロ-パスフィルタ処理後のフーリエ変換(FFT)の結果も見ておきましょう。
f_abs = np.abs(f)
plt.plot(f_abs[:int(fs/2)+1])
plt.show() - 逆フーリエ変換(IFFT)の実行
ロ-パスフィルタ処理後元の波形がどう変化したか見てみましょう。
f_ifft = np.fft.ifft(f*2)
# 逆フーリエ変換(IFFT)
f_real = f_ifft.real
# 実数部のみにする
plt.plot(t, f_real)
plt.show()
IFFT は inverse fast Fourier transform の略称で FFT の結果を元の信号形式に戻すことができます。
IFFT 処理結果は f_ifft で受け取ります。
IFFT の処理結果は numpy.ndarray 形式で、値は複素数です。
f_ifft.real に実数部が、f_ifft.imag に虚数部が格納されます。
この実数部がロ-パスフィルタ処理後の元の信号形式を表しています。
実数部をプロットします。
急激な動きがなくなり、なめらかな変化になります。
これが正規化された予測値になります。 - 正規化された予測値の表示
予測値の全部を表示します。
plt.plot(t, f_real)
plt.show()
次に、古いデータは表示せず最新予測110個の予測値に限定して表示します。
f_real_110 = f_real[-110:]
t_110 = t[-110:] - t[-110]
plt.plot(t_110, f_real_110)
plt.show() - 正規化された予測値を実値に戻す
正規化された予測値を実値 result_110 に戻します。
result_110 = f_real_110.copy()
result_110 *= std
result_110 += mean
print("result_110")
print(result_110) - 予測誤差回避
豪ドル/円 デ-タは波の最後の部分は1周期が完了する前に終わってしまいます。
当然そのスペクトラムも連続正弦波とは異なりこれが予測誤差となってしまいます。
このように、有限の時間範囲でデータを切り取ってしまうために生じる不確かさが発生します。
FFT を利用する場合、信号の周期と取り込み区間を同期できません。
不連続による高調波発生を回避するためラスト5個の予測データを捨てます。
ラスト5個のデータには不連続が発生し高調波が発生し予測誤差が含まれていると考えるからです。
result_105 = result_110[:105]
print("result_105")
print(result_105)
これが実値の予測値になります。
元デ-タと予測値プロット表示
ここまでで FFT 解析は終わったので、元デ-タと予測値をプロット表示して行きます。
元デ-タは 約5000 ありますので表示は最新の 100 だけにします。
また予測値100この内最後の5個は精度が良くないので捨てます。
ファイル作成方法については
Win11 WSL2 Ubuntu Python RNN--元デ-タと予測値プロット表示・・・①
に詳細説明がありますので、これを参考にしてください。
Idx0 = Idx.copy()
Idx_100 = Idx0[-100:] - Idx0[-100]
Idx_100 = Idx_100
print("Idx_100")
print(Idx_100)
t_105 = t_110[:105]
print("t_105")
print(t_105)
Close_100 = Close1[-100:]
plt.plot(t_105, result_105)
plt.plot(Idx_100, Close_100)
plt.show()
ここまでで、豪ドル/円 大容量デ-タを FFT 解析して、豪ドル/円を予測できました。
引き続き、予測図の元デ-タをロ-ソク足表示に変更していきます。