Эффективный онлайн алгоритм линейной регрессии в python

1

Я получил двухмерный набор данных с двумя столбцами x и y. Я хотел бы получить динамические коэффициенты регрессии и перехвата динамически при подаче новых данных. Используя scikit-learn, я мог бы рассчитать все текущие доступные данные следующим образом:

from sklearn.linear_model import LinearRegression
regr = LinearRegression()
x = np.arange(100)
y = np.arange(100)+10*np.random.random_sample((100,))
regr.fit(x,y)
print(regr.coef_)
print(regr.intercept_)

Тем не менее, у меня довольно большой набор данных (всего более 10 тыс. Строк), и я хочу рассчитать коэффициент и перехватить как можно быстрее, когда появятся новые строки. В настоящее время вычислять 10 тыс. Строк занимает около 600 микросекунд, и я хочу ускорить этот процесс,

Scikit-learn выглядит как не имеет функции онлайн-обновления для линейного регрессионного модуля. Есть ли лучшие способы сделать это?

  • 0
    В sklearn только оценщики, отмеченные здесь, имеют возможность онлайн-обучения.
  • 0
    @VivekKumar Есть ли какая-либо другая формула или пакет может решить эту проблему?
Показать ещё 1 комментарий
Теги:
numpy
scikit-learn
linear-regression

1 ответ

1
Лучший ответ

Я нашел решение из этой статьи: обновление простой линейной регрессии. Реализация выполняется следующим образом:

def lr(x_avg,y_avg,Sxy,Sx,n,new_x,new_y):
    """
    x_avg: average of previous x, if no previous sample, set to 0
    y_avg: average of previous y, if no previous sample, set to 0
    Sxy: covariance of previous x and y, if no previous sample, set to 0
    Sx: variance of previous x, if no previous sample, set to 0
    n: number of previous samples
    new_x: new incoming 1-D numpy array x
    new_y: new incoming 1-D numpy array x
    """
    new_n = n + len(new_x)

    new_x_avg = (x_avg*n + np.sum(new_x))/new_n
    new_y_avg = (y_avg*n + np.sum(new_y))/new_n

    if n > 0:
        x_star = (x_avg*np.sqrt(n) + new_x_avg*np.sqrt(new_n))/(np.sqrt(n)+np.sqrt(new_n))
        y_star = (y_avg*np.sqrt(n) + new_y_avg*np.sqrt(new_n))/(np.sqrt(n)+np.sqrt(new_n))
    elif n == 0:
        x_star = new_x_avg
        y_star = new_y_avg
    else:
        raise ValueError

    new_Sx = Sx + np.sum((new_x-x_star)**2)
    new_Sxy = Sxy + np.sum((new_x-x_star).reshape(-1) * (new_y-y_star).reshape(-1))

    beta = new_Sxy/new_Sx
    alpha = new_y_avg - beta * new_x_avg
    return new_Sxy, new_Sx, new_n, alpha, beta, new_x_avg, new_y_avg

Сравнение производительности:

Scikit изучает версию, которая вычисляет 10k выборок в целом.

from sklearn.linear_model import LinearRegression
x = np.arange(10000).reshape(-1,1)
y = np.arange(10000)+100*np.random.random_sample((10000,))
regr = LinearRegression()
%timeit regr.fit(x,y)
# 419 µs ± 14.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Моя версия предполагает, что образец 9k уже рассчитан:

Sxy, Sx, n, alpha, beta, new_x_avg, new_y_avg = lr(0, 0, 0, 0, 0, x.reshape(-1,1)[:9000], y[:9000])
new_x, new_y = x.reshape(-1,1)[9000:], y[9000:]
%timeit lr(new_x_avg, new_y_avg, Sxy,Sx,n,new_x, new_y)
# 38.7 µs ± 1.31 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Ожидается, что в 10 раз быстрее.

  • 1
    Получаете ли вы аналогичные прогнозы / коэффициенты по сравнению со sklearn?
  • 0
    @VivekKumar они коэффициент и перехват одинаковы

Ещё вопросы

Сообщество Overcoder
Наверх
Меню