Scipy.Odr множественная переменная регрессия

1

Я хотел бы выполнить многомерный ODR с scipy.odr. Я прочитал документацию по API, он говорит, что многомерность возможна, но я не могу заставить ее работать. Я не могу найти рабочий пример в Интернете, и API действительно груб и не дает никаких подсказок, как действовать.

Вот мой MWE:

import numpy as np
import scipy.odr

def linfit(beta, x):
    return beta[0]*x[:,0] + beta[1]*x[:,1] + beta[2]

n = 1000
t = np.linspace(0, 1, n)
x = np.full((n, 2), float('nan'))
x[:,0] = 2.5*np.sin(2*np.pi*6*t)+4
x[:,1] = 0.5*np.sin(2*np.pi*7*t + np.pi/3)+2
e = 0.25*np.random.randn(n)
y = 3*x[:,0] + 4*x[:,1] + 5 + e

print(x.shape)
print(y.shape)

linmod = scipy.odr.Model(linfit)
data = scipy.odr.Data(x, y)
odrfit = scipy.odr.ODR(data, linmod, beta0=[1., 1., 1.])
odrres = odrfit.run()
odrres.pprint()

Это вызывает следующее исключение:

scipy.odr.odrpack.odr_error: number of observations do not match

Что, похоже, связано с моими матричными фигурами, но я не знаю, как я должен правильно его формировать. Кто-нибудь знает?

Теги:
numpy
python-3.x
scipy
one-definition-rule

1 ответ

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

Во-первых, по моему опыту scipy.odr использует в основном массивы, а не матрицы. Похоже, что библиотека делает большой объем проверок по размеру, и заставить его работать с несколькими переменными, кажется, довольно хлопотно.

Это рабочий процесс, как обычно я получаю его на работу (и работал хотя бы на python 2.7):

import numpy as np
import scipy.odr

n = 1000
t = np.linspace(0, 1, n)

def linfit(beta, x):
    return beta[0]*x[0] + beta[1]*x[1] + beta[2] #notice changed indices for x

x1 = 2.5*np.sin(2*np.pi*6*t)+4
x2 = 0.5*np.sin(2*np.pi*7*t + np.pi/3)+2

x = np.row_stack( (x1, x2) ) #odr doesn't seem to work with column_stack

e = 0.25*np.random.randn(n)
y = 3*x[0] + 4*x[1] + 5 + e #indices changed

linmod = scipy.odr.Model(linfit)
data = scipy.odr.Data(x, y)
odrfit = scipy.odr.ODR(data, linmod, beta0=[1., 1., 1.])
odrres = odrfit.run()
odrres.pprint()

Таким образом, использование одинаковых (1D?) массивов, использование row_stack и адресация по одному номеру индекса, похоже, сработают.

  • 0
    Большое спасибо, работает и действительно не очевидно или хорошо задокументировано. Вы нашли это сами или у вас есть какие-либо документы по этому поводу.
  • 0
    Я действительно не помню. Я думаю, что я заработал это, имитируя пример где-то, и теперь у меня есть несколько сценариев, которые его используют, поэтому нужно было проверить один, чтобы написать его здесь.

Ещё вопросы

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