我利用as_strided利用滚动窗口示例来创建各种numpy函数的滑动版本。
def std(a,window):
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.std(np.lib.stride_tricks.as_strided(a, shape=shape,strides=strides),axis=1)
现在,我尝试在线性回归函数上利用相同的as_strided方法。 y = a + bx
def linear_regress(x,y):
sum_x = np.sum(x)
sum_y = np.sum(y)
sum_xy = np.sum(np.multiply(x,y))
sum_xx = np.sum(np.multiply(x,x))
sum_yy = np.sum(np.multiply(y,y))
number_of_records = len(x)
A = (sum_y*sum_xx - sum_x*sum_xy)/(number_of_records*sum_xx - sum_x*sum_x)
B = (number_of_records*sum_xy - sum_x*sum_y)/(number_of_records*sum_xx - sum_x*sum_x)
return A + B*number_of_records
您可以使用统计信息获得相同的结果
from scipy import stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x,p)
xValue = len(x)
y = (slope + intercept*xValue)
当传递两个数组时,我不确定如何将上述函数放入as_strided方法中。我想我必须创建两个形状并同时通过两个形状?
def rolling_lr(x,y,window):
shape = y.shape[:-1] + (y.shape[-1] - window + 1, window)
strides = y.strides + (y.strides[-1],)
return linear_regress(np.lib.stride_tricks.as_strided(x,y shape=shape, strides=strides))
感谢您的帮助。
答案 0 :(得分:0)
这是我想出的。不是最漂亮,但可以。
def linear_regress(x,y,window):
x_shape = x.shape[:-1] + (x.shape[-1] - window + 1, window)
x_strides = x.strides + (x.strides[-1],)
y_shape = y.shape[:-1] + (y.shape[-1] - window + 1, window)
y_strides = y.strides + (y.strides[-1],)
sx = np.lib.stride_tricks.as_strided(x,shape=x_shape, strides=x_strides)
sy = np.lib.stride_tricks.as_strided(y,shape=y_shape, strides=y_strides)
sum_x = np.sum(sx,axis=1)
sum_y = np.sum(sy,axis=1)
sum_xy = np.sum(np.multiply(sx,sy),axis=1)
sum_xx = np.sum(np.multiply(sx,sx),axis=1)
sum_yy = np.sum(np.multiply(sy,sy),axis=1)
m = (sum_y*sum_xx - sum_x*sum_xy)/(window*sum_xx - sum_x*sum_x)
b = (window*sum_xy - sum_x*sum_y)/(window*sum_xx - sum_x*sum_x)
答案 1 :(得分:0)
有趣的是,我从未见过跨步功能。文档确实会警告这种方法。另一种方法是使用线性代数在窗口上进行回归。这是一个简单的示例:
from numpy import *
# generate points
N = 30
x = linspace(0, 10, N)[:, None]
X = ones((N, 1)) * x
Y = X * array([1, 30]) + random.randn(*X.shape)*1e-1
XX = concatenate((ones((N,1)), X), axis = 1)
# window data
windowLength = 10
windows = array([roll(\
XX, -i * windowLength, axis = 0)[:windowLength, :]\
for i in range(len(XX) - windowLength)])
windowsY = array([roll(Y, -i * windowLength, axis = 0)[:windowLength, :]\
for i in range(len(Y) - windowLength)])
# linear regression on windows
reg = array([\
((linalg.pinv(wx.T.dot(wx))).dot(wx.T)).dot(wy) for \
wx, wy in zip(windows, windowsY)])
# plot regression on windows
from matplotlib import style
style.use('seaborn-poster')
from matplotlib.pyplot import subplots, cm
fig, ax = subplots()
colors = cm.tab20(linspace(0, 1, len(windows)))
for win, color, coeffs, yi in zip(windows, colors, reg, windowsY):
ax.plot(win, yi,'.', alpha = .5, color = color)
ax.plot(win[:, 1], win.dot(coeffs), alpha = .5, color = color)
x += 1
ax.set(**dict(xlabel = 'x', ylabel = 'y'))