2012-03-12 13 views
0

私はScipy.optimize.leastsqを使って関数に適合したいtimeseriesを持っています。Python:フィットパラメータの副条件との最小二乗適合

fitfunc= lambda a, x:  a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x /a[6])  
errfunc lambda a,x,y:  fitfunc(a,x) - y 

次に、最小限に抑えるためにerrfuncをleastsqに渡します。私が使用するフィット関数は、異なるタイムスケールa(4:6)と異なる重み(a(0:4))で減衰する指数の合計です。 (sideuqestionとして:1つ以上のパラメータ配列でleastsqを使うことができますか?私はそうしていませんでした....)

質問:どのように追加の条件を、関数。 = 1.0

答えて

3

ちょうど

import numpy as np 

def fitfunc(p, x): 
    a = np.zeros(7) 
    a[1:7] = p[:6] 
    a[0] = 1 - a[1:4].sum() 
    return a[0] + a[1]*exp(-x/a[4]) + a[2]*exp(-x/a[5]) + a[3]*exp(-x/a[6]) 

def errfunc(p, x, y1, y2): 
    return np.concatenate((
     fitfunc(p[:6], x) - y1, 
     fitfunc(p[6:12], x) - y2 
    )) 

を使用する一般的に、ラムダ関数が悪いスタイルと考えられている(そして、彼らはあなたのコードには何も追加しないでください):私は(4)(0)は、例えばその合計をしたいです。最小二乗フィットでいくつかの関数を使用するには、np.concatenateを使って指定した関数を追加するだけです。しかし、いずれのパラメータも相関していなければ、それほど意味をなさない。アルゴリズムの収束を遅くするだけです。あなたが要求した副条件は、与えた制約に基づいて1つの重みを計算するだけで実装されます(1 - a [1:4] .sum()を参照)。

0

制約の式を解くことができず、ある許容誤差で満たされている制約条件を満たすことができれば、別の方法として、大きな重みを持つカイ二乗に項を追加して、制約ほぼ満足している。

例:あなたは、\合計(罪(P [i])と== 1、あなたは次のことを行うことができます必要がある場合:

constraint_func = lambda a: sin(a).sum()-1 

def fitfunc (a,x): 
    np.concatenate((a[0]+a[1]*exp(-x/a[4])+a[2]*exp(-x/a[5])+a[3]*exp(-x /a[6]), 
        [constraint_func(a)])) 

def errfunc(a,x,y): 
    tolerance = 1e-10 
    return np.concatenate((fitfunc(a,x) - y, [tolerance])) 

明らかに収束が遅くなりますが、それでも保証されます