Sunday, January 17, 2016

1D Smoothing Savitzky Golay

 

Metoda Savitzky Golay (wikipedia)

Animasi di atas menunjukkan smoothing dengan menggunakan Metoda Savitzky Golay.



 Kode Python berikut berguna untuk melakukan 1D (XY) smoothing dengan menggunakan metoda Savitzky Golay. Kelebihan metoda ini adalah mempertahankan posisi X original.


#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt

def savitzky_golay(y, window_size, order, deriv=0, rate=1):
    import numpy as np
    from math import factorial
   
    try:
        window_size = np.abs(np.int(window_size))
        order = np.abs(np.int(order))
    except ValueError, msg:
        raise ValueError("window_size and order have to be of type int")
    if window_size % 2 != 1 or window_size < 1:
        raise TypeError("window_size size must be a positive odd number")
    if window_size < order + 2:
        raise TypeError("window_size is too small for the polynomials order")
    order_range = range(order+1)
    half_window = (window_size -1) // 2
    # precompute coefficients
    b = np.mat([[k**i for i in order_range] for k in range(-half_window, half_window+1)])
    m = np.linalg.pinv(b).A[deriv] * rate**deriv * factorial(deriv)
    # pad the signal at the extremes with
    # values taken from the signal itself
    firstvals = y[0] - np.abs( y[1:half_window+1][::-1] - y[0] )
    lastvals = y[-1] + np.abs(y[-half_window-1:-1][::-1] - y[-1])
    y = np.concatenate((firstvals, y, lastvals))
    return np.convolve( m[::-1], y, mode='valid')

x = np.linspace(0,2*np.pi,100)
y = np.sin(x) + np.random.random(100) * 0.2
yhat = savitzky_golay(y, 51, 3) # window size 51, polynomial order 3

plt.plot(x,y, 'b')
plt.plot(x,yhat, 'r')
plt.axis((min(x),max(x),min(y),max(y)))
plt.show()

No comments: