numpy polyfit проходя через 0



Предположим, что у меня есть векторы x и y с вектором веса wgt. Я могу вписать кубическую кривую (y = a x^3 + b x^2 + c x + d), используя np.polyfit следующим образом:



y_fit = np.polyfit(x, y, deg=3, w=wgt)


Теперь предположим, что я хочу сделать еще одну подгонку, но на этот раз я хочу, чтобы подгонка прошла через 0 (т. е. y = a x^3 + b x^2 + c x, d = 0), как я могу указать, что конкретный коэффициент (т. е. d в этом случае) равен нулю?

Спасибо

443   1  

1 ответ:

Вы можете использовать np.linalg.lstsq и построить матрицу коэффициентов вручную. Для начала я создам примеры данных x и y, а также "точное соответствие" y0:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(100)
y0 = 0.07 * x ** 3 + 0.3 * x ** 2 + 1.1 * x
y = y0 + 1000 * np.random.randn(x.shape[0])
Теперь я создам полную кубическую полиномиальную "обучающую" или "независимую переменную" матрицу, включающую столбец констант d.
XX = np.vstack((x ** 3, x ** 2, x, np.ones_like(x))).T
Давайте посмотрим, что я получу, если вычислю соответствие с этим набором данных и сравню его с polyfit:
p_all = np.linalg.lstsq(X_, y)[0]
pp = np.polyfit(x, y, 3)

print np.isclose(pp, p_all).all()
# Returns True

Где я использовал np.isclose, потому что два алгоритма действительно производят очень малые различия.

Вы, вероятно, думаете: "это хорошо, но я все еще не ответил на вопрос". Отсюда принуждение подгонки к нулевому смещению равносильно удалению столбца np.ones из массива:
p_no_offset = np.linalg.lstsq(XX[:, :-1], y)[0]  # use [0] to just grab the coefs
Хорошо, давайте посмотрим, как выглядит это соответствие по сравнению с нашими данными:
y_fit = np.dot(p_no_offset, XX[:, :-1].T)

plt.plot(x, y0, 'k-', linewidth=3)
plt.plot(x, y_fit, 'y--', linewidth=2)
plt.plot(x, y, 'r.', ms=5)

Это дает такую цифру,

Данные и подгонка.

Предупреждение: при использовании этого метода на данных, которые на самом деле не проходят через (x, y)=(0,0) вы будет смещать ваши оценки коэффициентов выходного решения (p), потому что lstsq будет пытаться компенсировать тот факт, что в ваших данных есть смещение. Своего рода проблема "квадратного колышка с круглым отверстием".

Кроме того, вы также можете поместить свои данные в кубический только , выполнив:

p_ = np.linalg.lstsq(X_[:1, :], y)[0]

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

Удачи вам!

Comments

    Ничего не найдено.