подгонка данных с помощью numpy

Позвольте мне начать с того, что я могу получить не то, что я ожидаю, и, возможно, вы можете мне помочь. У меня есть следующие данные:

>>> x
array([ 3.08,  3.1 ,  3.12,  3.14,  3.16,  3.18,  3.2 ,  3.22,  3.24,
    3.26,  3.28,  3.3 ,  3.32,  3.34,  3.36,  3.38,  3.4 ,  3.42,
    3.44,  3.46,  3.48,  3.5 ,  3.52,  3.54,  3.56,  3.58,  3.6 ,
    3.62,  3.64,  3.66,  3.68])

>>> y
array([ 0.000857,  0.001182,  0.001619,  0.002113,  0.002702,  0.003351,
    0.004062,  0.004754,  0.00546 ,  0.006183,  0.006816,  0.007362,
    0.007844,  0.008207,  0.008474,  0.008541,  0.008539,  0.008445,
    0.008251,  0.007974,  0.007608,  0.007193,  0.006752,  0.006269,
    0.005799,  0.005302,  0.004822,  0.004339,  0.00391 ,  0.003481,
    0.003095])

Теперь я хочу сопоставить эти данные, скажем, с полиномом 4-й степени. Итак, я делаю:

>>> coefs = np.polynomial.polynomial.polyfit(x, y, 4)
>>> ffit = np.poly1d(coefs)

Теперь я создаю новую сетку для значений x, чтобы оценить функцию подгонки ffit:

>>> x_new = np.linspace(x[0], x[-1], num=len(x)*10)

Когда я делаю все построение (набор данных и подгонка кривой) с помощью команды:

>>> fig1 = plt.figure()                                                                                           
>>> ax1 = fig1.add_subplot(111)                                                                                   
>>> ax1.scatter(x, y, facecolors='None')                                                                     
>>> ax1.plot(x_new, ffit(x_new))                                                                     
>>> plt.show()

Получаю следующее:

Fit_data.pngFit_data.png

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

Заранее спасибо.


person ezitoc    schedule 12.09.2013    source источник


Ответы (2)


К сожалению, np.polynomial.polynomial.polyfit возвращает коэффициенты в порядке, обратном порядку для np.polyfit и np.polyval (или, как вы использовали np.poly1d). Проиллюстрировать:

In [40]: np.polynomial.polynomial.polyfit(x, y, 4)
Out[40]: 
array([  84.29340848, -100.53595376,   44.83281408,   -8.85931101,
          0.65459882])

In [41]: np.polyfit(x, y, 4)
Out[41]: 
array([   0.65459882,   -8.859311  ,   44.83281407, -100.53595375,
         84.29340846])

В общем: np.polynomial.polynomial.polyfit возвращает коэффициенты от [A, B, C] до A + Bx + Cx^2 + ..., а np.polyfit возвращает: ... + Ax^2 + Bx + C.

Поэтому, если вы хотите использовать эту комбинацию функций, вы должны изменить порядок коэффициентов, как в:

ffit = np.polyval(coefs[::-1], x_new)

Однако в документации четко указано, что следует избегать np.polyfit, np.polyval и np.poly1d, и вместо этого использовать только новый (er) пакет.

Безопаснее всего использовать только полиномиальный пакет:

import numpy.polynomial.polynomial as poly

coefs = poly.polyfit(x, y, 4)
ffit = poly.polyval(x_new, coefs)
plt.plot(x_new, ffit)

Или, чтобы создать полиномиальную функцию:

ffit = poly.Polynomial(coefs)    # instead of np.poly1d
plt.plot(x_new, ffit(x_new))

подгонка и график данных

person askewchan    schedule 12.09.2013

Обратите внимание, что вы можете использовать класс Polynomial напрямую, чтобы выполнить подгонку и вернуть экземпляр Polynomial.

from numpy.polynomial import Polynomial

p = Polynomial.fit(x, y, 4)
plt.plot(*p.linspace())

p использует масштабированные и сдвинутые значения x для числовой стабильности. Если вам нужна обычная форма коэффициентов, вам нужно будет следовать

pnormal = p.convert(domain=(-1, 1))
person Charles Harris    schedule 22.04.2014
comment
+1 для преобразования коэффициентов, что полезно, если вам нужно выполнить некоторые вычисления с другими полиномами в домене по умолчанию. Обратите внимание, что это можно сделать напрямую в fit() методе с тем же аргументом domain. - person BenC; 03.03.2015