有不止一种方法可以做到!
这里我展示了如何使用各种技术来降低噪音:
- 移动平均线
- LOWESS 回归
- 低通滤波器
- 插值
坚持使用@Hooked 示例数据以保持一致性:
import numpy as np
import matplotlib.pyplot as plt
X = np.arange(1, 1000, 1)
Y = np.log(X ** 3) + 10 * np.random.random(X.shape)
plt.plot(X, Y, alpha = .5)
plt.show()
- 移动平均线
有时您只需要moving average。
例如,使用窗口大小为 100 的 pandas:
import pandas as pd
df = pd.DataFrame(Y, X)
df_mva = df.rolling(100).mean() # moving average with a window size of 100
df_mva.plot(legend = False);
您可能需要对数据尝试几种窗口大小。请注意,df_mva 的前 100 个值将为 NaN,但可以使用 dropna 方法删除这些值。
pandas rolling function 的使用详情。
- LOWESS 回归
我已成功使用 LOWESS(局部加权散点图平滑)来消除重复测量数据集中的噪声。有关局部回归方法的更多信息,包括 LOWESS 和 LOESS,here。这是一种简单的方法,只需要调整一个参数,根据我的经验,它会产生很好的效果。
下面是如何使用statsmodels 实现来应用LOWESS 技术:
import statsmodels.api as sm
y_lowess = sm.nonparametric.lowess(Y, X, frac = 0.3) # 30 % lowess smoothing
plt.plot(y_lowess[:, 0], y_lowess[:, 1]) # some noise removed
plt.show()
可能需要更改frac 参数,这是估计每个y 值时使用的数据的一部分。增加frac 值以增加平滑量。 frac 值必须介于 0 和 1 之间。
关于statsmodels lowess usage的更多详情。
- 低通滤波器
Scipy 提供了一组可能合适的low pass filters。
应用过滤器后:
from scipy.signal import lfilter
n = 50 # larger n gives smoother curves
b = [1.0 / n] * n # numerator coefficients
a = 1 # denominator coefficient
y_lf = lfilter(b, a, Y)
plt.plot(X, y_lf)
plt.show()
查看scipy lfilter documentation,了解有关如何在差分方程中使用分子和分母系数的实施细节。
scipy.signal package 中还有其他过滤器。
- 插值
最后,这里是radial basis function interpolation的例子:
from scipy.interpolate import Rbf
rbf = Rbf(X, Y, function = 'multiquadric', smooth = 500)
y_rbf = rbf(X)
plt.plot(X, y_rbf)
plt.show()
可以通过增加smooth 参数来实现更平滑的近似。要考虑的替代function 参数包括“cubic”和“thin_plate”。在考虑function 值时,我通常先尝试“thin_plate”,然后再尝试“cubic”;然而,“thin_plate”和“cubic”似乎都在与这个数据集中的噪音作斗争。
检查scipy docs 中的其他Rbf 选项。 Scipy 提供了其他单变量和多变量插值技术(参见tutorial)。