скользящее окно для линейной регрессии с использованием numpy as_strided - PullRequest
0 голосов
/ 24 ноября 2018

Я использовал примеры скользящего окна, используя 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

Вы можете получить тот же результат, используя stats

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 голосов
/ 25 ноября 2018

Интересно, я никогда не видел функцию шага.Однако документы предупреждают об этом методе.Альтернативным методом будет использование линейной алгебры для регрессии в окнах.Вот тривиальный пример:

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

0 голосов
/ 25 ноября 2018

Вот что я придумал.Не самая красивая, но работает.

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)      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...