Подгонка полиномов с дополнительными функциями - PullRequest
0 голосов
/ 04 декабря 2018

Предположим, у меня есть массив с именем Y и другой массив с именем X.Я знаю, как подогнать полином с помощью numpy.polyfit(), и в качестве вывода я получу массив с коэффициентами.Но что, если я хочу добавить некоторую функцию f(x) в качестве дополнительного регрессора к полиному, как я могу это сделать в python?

Например Y = [1,2,3,4,5,6], X = [101,102,103,104,105,106].Я знаю, как оценить коэффициенты y = a_0+a_1x+a_2x^2+a_3x^3 (полином 3-го порядка), я могу оценить его, используя z = numpy.polyfit(Y, X, 3).Теперь я хочу оценить y = a_0+a_1x+a_2x^2+a_3x^3 + a_4f(x), где f(x) - некоторая функция.Я новичок в Python, не могу найти ответ в Google

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Вот код для графического установщика, использующий пример функции, предоставленной в ответе Гергеса Диба.Обратите внимание, что Scipy's Curve_fit () является нелинейным решателем, который требует начальных оценок параметров в качестве отправной точки, и все они имеют значение 1,0 по умолчанию, если вы сами не предоставляете.Здесь вы можете видеть, что результат подбора визуально выглядит нормально, но если бы это было не так, возможно, это произошло из-за начальных оценок параметров - это иногда случается.У Сципи есть генетический алгоритм, помогающий определить начальные оценки параметров, в этом примере это не требуется.

import numpy, scipy, matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

xData = numpy.array([19.1647, 18.0189, 16.9550, 15.7683, 14.7044, 13.6269, 12.6040, 11.4309, 10.2987, 9.23465, 8.18440, 7.89789, 7.62498, 7.36571, 7.01106, 6.71094, 6.46548, 6.27436, 6.16543, 6.05569, 5.91904, 5.78247, 5.53661, 4.85425, 4.29468, 3.74888, 3.16206, 2.58882, 1.93371, 1.52426, 1.14211, 0.719035, 0.377708, 0.0226971, -0.223181, -0.537231, -0.878491, -1.27484, -1.45266, -1.57583, -1.61717])
yData = numpy.array([0.644557, 0.641059, 0.637555, 0.634059, 0.634135, 0.631825, 0.631899, 0.627209, 0.622516, 0.617818, 0.616103, 0.613736, 0.610175, 0.606613, 0.605445, 0.603676, 0.604887, 0.600127, 0.604909, 0.588207, 0.581056, 0.576292, 0.566761, 0.555472, 0.545367, 0.538842, 0.529336, 0.518635, 0.506747, 0.499018, 0.491885, 0.484754, 0.475230, 0.464514, 0.454387, 0.444861, 0.437128, 0.415076, 0.401363, 0.390034, 0.378698])


def func(x, a0, a1, a2, a3, a4): # Gerges Dib gave this example function
    func_term = numpy.exp(-abs(x))  # can be anything you need
    return a0 + a1 * x + a2 * x**2 + a3 * x**3 + a4 * func_term


fittedParameters, pcov = curve_fit(func, xData, yData)
print('Fitted parameters:', fittedParameters)
print()

modelPredictions = func(xData, *fittedParameters) 

absError = modelPredictions - yData

SE = numpy.square(absError) # squared errors
MSE = numpy.mean(SE) # mean squared errors
RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (numpy.var(absError) / numpy.var(yData))

print()
print('RMSE:', RMSE)
print('R-squared:', Rsquared)

print()


##########################################################
# graphics output section
def ModelAndScatterPlot(graphWidth, graphHeight):
    f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
    axes = f.add_subplot(111)

    # first the raw data as a scatter plot
    axes.plot(xData, yData,  'D')

    # create data for the fitted equation plot
    xModel = numpy.linspace(min(xData), max(xData))
    yModel = func(xModel, *fittedParameters)

    # now the model as a line plot
    axes.plot(xModel, yModel)

    axes.set_xlabel('X Data') # X axis data label
    axes.set_ylabel('Y Data') # Y axis data label

    axes.set_title('Gerges Dib example function')

    plt.show()
    plt.close('all') # clean up after using pyplot

graphWidth = 800
graphHeight = 600
ModelAndScatterPlot(graphWidth, graphHeight)

example

0 голосов
/ 04 декабря 2018

scipy.optimize.curve_fit - это то, что вы ищете.Она может принимать любую произвольную функцию, и, таким образом, вы можете определить как полиномиальный член, так и дополнительный функциональный член в этой функции.

def f(x, a0, a1, a2, a3, a4):
  func_term = np.exp(-abs(x))  # can be anything you need
  return a0 + a1 * x + a2 * x**2 + a3 * x**3 + a4 * func_term

и затем подгоните кривую:

popt, _ = curve_fit(f, xdata, ydata)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...