Использование scipy.optimize.leastsq :
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
def sigmoid(p,x):
x0,y0,c,k=p
y = c / (1 + np.exp(-k*(x-x0))) + y0
return y
def residuals(p,x,y):
return y - sigmoid(p,x)
def resize(arr,lower=0.0,upper=1.0):
arr=arr.copy()
if lower>upper: lower,upper=upper,lower
arr -= arr.min()
arr *= (upper-lower)/arr.max()
arr += lower
return arr
# raw data
x = np.array([821,576,473,377,326],dtype='float')
y = np.array([255,235,208,166,157],dtype='float')
x=resize(-x,lower=0.3)
y=resize(y,lower=0.3)
print(x)
print(y)
p_guess=(np.median(x),np.median(y),1.0,1.0)
p, cov, infodict, mesg, ier = scipy.optimize.leastsq(
residuals,p_guess,args=(x,y),full_output=1,warning=True)
x0,y0,c,k=p
print('''\
x0 = {x0}
y0 = {y0}
c = {c}
k = {k}
'''.format(x0=x0,y0=y0,c=c,k=k))
xp = np.linspace(0, 1.1, 1500)
pxp=sigmoid(p,xp)
# Plot the results
plt.plot(x, y, '.', xp, pxp, '-')
plt.xlabel('x')
plt.ylabel('y',rotation='horizontal')
plt.grid(True)
plt.show()
выход
с сигмовидными параметрами
x0 = 0.826964424481
y0 = 0.151506745435
c = 0.848564826467
k = -9.54442292022
Обратите внимание, что для более новых версий scipy (например, 0.9) есть также функция scipy.optimize.curve_fit , которая проще в использовании, чем leastsq
.Соответствующее обсуждение подбора сигмоидов с использованием curve_fit
можно найти здесь .
Редактировать: добавлена функция resize
, так что необработанные данные можно было изменить и изменить в соответствии с любым желаемымограничивающий прямоугольник.
"ваше имя появляется как автор документации scipy"
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не автор документации scipy.Я просто пользователь и новичок в этом.Многое из того, что я знаю о leastsq
, пришло от прочтения этого урока , написанного Трэвисом Олифантом.
1.) Вызывает ли leastsq () функцию residuals (), которая затем возвращаетразница между входным y-вектором и y-вектором, возвращаемым функцией sigmoid ()?
Да!точно.
Если это так, как он учитывает разницу в длине входного y-вектора и y-вектора, возвращаемого функцией sigmoid ()?
Длины одинаковы:
In [138]: x
Out[138]: array([821, 576, 473, 377, 326])
In [139]: y
Out[139]: array([255, 235, 208, 166, 157])
In [140]: p=(600,200,100,0.01)
In [141]: sigmoid(p,x)
Out[141]:
array([ 290.11439268, 244.02863507, 221.92572521, 209.7088641 ,
206.06539033])
Одна из замечательных особенностей Numpy заключается в том, что он позволяет писать «векторные» уравнения, которые оперируют целыми массивами.
y = c / (1 + np.exp(-k*(x-x0))) + y0
может показаться, что он работает с плавающей точкой (на самом деле так и будет), но если вы сделаете x
массив с пустым фрагментом и c
, k
, x0
, y0
с плавающей точкой, то уравнение определяет y
какмассив numpy такой же формы, как x
.Таким образом, sigmoid(p,x)
возвращает пустой массив.Существует более полное объяснение того, как это работает в numpybook (требуется чтение для серьезных пользователей numpy).
2.) Похоже, я могу вызвать leastsq ()для любого математического уравнения, пока я получаю доступ к этому математическому уравнению через функцию невязок, которая в свою очередь вызывает математическую функцию.Это правда?
Правда.leastsq
пытается минимизировать сумму квадратов остатков (разностей).Он ищет пространство параметров (все возможные значения p
), ища p
, который минимизирует эту сумму квадратов.x
и y
, отправленные на residuals
, являются вашими значениями необработанных данных.Они исправлены.Они не меняются.Это p
s (параметры в сигмоидальной функции), которые leastsq
пытается минимизировать.
3.) Также я заметил, что p_guess имеет то же количество элементов, что и p.Означает ли это, что четыре элемента p_guess соответствуют по порядку соответственно значениям, возвращаемым x0, y0, c и k?
Точно так же!Как и метод Ньютона, leastsq
требуется начальное предположение для p
.Вы поставляете это как p_guess
.Когда вы видите
scipy.optimize.leastsq(residuals,p_guess,args=(x,y))
, вы можете думать, что как часть алгоритма leastsq (на самом деле алгоритм Левенбурга-Марквардта) в качестве первого прохода, leastsq вызывает residuals(p_guess,x,y)
.Обратите внимание на визуальное сходство между
(residuals,p_guess,args=(x,y))
и
residuals(p_guess,x,y)
Это может помочь вам вспомнить порядок и значение аргументов для leastsq
.
residuals
, например, sigmoid
возвращает пустой массив.Значения в массиве возводятся в квадрат, а затем суммируются.Это число, чтобы бить.p_guess
затем изменяется, так как leastsq
ищет набор значений, который минимизирует residuals(p_guess,x,y)
.
4.) Является ли p, который отправляется в качестве аргумента для residuals () и sigmoid() работает с тем же p, который будет выводиться функцией leastsq (), а функция leastsq () использует это p внутренне, прежде чем его вернуть?
Ну, не совсем так.Как вы уже знаете, p_guess
изменяется, так как leastsq
ищет значение p
, которое минимизирует residuals(p,x,y)
.p
(er, p_guess
), который отправляется на leastsq
, имеет ту же форму, что и p
, который возвращается leastsq
.Очевидно, что значения должны отличаться, если вы не чертовски догадайтесь:)
5.) Может ли p и p_guess иметь любое количество элементов, в зависимости отсложность уравнения, используемого в качестве модели, при условии, что количество элементов в p равно количеству элементов в p_guess?
Да.Я не тестировал стресс leastsq
для очень большого числа параметров, но это потрясающе мощный инструмент.