Python最小化带列的最小化

时间:2014-05-04 16:29:32

标签: python arrays mathematical-optimization

请原谅,但我最近开始使用Python ...和代码。 我在python中遇到了一些优化问题... 我想确定residual_x中定义的多项式的系数k0,k1 ...与向量" T"的数据。对于每列2D阵列" test" (例如这里有3列),是否可能?并将结果存储为2D数组。

正如您所看到的,我只针对数据列表。

非常感谢你的帮助!!!

import numpy as np
import scipy
import pylab 
from scipy.optimize import leastsq

T = np.arange(5,56,5)
T = np.reshape(T,(11,1))

test = np.array([[  3051.11,   2984.85,   3059.17],
       [  3510.78,   3442.43,   3520.7 ],
       [  4045.91,   3975.03,   4058.15],
       [  4646.37,   4575.01,   4662.29],
       [  5322.75,   5249.33,   5342.1 ],
       [  6102.73,   6025.72,   6127.86],
       [  6985.96,   6906.81,   7018.22],
       [  7979.81,   7901.04,   8021.  ],
       [  9107.18,   9021.98,   9156.44],
       [ 10364.26,  10277.02,  10423.1 ],
       [ 11776.65,  11682.76,  11843.18]])

k0 = 100.
k1 = 100.
k2 = 1.
k3 = 1.
k4 = 1.
k5 = 10.

def residual_x(vars, T, donnees):
    k0 = vars[0]
    k1 = vars[1]
    k2 = vars[2]
    k3 = vars[3]
    k4 = vars[4]
    k5 = vars[5]
    modele = T**5*k0+T**4*k1+T**3*k2+T**2*k3+T*k4+k5
    return (donnees-modele)

vars = [k0, k1, k2, k3, k4, k5]
out_x = leastsq(residual_x, vars, args=(T, test),epsfcn=0.001)

1 个答案:

答案 0 :(得分:1)

我认为你试图将三个不同的5度多项式与一组共同的域点{5,10,15,...,55}拟合到三个不同的范围集(列中的test)。

您的原始代码存在缩进错误:来自k0 = 100.并且向下缩进错误;这可能是一个剪切和粘贴错误。

更重要的是,您需要单独拟合每个多项式,因此您应该为每列调用scipy.optimize.leastsq。这对于for循环来说是最容易的(参见代码)。您还需要收集每个多项式的系数;你可以用3x6阵列做到这一点;我在下面的示例中使用了一个列表。

编辑:当我回答这个问题时,我专注于让你的代码工作,所以我完全忘记了拟合多项式系数不需要非线性求解器。你应该看看numpy.polyfit,它是围绕多项式系数的最小二乘线性求解器的便利包装器。您可以找到更多in the numpy docsat Wikipedia,并且我已将numpy.polyfit的示例用法添加到以下示例中。

import numpy as np
from scipy.optimize import leastsq

T = np.arange(5,56,5)

test = np.array([[  3051.11,   2984.85,   3059.17],
                 [  3510.78,   3442.43,   3520.7 ],
                 [  4045.91,   3975.03,   4058.15],
                 [  4646.37,   4575.01,   4662.29],
                 [  5322.75,   5249.33,   5342.1 ],
                 [  6102.73,   6025.72,   6127.86],
                 [  6985.96,   6906.81,   7018.22],
                 [  7979.81,   7901.04,   8021.  ],
                 [  9107.18,   9021.98,   9156.44],
                 [ 10364.26,  10277.02,  10423.1 ],
                 [ 11776.65,  11682.76,  11843.18]])


k0 = 100.
k1 = 100.
k2 = 1.
k3 = 1.
k4 = 1.
k5 = 10.

def residual_x(vars, T, donnees):
    k0 = vars[0]
    k1 = vars[1]
    k2 = vars[2]
    k3 = vars[3]
    k4 = vars[4]
    k5 = vars[5]
    modele = T**5*k0+T**4*k1+T**3*k2+T**2*k3+T*k4+k5
    return donnees-modele

vars = [k0, k1, k2, k3, k4, k5]
coeffs=[]

for i in range(test.shape[1]):
#EDIT: previously appended the complete output of leastsq to coeffs list
#      this is wrong; leastsq returns two outputs (i.e., a tuple)
#      and we're only really interested in the coefficients
    thiscoeffs,_=leastsq(residual_x, vars, args=(T, test[:,i]),epsfcn=0.001)
    coeffs.append(thiscoeffs)

for i in range(test.shape[1]):
    print 'poly[%d] coeffs: %s' % (i,str(coeffs[i]))

# try first example with numpy.polyfit
coeffs2 = np.polyfit(T,test[:,0],5)
print 'np.polyfit for case 0: %s',str(coeffs2)

#EDIT: this added in second edit
# if you want coeffs as an array, you could convert the list like this
coeffs_array=np.asarray(coeffs)
# or you could make coeffs a numpy array in the first place

这给[编辑:添加了coeffs2溶液]

poly[0] coeffs: (array([ -9.70769231e-07,   1.56254079e-04,   5.27449301e-03,
         1.03258957e+00,   7.62019210e+01,   2.64248394e+03]), 3)
poly[1] coeffs: (array([ -1.37025641e-06,   2.10074592e-04,   2.49477855e-03,
         1.09748240e+00,   7.51708855e+01,   2.58007182e+03]), 2)
poly[2] coeffs: (array([ -1.09435897e-06,   1.58983683e-04,   5.97712121e-03,
         1.01704522e+00,   7.67132035e+01,   2.64824061e+03]), 3)
np.polyfit for case 0: %s [ -9.70769231e-07   1.56254079e-04   5.27449301e-03   1.03258957e+00
   7.62019210e+01   2.64248394e+03]