Python — рассчитать текущее 1 стандартное отклонение от линии линейной регрессии

Мне удалось получить линию линейной регрессии для данных временных рядов, во многом благодаря предыдущему stackoverflow. Итак, у меня есть следующие графики/линия, нарисованные из python:

Линия линейной регрессии

Я получил эту линию регрессии со следующим кодом, первоначально импортируя данные ценового/временного ряда из CSV-файла:

f4 = open('C:\Users\cost9\OneDrive\Documents\PYTHON\TEST-ASSURANCE FILES\LINEAR REGRESSION MULTI TREND IDENTIFICATION\ES_1H.CSV')    
ES_1H = pd.read_csv(f4)
ES_1H.rename(columns={'Date/Time': 'Date'}, inplace=True)
ES_1H['Date'] = ES_1H['Date'].reset_index()
ES_1H.Date.values.astype('M8[D]')
ES_1H_Last_300_Periods = ES_1H[-300:]
x = ES_1H_Last_300_Periods['Date']
y = ES_1H_Last_300_Periods['Close']
x = sm.add_constant(x)
ES_1H_LR = pd.ols(y = ES_1H_Last_300_Periods['Close'], x = ES_1H_Last_300_Periods['Date'])
plt.scatter(y = ES_1H_LR.y_fitted.values, x = ES_1H_Last_300_Periods['Date'])

То, что я ищу, - это иметь возможность построить/идентифицировать 1 стандартное отклонение от линии регрессии (показано на рисунке выше). Большая часть приведенного выше кода предназначена только для согласования данных, чтобы можно было успешно построить линию регрессии — измените данные даты и времени, чтобы они работали в формуле ols, отрежьте данные до последних 300 периодов и т. д. Но я не уверен, как получить 1 стандартное отклонение от линии, нарисованной с помощью линейной регрессии.

Так что в идеале то, что я ищу, будет выглядеть примерно так:

Канал линейной регрессии

... с желтыми линиями, отстоящими на 1 стандартное отклонение от линии регрессии. Кто-нибудь знает, как здесь получить 1 стандартное отклонение от линии линейной регрессии? Для справки, вот статистика линейной регрессии:

Статистика линейной регрессии

edit: Для справки вот что я сделал:

plt.scatter(y = ES_1D_LR.y_fitted.values, x = ES_1D_Last_30_Periods['Date'])
plt.scatter(y = ES_1D_Last_30_Periods.Close, x = ES_1D_Last_30_Periods.Date)
plt.scatter(y = ES_1D_LR.y_fitted.values - np.std(ES_1D_LR.y_fitted.values), x = ES_1D_Last_30_Periods.Date)
plt.scatter(y = ES_1D_LR.y_fitted.values + np.std(ES_1D_LR.y_fitted.values), x = ES_1D_Last_30_Periods.Date)
plt.show()

person Cole Starbuck    schedule 15.02.2017    source источник


Ответы (3)


IIUC вы можете сделать это следующим образом:

In [185]: x = np.arange(100)

In [186]: y = x*0.6

In [187]: plt.scatter(x, y, c='b')
Out[187]: <matplotlib.collections.PathCollection at 0xc512390>

In [188]: plt.scatter(x, y - np.std(y), c='y')
Out[188]: <matplotlib.collections.PathCollection at 0xc683940>

In [189]: plt.scatter(x, y + np.std(y), c='y')
Out[189]: <matplotlib.collections.PathCollection at 0xc69a550>

Результат:

введите здесь описание изображения

person MaxU    schedule 15.02.2017
comment
Отлично, спасибо, что-то подобное работает для моих данных. Итак, у меня есть «канал регрессии», аналогичный приведенному выше, но знаете ли вы, как получить значение для линии регрессии в определенной точке x? Например, в вашем примере я ищу значение линии регрессии при x = 60 (на вашем графике это выглядит примерно как 35). - person Cole Starbuck; 16.02.2017
comment
@ColeStarbuck, что-то вроде этого: y[np.where(x == 60)[0][0]]? - person MaxU; 16.02.2017
comment
В настоящее время я использую z = ES_1D['Date'][-1:] n = z*1,8758 + 1865,8121, где z, например, дает мне последнюю дату, а затем n использует точку пересечения + z*slope, чтобы получить 2310,38, что выглядит правильно по графику. Я полагаю, это работает, просто хотел бы подтвердить, что это имеет смысл - person Cole Starbuck; 16.02.2017

Я просто хотел добиться того же. Вот как я это сделал.

import matplotlib.pyplot as plt
import numpy as np

Учитывая эти данные:

plt.plot(time, price)
plt.plot(time, predicted_price)
plt.show()

введите здесь описание изображения

Постройте окно вокруг линии регрессии predicted_price:

sq_dis = (price - predicted_price) ** 2
limit = (sq_dis.mean() + sq_dis.std()) * 0.3 # < - adjust window here
filter = np.abs(sq_dis) < limit
plt.plot(time, price)
plt.plot(time, predicted_price)
plt.plot(time[filter], price[filter])
plt.show()

введите здесь описание изображения

person James Schinner    schedule 04.02.2018

Я нашел этот метод более близким к тому, как я планировал построить свои графики регрессии, поэтому, возможно, вам он тоже покажется интересным:

Используйте функцию plt.fill_between, чтобы затенить область между средним значением и (среднее значение + стандартное отклонение), как показано в следующей ссылке: https://jakevdp.github.io/PythonDataScienceHandbook/04.03-errorbars.html

person Sadaf Farkhani    schedule 11.05.2020