2015-03-31 27 views
13
ile hedef işlevi çağırıyor

Gürültü varlığında gerçek dünya verilerine bir dizi parametreyi sığdırmayı denemek için scipy.optimize.leastsq kullanıyorum. Amaca yönelik işlev, zaman zaman, mini paketin içinden NaN'ler ile çağrılır. Bu scipy.optimize.leastsq beklenen davranış mı? Bu durumda NaN tortularını geri döndürmekten daha iyi bir seçenek var mı?scipy.optimize.leastsq, NaN

import scipy.optimize 
import numpy as np 

xF = np.array([1.0, 2.0, 3.0, 4.0]) # Target value for fit 
NOISE_LEVEL = 1e-6 # The random noise level 
RETURN_LEN = 1000 # The objective function return vector length 

def func(x): 
    if np.isnan(np.sum(x)): 
     raise ValueError('Invalid x: %s' % x) 
    v = np.random.rand(RETURN_LEN) * NOISE_LEVEL 
    v[:len(x)] += xF - x 
    return v 

iteration = 0 
while (1): 
    iteration += 1 
    x = np.zeros(len(xF)) 
    y, cov = scipy.optimize.leastsq(func, x) 
    print('%04d %s' % (iteration, y)) 

Jakobiyeni sayısal bilgisayarlı ediliyor:

Aşağıdaki kod davranışı gösterir. Üretim kodunda, optimizasyon normalde başlangıç ​​tahmininin çok iyi olduğu durumlar dışında çalışır, yüzey aşırı derecede düzdür ve gürültü, Jacobian'ı sayısal olarak hesaplamak için kullanılan deltaları alt eder. Bu durumda, hedef fonksiyonun kalıntıları, yukarıdaki kod örneği gibi rastgele bir gürültü gibi görünür ve optimizasyonun yakınsamasını beklemezdim.

Bu kod örneğinde, küçük NOISE_LEVEL değerleri (< 1e-10) her zaman birleşir. 1e-6'da, ValueError tipik olarak birkaç yüz denemede atılır.

v = np.empty(RETURN_LEN) 
v.fill(np.nan) 
return v 

Bu çözüm kirli ise etkili görünmektedir:

olası bir çözüm gibi, bir yüksek ceza kalıntı (NaN veya INF olarak) döndürmektir. NaN'leri ilk etapta önlemek için daha iyi alternatifler veya yollar?

Bu davranış 2.7.9 x32

+6

görünüyor NaNlerde. Bu, optimize edicinin güvenilir sonuçlar sağlayamadığının güçlü bir göstergesidir. Bu genellikle optimizasyon probleminin yeniden oluşturulmasını, ek kısıtlamalar getirerek, daha az gösterişli hale getirilmesini gerektirir. Belki de kısıtlı bir optimizer (https://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html#constrained-minimization-of-multivariate-scalar-functions-minimize) kullanmak olası bir çözüm olabilir. Ayrıca fesih koşullarının gevşetilmesi yardımcı olabilir. – Dietrich

cevap

4

senin sorunun tanımı doğrusal olmayan bir sorun (gürültü) üzerinde doğrusal bir çözücü kullanan yana Windows 7 üzerinde çalışan Python altında gözlendi, çözücü gürültü sürece, kafayı seviye, fark edilebilirlik eşiğinin altındadır.

Bu sorunu çözmek için doğrusal olmayan bir çözücü kullanmayı deneyebilirsiniz. çıktı olarak

import scipy.optimize 
import numpy as np 

xF = np.array([1.0, 2.0, 3.0, 4.0]) # Target value for fit 
NOISE_LEVEL = 1.e-6 # The random noise level 
RETURN_LEN = 1000 # The objective function return vector length 

def func(x): 
    if np.isnan(np.sum(x)): 
     raise ValueError('Invalid x: %s' % x) 
    v = np.random.rand(RETURN_LEN) * NOISE_LEVEL 

    v[:len(x)] += xF - x 

    return v[:len(x)] 

iteration = 0 
while iteration < 10: 
    iteration += 1 
    x = np.random.rand(len(xF)) 
    y = scipy.optimize.broyden1(func, x) 
    print('%04d %s' % (iteration, y)) 

döner: leastsq yerine broyden1 çözme algoritması kullanarak Örneğin gürültü ve sayısal Jacobian kombinasyonu sonuçlanan yolu kapalı bölgeye x vuruyor böyle

0001 [ 1.00000092 2.00000068 3.00000051 4.00000097] 
0002 [ 1.0000012 2.00000214 3.00000272 4.00000369] 
0003 [ 0.99999991 1.99999931 2.99999815 3.9999978 ] 
0004 [ 1.00000097 2.00000198 3.00000345 4.00000425] 
0005 [ 1.00000047 1.99999983 2.99999938 3.99999922] 
0006 [ 1.00000024 2.00000021 3.00000071 4.00000136] 
0007 [ 1.00000116 2.00000102 3.00000225 4.00000357] 
0008 [ 1.00000006 2.00000002 3.00000017 4.00000039] 
0009 [ 1.0000002 2.00000034 3.00000062 4.00000051] 
0010 [ 1.00000137 2.0000015 3.00000193 4.00000344]