前提・実現したいこと
y軸の正方向のノイズを含む直線データからノイズを取り除き、直線を取り出すプログラムをつくっています。ノイズの大きさは1%程度です。直線に対して高速フーリエ変換(FFT)は不適なので、移動平均とスプライン補間による平滑化を試みました。しかし、以下のコードでは取り出したい直線をうまく抽出できず困っています。ノイズを含むy=10-x+noise(グラフのlinear, 青)からノイズを含まないy=10-x(グラフのoriginal, 黒)を取り出すのが目標です。改善点、アドバイス、別のアプローチなどがあれば教えていただけると幸いです。
。
以下のサイトを参考にしました。
https://snova301.hatenablog.com/entry/2018/10/07/135233
該当のソースコード
Python
1import numpy as np 2import matplotlib.pyplot as plt 3from scipy.interpolate import interp1d 4 5 6def make_func(in_x): 7 np.random.seed(0) 8 out_y = 10 - in_x + 0.3*(np.random.rand(in_x.size)) # 10-x に正方向のみの誤差を加える 9 return out_y 10 11 12def spline_interp(in_x, in_y): 13 out_x = np.linspace(np.min(in_x), np.max(in_x), np.size(in_x)*100) # もとのxの個数より多いxを用意 14 func_spline = interp1d(in_x, in_y, kind='cubic') # 3次のスプライン曲線 15 out_y = func_spline(out_x) # func_splineはscipyオリジナルの型 16 17 return out_x, out_y 18 19 20def moving_avg(in_x, in_y): 21 np_y_conv = np.convolve(in_y, np.ones(3)/float(3), mode='valid') 22 out_x_dat = np.linspace(np.min(in_x), np.max(in_x), np.size(np_y_conv)) 23 24 return out_x_dat, np_y_conv 25 26 27def main(): 28 x1 = np.linspace(0, 10, 100) 29 y1 = make_func(x1) 30 31 x2, y2 = spline_interp(x1, y1) 32 33 x3, y3 = moving_avg(x1, y1) 34 x4, y4 = spline_interp(x3, y3) 35 36 plt.plot(x1, 10-x1, color='k', label='original', alpha=0.7) 37 plt.plot(x1, y1, color='b', label='linear', alpha=0.7) 38 plt.plot(x2, y2, color='r', label='spline', alpha=0.7) 39 plt.plot(x4, y4, color='g', label='average + spline', alpha=0.7) 40 plt.legend() 41 plt.show() 42 43 44if __name__ == '__main__': 45 main()
補足情報(FW/ツールのバージョンなど)
python 3.8.8
回答5件
あなたの回答
tips
プレビュー