2014-12-14 5 views
3

В Python у меня есть функция error_p, которая вычисляет среднеквадратичную ошибку между набором наблюдаемых вероятностей (или, вернее, нормализованными частотами) и распределением Пуассона для данного среднего.Scipy.optimize.minimize возвращает неверные результаты

from scipy.stats import poisson 
import numpy as np 
from scipy.optimize import minimize 

def error_p(mu): 
    """ 
    Returns mean squared error between observed data points and Poisson distribution 
    """ 
    data = np.array([17.0,32,20,19,6,5,7,5,0,1,3,1,1,0,0,0,0,1,0,0]) 
    data = data/sum(data) 
    x = range(len(data)) 
    theory = [poisson.pmf(x, mu) for x in x] 
    error = np.mean((data - theory)**2) 
    return error 

График этой функции (error_p) в диапазоне mu значений:

enter image description here

Очевидно, что есть минимум на входной величины (мю) чуть ниже 2. Однако, когда я называю scipy.optimize.minimize так:

results = minimize(error_p, 2, tol=0.00001) 
results['x'], results['fun'] 

Я получаю

(array([ 13.86128699]), 0.007078183160196419) 

, указывающий минимум при мю = 13,86 с функцией величины ~ 0,007, тогда как, если я бегу

error_p(2) 

я получаю

0.000848142902892 

Почему scipy.optimize.minimize не найти истинного минимума?

+0

Добро пожаловать в переполнение стека! Я вложил ваше изображение и дал вам преимущество для хорошего первого вопроса - достаточно скоро вы сможете добавлять фотографии в свои собственные сообщения! – Hooked

ответ

5

Если вы используете функцию scipy.optimize.minimize_scalar вы получите ожидаемый результат:

results = minimize_scalar(error_p, tol=0.00001) 
print results['x'], results['fun'] 
>>> 1.88536329298 0.000820148069544 

Почему scipy.optimize.minimize не работает? Я предполагаю, что ваша функция error_p искажена с точки зрения numpy. Попробуйте следующее:

MU = np.linspace(0,20,100) 
error_p(MU) 

, и вы увидите, что он не работает. Ваша функция не предназначена для ввода массива входов и выплескивает массив выходов, и я думаю, что это то, что ищет минимизация.

+0

Вы правы. После консультаций с API я обнаружил, что scipy.optimize.minimize передает входные аргументы в виде массива, поэтому минимизируемая функция должна обрабатывать их как таковые. Напротив, minim_scalar передает ввод как float. В error_p, изменяя теорию = [poisson.pmf (x, mu) для x в x] до теории = [poisson.pmf (x, float (mu)) для x в x], решили проблему. – Simon

+0

Я сталкиваюсь с той же ошибкой, но я не могу использовать scipy.optimize.minimize_scalar, потому что у меня есть набор ограничений. Любая идея о том, как объяснить это? – DGMS89

5

Изменить

theory = [poisson.pmf(x, mu) for x in x] 

в

theory = poisson.pmf(x, mu) 

и она работает, как ожидалось.

+0

Это хорошо сочетается с моим ответом - ваше исправление, мое объяснение. – Hooked

+0

Спасибо! В общем, я думаю, проблема заключается в том, что optimize.minimize обрабатывает входные функции как массив, поэтому минимизируемая функция должна иметь возможность обрабатывать тип np.ndarray. Я ожидал, что это будет подчеркнуто в документах SciPy. – Simon

Смежные вопросы