statsmodels.nonparametric.smoothers_lowess.lowess¶
-
statsmodels.nonparametric.smoothers_lowess.lowess(endog, exog, frac=
0.6666666666666666, it=3, delta=0.0, xvals=None, is_sorted=False, missing='drop', return_sorted=True)[source]¶ LOWESS(局部加权散点图平滑法)
一个lowess函数,用于输出在给定的exog值处对endog的平滑估计,数据点为(exog, endog)
- Parameters:¶
- endog1-D
numpyarray 观察点的y值
- exog1-D
numpyarray 观察点的x值
- frac
float 介于0和1之间。在估计每个y值时使用的数据比例。
- it
int 要执行的基于残差的重新加权次数。
- delta
float 在此距离内使用线性插值而不是加权回归。
- xvals: 1-D numpy array
要评估回归的自变量值。 如果提供,则不能使用delta。
- is_sortedbool
如果为 False(默认值),则数据将在计算 lowess 之前按 exog 排序。如果为 True,则假定数据已经按 exog 排序。如果指定了 xvals,则在 is_sorted 为 True 时,它也必须排序。
- missing
str 可用的选项是‘none’、‘drop’和‘raise’。如果选择‘none’,则不进行nan检查。如果选择‘drop’,则会删除任何包含nan的观测值。如果选择‘raise’,则会引发错误。默认值是‘drop’。
- return_sortedbool
如果为True(默认),则返回的数组按exog排序,并移除缺失(nan或无限)的观测值。如果为False,则返回的数组与输入数组具有相同的长度和相同的观测顺序。
- endog1-D
- Returns:¶
注释
此lowess函数实现了以下参考文献中给出的算法,使用局部线性估计。
假设输入数据有N个点。该算法通过 估计平滑的y_i,方法是取frac*N个最接近(x_i,y_i)的点 基于它们的x值,并使用加权线性回归估计y_i。(x_j,y_j)的权重 是应用于abs(x_i-x_j)的三次立方函数。
如果它 > 1,则进一步执行加权局部线性回归,其中权重与上述相同,乘以残差的_lowess_bisquare函数。每次迭代所需的时间大约与原始拟合相同,因此这些迭代成本较高。当噪声具有极重的尾部时,例如柯西噪声,它们最为有用。尾部较轻的噪声,例如自由度df>2的t分布,问题较小。权重降低了具有较大残差的点的影响。在极端情况下,残差大于6倍中位数绝对残差的点被赋予权重0。
delta 可以用于节省计算。对于每个 x_i,回归会跳过距离小于 delta 的点。下一个回归会拟合距离 x_i 在 delta 范围内的最远点,并且所有中间的点都会通过线性插值在两个回归拟合之间进行估计。
明智地选择delta可以显著减少大型数据(N > 5000)的计算时间。一个好的选择是
delta = 0.01 * range(exog)。如果提供了xvals,则在那些点上计算回归,并返回拟合值。否则,回归将在exog的点上运行。
可能需要进行一些实验来为特定数据集找到合适的frac和iter选择。
参考文献
克利夫兰, W.S. (1979) “鲁棒局部加权回归与平滑散点图”. 美国统计协会杂志 74 (368): 829-836.
示例
以下内容允许比较不同frac值的lowess拟合之间的差异。
>>> import numpy as np >>> import statsmodels.api as sm >>> lowess = sm.nonparametric.lowess >>> x = np.random.uniform(low = -2*np.pi, high = 2*np.pi, size=500) >>> y = np.sin(x) + np.random.normal(size=len(x)) >>> z = lowess(y, x) >>> w = lowess(y, x, frac=1./3)这给出了当值为0与不为0时的类似比较。
>>> import numpy as np >>> import scipy.stats as stats >>> import statsmodels.api as sm >>> lowess = sm.nonparametric.lowess >>> x = np.random.uniform(low = -2*np.pi, high = 2*np.pi, size=500) >>> y = np.sin(x) + stats.cauchy.rvs(size=len(x)) >>> z = lowess(y, x, frac= 1./3, it=0) >>> w = lowess(y, x, frac=1./3)