Как кодировать подгонку кривой доза-ответ (4PL) с помощью optimize.minimize () - PullRequest
1 голос
/ 14 октября 2019

Я хочу оптимизировать кривую доза-эффект (логистика 4 параметров), используя набор данных. Мне нужно использовать алгоритм Пауэлла, поэтому я должен использовать optimize.minimize () вместо кривой_fit или наименьших квадратов. Я написал следующий код:

import numpy as np
from scipy.optimize import minimize

ydata = np.array([0.1879, 0.4257, 0.80975, 1.3038, 1.64305, 1.94055, 2.21605, 2.3917])
xdata = np.array([40, 100, 250, 400, 600, 800, 1150, 1400])
initParams = [2.4, 0.2, 600.0, 1.0]

def logistic(params):
    A = params[0]
    B = params[1]   
    C = params[2]
    D = params[3]

    logistic4 = ((A-D)/(1.0+((xdata/C)**B))) + D
    sse = np.sum(np.square(ydata-logistic4))
    print sse

results = minimize(logistic, initParams, method='Powell')
print results

Теоретически это сводит к минимуму использование экспериментальных и теоретических наборов данных, повторяя 4 параметра, первоначально введенных с использованием алгоритма Пауэлла. Практически это не работает: он запускается, и последняя ошибка в довольно длинном списке:

TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'.

Есть идеи, как это закодировать?

1 Ответ

0 голосов
/ 14 октября 2019

Вот графический решатель Python для ваших данных и уравнения, он использует minimal () с 'Powell', а также имеет закомментированный вызов кривой_fit. Я не смог получить хорошее соответствие с исходными оценками параметров, которые вы предоставили, поэтому они закомментированы здесь и заменены моими собственными значениями. Мой поиск по уравнению подтверждает, что это превосходное уравнение для использования при моделировании этого набора данных.

plot

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

xData = numpy.array([40, 100, 250, 400, 600, 800, 1150, 1400], dtype=float)
yData = numpy.array([0.1879, 0.4257, 0.80975, 1.3038, 1.64305, 1.94055, 2.21605, 2.3917], dtype=float)


def func(xdata, A, B, C, D):
    return ((A-D)/(1.0+((xdata/C)**B))) + D

# minimize() requires a function to be minimized, unlike curve_fit()
def SSE(inParameters): # function to minimize, here sum of squared errors
    predictions = func(xData, *inParameters) 
    errors = predictions - yData
    return numpy.sum(numpy.square(errors))


#initialParameters = numpy.array([2.4, 0.2, 600.0, 1.0])
initialParameters = numpy.array([3.0, -1.5, 500.0, 0.1])


# curve fit the data with curve_fit()
#fittedParameters, pcov = curve_fit(func, xData, yData, initialParameters)

# curve fit the data with minimize()
resultObject = minimize(SSE, initialParameters, method='Powell')
fittedParameters = resultObject.x


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('Parameters:', fittedParameters)
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

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

graphWidth = 800
graphHeight = 600
ModelAndScatterPlot(graphWidth, graphHeight)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...