Я использую scipy.optimize.leastsq, чтобы попытаться сопоставить ряд параметров с реальными данными при наличии шума. Целевая функция иногда вызывается с NaN изнутри minpack. Это ожидаемое поведение 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))
Якоби вычислен численно. В производственном коде оптимизация обычно работает, за исключением случаев, когда начальная оценка слишком хороша, поверхность чрезвычайно плоская, а шум подавляет дельта, используемые для численного вычисления якобиана. В этом случае остатки целевой функции выглядят как случайный шум, подобный приведенному выше примеру кода, и я не ожидал, что оптимизация сходится.
В этом примере кода небольшие значения NOISE_LEVEL (< 1e-10) всегда сходятся. В 1e-6 значение ValueError выбрасывается обычно в пределах нескольких сотен попыток.
Одним из возможных способов решения является возврат сильно оштрафованного остатка (либо NaN, либо INF), например:
v = np.empty(RETURN_LEN)
v.fill(np.nan)
return v
Это обходное решение кажется эффективным, если оно грязное. Любые лучшие альтернативы или способы предотвращения NaN в первую очередь?
Это поведение наблюдалось в Python 2.7.9 x32, работающем в Windows 7.