使用numpy as_strided

时间:2018-11-23 22:05:29

标签: python numpy regression

我利用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))

感谢您的帮助。

2 个答案:

答案 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'))

哪个生产: enter image description here