Множественная линейная регрессия со статистической моделью Python

В R можно выполнить множественную линейную регрессию, например

temp = lm(log(volume_1[11:62])~log(price_1[11:62])+log(volume_1[10:61]))

В Python можно выполнить множественную линейную регрессию с помощью формулы стиля R, поэтому я подумал, что приведенный ниже код должен работать так же хорошо,

import statsmodels.formula.api as smf
import pandas as pd
import numpy as np

rando = lambda x: np.random.randint(low=1, high=100, size=x)

df = pd.DataFrame(data={'volume_1': rando(62), 'price_1': rando(62)})

temp = smf.ols(formula='np.log(volume_1)[11:62] ~ np.log(price_1)[11:62] + np.log(volume_1)[10:61]', 
               data=df) 
# np.log(volume_1)[10:61] express the lagged volume

но я получаю ошибку

PatsyError: Number of rows mismatch between data argument and volume_1[11:62] (62 versus 51)
volume_1[11:62] ~ price_1[11:62] + volume_1[10:61]

Я предполагаю, что невозможно регрессировать только часть строк в столбцах, потому что data = df имеет 62 строки, а другие переменные имеют 51 строку.

Есть ли удобный способ сделать регрессию, как R?

Тип df — pandas Dataframe, а имена столбцов — Volume_1, Price_1.


person Park Dongyeon    schedule 09.10.2018    source источник
comment
Похоже, что ошибка исходит от Patsy, который используется для R как синтаксис формулы в python. Если бы вы использовали одно и то же подмножество строк для каждого термина, было бы легко использовать один и тот же фрагмент df, но в вашем примере это не так.   -  person jtweeder    schedule 25.10.2018


Ответы (1)


Используя пример из вопроса github в репозитории patsy, можно заставить ваш столбец отставания работать правильно.

import statsmodels.formula.api as smf
import pandas as pd
import numpy as np

rando = lambda x: np.random.randint(low=1, high=100, size=x)

df = pd.DataFrame(data={'volume_1': rando(62), 'price_1': rando(62)})

def lag(x, n):
    if n == 0:
        return x
    if isinstance(x,pd.Series):
        return x.shift(n)

    x = x.astype('float')
    x[n:] = x[0:-n]
    x[:n] = np.nan
    return x

temp = smf.ols(formula='np.log(volume_1) ~ np.log(price_1) + np.log(lag(volume_1,1))', 
               data=df[11:62]) 
person jtweeder    schedule 25.10.2018
comment
Почему бы не использовать метод .shift() для фрейма данных? - person Evgeny; 25.10.2018
comment
temp = smf.ols(formula='np.log(volume_1) ~ np.log(price_1) + np.log(volume_1.shift())', data=df[11:62]) тоже работает. Но в случаях, когда data не предоставляется в качестве фрейма данных, могут возникнуть проблемы. Данные могут быть любым диктоподобным объектом с переменными в формуле. Таким образом, {'volume_1': [values], 'price_1': [values]} можно было бы использовать в качестве аргумента данных, и он потерпел бы неудачу, если бы использовался только .shift(). - person jtweeder; 25.10.2018
comment
... и причина, по которой вы пытаетесь поймать орбитальный тип, - это поведение кода R? - person Evgeny; 25.10.2018
comment
Да... функция R lm позволяет несколько разных типов данных для передачи в аргумент data. Таким образом, использование функции задержки, как указано выше, позволяет использовать smf.ols так же, как в R. - person jtweeder; 25.10.2018