2

Я пытаюсь извлечь параметры распределения Weibull (форма 'k' и масштаб lambda), которые удовлетворяют определенному среднему значению и дисперсии. В этом примере среднее составляет 4, а дисперсия - 8. Это проблема типа 2-неизвестных и 2-уравнений.Использование SCIPY.OPTIMIZE.FMIN_CG для извлечения параметров распределения Weibull

Поскольку этот алгоритм работает с GRG Solver Excel 2010, я уверен, что речь идет о том, как я создаю проблему или, возможно, библиотеки, которые я использую. Я не слишком хорошо знаком с библиотеками оптимизации, поэтому, пожалуйста, дайте мне знать, где ошибка.

Ниже приведен сценарий:

from scipy.optimize import fmin_cg 
import math 

def weibull_mu(k, lmda):     #Formula can be found on wikipedia 
    return lmda*math.gamma(1+1/k) 
def weibull_var(k, lmda):     #Formula can be found on wikipedia 
    return lmda**2*math.gamma(1+2/k)-weibull_mu(k, lmda)**2 

def min_function(arggs): 
    actual_mean = 4       # specific to this example 
    actual_var = 8       # specific to this example 
    k = arggs[0] 
    lmda = arggs[1] 
    output = [weibull_mu(k, lmda)-(var_wei)] 
    output.append(weibull_var(k, lmda)-(actual_var)**2-(actual_mean)**2) 
    return output 

print fmin(min_function, [1,1]) 

Этот скрипт дает мне следующую ошибку:

[...] 
    File "C:\Program Files\Python27\lib\site-packages\scipy\optimize\optimize.py", line 278, in fmin 
    fsim[0] = func(x0) 
ValueError: setting an array element with a sequence. 

ответ

2

Мне удалось заставить его работать благодаря комментарию Андерса Густафссона (спасибо). Этот скрипт теперь работает, если вы возвращаете только скаляр (в этом случае я использовал что-то по строкам наименьших квадратов). Кроме того, были добавлены ограничения, изменив функцию оптимизации на «fmin_l_bfgs_b» (опять же, благодаря Андерсу Густафссону).

Я только изменил определение min_function относительно вопроса.

from scipy.optimize import fmin_l_bfgs_b 
import math 

def weibull_mu(k, lmda): 
    return lmda*math.gamma(1+1/k) 
def weibull_var(k, lmda): 
    return lmda**2*math.gamma(1+2/k)-weibull_mu(k, lmda)**2 

def min_function(arggs): 
    actual_mean = 4.     # specific to this example 
    actual_var = 8.      # specific to this example 
    k = arggs[0] 
    lmda = arggs[1] 
    extracted_var = weibull_var(k, lmda) 
    extracted_mean = weibull_mu(k, lmda) 
    output = (extracted_var - actual_var)**2 + (extracted_mean - actual_mean)**2 
    return output 

print fmin_l_bfgs_b(min_function, best_guess, approx_grad = True, bounds = [(.0000001,None),(.0000001,None)], disp = False) 

Примечание: Пожалуйста, не стесняйтесь использовать этот скрипт для собственного или профессионального использования.

+0

Если вы хотите применить границы, используйте, например, [fmin_l_bfgs_b] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html), что позволяет установить границы ваших переменных. Кроме того, если вы нашли мой ответ полезным, не стесняйтесь его повышать :-) –

+0

Я бы с удовольствием, но я, видимо, должен иметь 15 репутации. Кроме того, fmin_l_bfgs также дает мне ошибку: Файл «C: \ Program Files \ Python27 \ lib \ site-packages \ scipy \ optimize \ lbfgsb.py», строка 150, в func_and_grad f, g = func (x, * args) ТипError: объект «numpy.float64» не итерируется – TimY

+0

Типичный :-) При взгляде на список аргументов кажется, что вам нужно установить аргумент 'approx_grad'' True'. Если вы этого не сделаете, нужно определить 'fprime' или градиент должен быть включен в возвращаемое значение из' func'. Помогает ли это? –

3

Насколько я могу судить, min_function возвращает многомерный список, но fmin и fmin_cg что объектная функция возвращает скаляр, если я не ошибаюсь.

Если вы ищете корень проблемы с двумя уравнениями, я полагаю, что вместо этого вы применяете функцию root. Насколько мне удалось выяснить, scipy не предоставляет общих оптимизаторов для векторных функций.

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

  • Нет связанных вопросов^_^