Python でのスムーズなデータ

Shivam Arora 2023年1月30日
  1. Python で scipy.signal.savgol_filter() メソッドを使用してデータを平滑化する
  2. Python で numpy.convolve メソッドを使用してデータをスムーズにする
  3. Python で statsmodels.kernel_regression を使用してデータを平滑化する
Python でのスムーズなデータ

Python には、データ分析と視覚化に幅広いアプリケーションがあります。多くの観測値を含む大規模なデータセットを分析する場合、最終的なプロットをより注意深く研究するためにグラフの曲線を滑らかにする必要がある状況に遭遇する可能性があります。さまざまな方法を使用して Python でこれを実現する方法について説明します。

Python で scipy.signal.savgol_filter() メソッドを使用してデータを平滑化する

Savitzky-Golay フィルターは、グラフを平滑化するためにデータポイントを使用するデジタルフィルターです。小さなウィンドウを作成し、そのウィンドウのデータに多項式を適用する最小二乗法を使用し、その多項式を使用して特定のウィンドウの中心点を想定します。次に、ウィンドウが 1つのデータポイントだけシフトされ、すべてのネイバーが互いに比較的調整されるまでプロセスが繰り返されます。

scipy.signal.savgol_filter() 関数を使用して、これを Python で実装できます。

次の例を参照してください。

import numpy as np
from scipy.signal import savgol_filter
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x) + np.random.random(100) * 0.2
yhat = savgol_filter(y, 51, 3)

plt.plot(x, y)
plt.plot(x, yhat, color="green")
plt.show()

出力:

Python スムーズデータ 1

上記の例では、フィルタリング方法を使用して、y 軸にプロットされるデータを平滑化しました。違いを観察できるように、元のデータと平滑化されたデータの両方をプロットしました。

Python で numpy.convolve メソッドを使用してデータをスムーズにする

numpy.convolve() は、2つの 1 次元シーケンスの離散的な線形畳み込みを提供します。これを使用して、データをフィルタリングおよび平滑化できる移動平均を作成します。

これは良い方法とは見なされません。

例えば、

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x) + np.random.random(100) * 0.8


def smooth(y, box_pts):
    box = np.ones(box_pts) / box_pts
    y_smooth = np.convolve(y, box, mode="same")
    return y_smooth


plt.plot(x, y)
plt.plot(x, smooth(y, 3))
plt.plot(x, smooth(y, 19))

出力:

Python スムーズデータ 2

上記の例では、時間デルタが 3 と 19 の 2つの移動平均をプロットしました。両方をグラフにプロットしました。

他の方法を使用して移動平均を計算することもできます。

Python で statsmodels.kernel_regression を使用してデータを平滑化する

カーネル回帰は、条件付き平均 E[y|X] を計算します。ここで、y = g(X) + e であり、モデルに適合します。制御変数に基づいてデータを平滑化するために使用できます。

これを実行するには、statsmodels モジュールの KernelReg() 関数を使用する必要があります。

例えば、

from statsmodels.nonparametric.kernel_regression import KernelReg
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x) + np.random.random(100) * 0.2

kr = KernelReg(y, x, "c")
plt.plot(x, y, "+")
y_pred, y_std = kr.fit(x)

plt.plot(x, y_pred)
plt.show()

出力:

Python スムーズデータ 3

この方法では良い結果が得られますが、非常に遅いと見なされることに注意してください。フーリエ変換も使用できますが、これは周期的なデータでのみ機能します。

関連記事 - Python Graph