Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python scipy智能优化_Python_Optimization_Scipy - Fatal编程技术网

Python scipy智能优化

Python scipy智能优化,python,optimization,scipy,Python,Optimization,Scipy,我需要用直线拟合不同数据集中的一些点。从每个数据集中,我想拟合一条直线。所以我得到了描述I线的参数ai和bi:ai+bi*x。问题是我想强制每个ai都是平等的,因为我想要相同的拦截器。我在这里找到了一个教程:。不同的是我不知道我有多少数据集。我的代码是: from numpy import * from scipy import optimize # here I have 3 dataset, but in general I don't know how many dataset are

我需要用直线拟合不同数据集中的一些点。从每个数据集中,我想拟合一条直线。所以我得到了描述I线的参数ai和bi:ai+bi*x。问题是我想强制每个ai都是平等的,因为我想要相同的拦截器。我在这里找到了一个教程:。不同的是我不知道我有多少数据集。我的代码是:

from numpy import *
from scipy import optimize

# here I have 3 dataset, but in general I don't know how many dataset are they
ypoints = [array([0, 2.1, 2.4]),    # first dataset, 3 points
           array([0.1, 2.1, 2.9]),  # second dataset
           array([-0.1, 1.4])]      # only 2 points

xpoints = [array([0, 2, 2.5]),      # first dataset
           array([0, 2, 3]),        # second, also x coordinates are different
           array([0, 1.5])]         # the first coordinate is always 0

fitfunc = lambda a, b, x: a + b * x
errfunc = lambda p, xs, ys: array([ yi - fitfunc(p[0], p[i+1], xi) 
                                    for i, (xi,yi) in enumerate(zip(xs, ys)) ])


p_arrays = [r_[0.]] * len(xpoints)
pinit = r_[[ypoints[0][0]] + p_arrays]
fit_parameters, success = optimize.leastsq(errfunc, pinit, args = (xpoints, ypoints))
我得到

回溯(最近一次呼叫最后一次):
文件“prova.py”,第19行,在
fit_参数,success=optimize.leastsq(errfunc,pinit,args=(xpoints,ypoints))
文件“/usr/lib64/python2.6/site packages/scipy/optimize/minpack.py”,第266行,在leastsq中
m=检查函数(func,x0,args,n)[0]
文件“/usr/lib64/python2.6/site packages/scipy/optimize/minpack.py”,第12行,在check\u func中
res=至少1d(thefunc(*(x0[:numput],)+args)))
文件“prova.py”,第14行,在
对于枚举(zip(xs,ys))]中的i(xi,yi)
ValueError:使用序列设置数组元素。
(旁注:使用
def
,而不是
lambda
分配给一个名字——这完全是愚蠢的,而且只有缺点,
lambda
的唯一用途是使用匿名功能!)


您的
errfunc
应该返回一个浮点数序列(数组或其他),但它不是,因为您试图将每个
y
点(请记住,
ypoints
aka
ys
是数组列表!)和fit函数结果的差异数组作为数组项。因此,您需要将表达式
yi-fitfunc(p[0],p[i+1],xi)
压缩为单个浮点数,例如
norm(yi-fitfunc(p[0],p[i+1],xi))
如果您只需要线性拟合,那么最好使用线性回归而不是非线性优化器进行估计。 可以使用scikits.statsmodels获得更合适的统计数据

import numpy as np
from numpy import array

ypoints = np.r_[array([0, 2.1, 2.4]),    # first dataset, 3 points
           array([0.1, 2.1, 2.9]),  # second dataset
           array([-0.1, 1.4])]      # only 2 points

xpoints = [array([0, 2, 2.5]),      # first dataset
           array([0, 2, 3]),        # second, also x coordinates are different
           array([0, 1.5])]         # the first coordinate is always 0

xp = np.hstack(xpoints)
indicator = []
for i,a in enumerate(xpoints):
    indicator.extend([i]*len(a))

indicator = np.array(indicator)


x = xp[:,None]*(indicator[:,None]==np.arange(3)).astype(int)
x = np.hstack((np.ones((xp.shape[0],1)),x))

print np.dot(np.linalg.pinv(x), ypoints)
# [ 0.01947973  0.98656987  0.98481549  0.92034684]
回归系数矩阵有一个共同的截距,但每个数据集有不同的列:

>>> x
array([[ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  2. ,  0. ,  0. ],
       [ 1. ,  2.5,  0. ,  0. ],
       [ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  0. ,  2. ,  0. ],
       [ 1. ,  0. ,  3. ,  0. ],
       [ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  0. ,  0. ,  1.5]])

我不明白这两个例子之间的区别link@Wiso,该代码相当晦涩(带有一个未记录的
r\uu
,等等),但我确信它最终会从errfunc返回一个浮点数序列,因为这是文档所需要的--使用调试器检查或使用
打印
工具进行验证,如果你能自己成功地运行代码(我不能——什么是
r
?)。好的,我解决了。通常,scipy有很好的文档记录,这里的
r
函数:解决方案是将
array
更改为
concatenate
,以获得您所说的唯一数组。特别是我得到了系数:
[0.01947973 0.98656987 0.98481549 0.92034684]
它们似乎是正确的汉克斯,我喜欢它。问题是现在我需要使用误差,我的意思是:y点有误差,我需要用1/error^2来加权它们。如何使用您的代码?最好使用scikits.statsmodels,因为在这种情况下,您需要预先准备所有的估计、预测和结果统计信息。以及获取预测y参数=np.dot(np.linalg.pinv(x),ypoints)ypred=np.dot(x,params)errors=ypoints-ypred的链接。。。如果您的意思是通过对误差进行加权来使用加权最小二乘法,那么x和Y点都需要除以误差标准偏差,或者使用scikets.statsmodels中的WLS类。
>>> x
array([[ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  2. ,  0. ,  0. ],
       [ 1. ,  2.5,  0. ,  0. ],
       [ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  0. ,  2. ,  0. ],
       [ 1. ,  0. ,  3. ,  0. ],
       [ 1. ,  0. ,  0. ,  0. ],
       [ 1. ,  0. ,  0. ,  1.5]])