我有几个数据点:
X = np.array([0.01,0.05,0.2,1,10,100,400,2000])
Y = np.array([623,3245.5,710564,332456,540124.5,1851657,5679457,10096844])
我希望将这些数据点适合sigmoid函数:
S=D+(A-D)/(1+(X/C)**B)
A,B,C,D
需要通过给出初始值p(A0,B0,C0,D0)
来确定四个参数。
此外,每个点应该为残差添加权重因子,从而使平方和达到全局最小值:
weight = ([100,90,80,70,60,50,40,30])
我是算法和编码方面的新手,有人可以就如何拟合这些数据提出一些想法吗?百万谢谢!
这是我的Levenberg-Maquardt代码:
from numpy import *
def function(p):
r = array([10*(p[1]-p[0]**2),(1-p[0])])
fp = dot(transpose(r),r) #= 100*(p[1]-p[0]**2)**2 + (1-p[0])**2
J = (array([[-20*p[0],10],[-1,0]]))
grad = dot(transpose(J),transpose(r))
return fp,r,grad,J
def lm(p0,tol=10**(-5),maxits=100):
nvars=shape(p0)[0]
nu=0.01
p = p0
fp,r,grad,J = function(p)
e = sum(dot(transpose(r),r))
nits = 0
while nits<maxits and linalg.norm(grad)>tol:
nits += 1
fp,r,grad,J = function(p)
H=dot(transpose(J),J) + nu*eye(nvars)
pnew = zeros(shape(p))
nits2 = 0
while (p!=pnew).all() and nits2<maxits:
nits2 += 1
dp,resid,rank,s = linalg.lstsq(H,grad)
pnew = p-dp
fpnew,rnew,gradnew,Jnew = function(pnew)
enew = sum(dot(transpose(rnew),rnew))
rho = linalg.norm(dot(transpose(r),r)-dot(transpose(rnew),rnew))
rho /= linalg.norm(dot(transpose(grad),pnew-p))
if rho>0:
update = 1
p = pnew
e = enew
if rho>0.25:
nu=nu/10
else:
nu=nu*10
update = 0
print fp, p, e, linalg.norm(grad), nu
p0 = array([-1.92,2])
lm(p0)