Оптимизация параметров с использованием Минимизации в Python

#python #matlab #optimization #scipy #minimize

Вопрос:

Я написал следующие две функции для калибровки модели :

Основная функция заключается в:

 def function_Price(para,y,t,T,tau,N,C):  
# y= price array
# C = Auto and cross correlation array
# a= paramters need to be calibrated
    a=para[0:]
    temp=0
    for j in range(N):
        price_j = a[j]*C[j]*P[t:T-tau,j]
        temp=temp price_j
        Price=temp
        return Price 
 

Целевая функция заключается в :

 def GError_function_Price(para,y,k,t,T,tau,N,C):
# k is the price need to be fitted
   return sum((function_Price(para,y,t,T,tau,N,C)-k[t tau:T]) ** 2)
 

Теперь я вызываю эти две функции для оптимизации модели:

 import numpy as np
from scipy.optimize import minimize
 
# Prices (example)
y = np.array([[1,2,3,4,5,4], [4,5,6,7,8,9], [6,7,8,7,8,6], [13,14,15,11,12,19]])

# Correaltion (example)
Corr= np.array([[1,2,3,4,5,4], [4,5,6,7,8,9], [6,7,8,7,8,6], [13,14,15,11,12,19],[1,2,3,4,5,4],[6,7,8,7,8,6]])

# Define 
tau=1
Size = y.shape
N = Size[1]
T = Size[0]
t=0

# initial Values
para=np.zeros(N) 

# Bounds
B = np.zeros(shape=(N,2)) 
for n in range(N):
    B[n][0]= float('-inf')
    B[n][1]= float('inf')

# Calibration 
A = np.zeros(shape=(N,N))  
for i in range (N):
    k=y[:,i] #fitted one
    C=Corr[i,:]
    parag=minimize(GError_function_Price,para,args=(y,Y,t,T,tau,N,C),method='SLSQP',bounds=B)
    A[i,:]=parag.x
 

Как только я запущу модель, она должна создать массив N на N оптимизированных значений параметров. Но, за исключением первого столбца, он сохраняет нули для остальных. Что — то не так.

Не могли бы вы помочь мне решить эту проблему, пожалуйста?

Я знаю, как это делается в Matlab.

Ниже приведен код Matlab : основная функция

 function Price=function_Price(para,P,t,T,tau,N,C)  
        a=para(:,:);
        temp=0;
       for j=1:N
        price_j = a(j).*C(j).*P(t:T-tau,j);
        temp=temp price_j;
       end
      Price=temp;
end
 

Целевая функция:

 function gerr=GError_function_Price(para,P,Y,t,T,tau,N,C)
gerr=sum((function_Price(para,P,t,T,tau,N,C)-Y(t tau:T)).^2);
end
 

Теперь я вызываю эти две функции следующим образом:

 P = [1,2,3,4,5,4;4,5,6,7,8,9;6,7,8,7,8,6;13,14,15,11,12,19];
AutoAndCrossCorr= [1,2,3,4,5,4;4,5,6,7,8,9;6,7,8,7,8,6;13,14,15,11,12,19;1,2,3,4,5,4;6,7,8,7,8,6];

tau=1;
Size = size(P);
N =6;
T =4;
t=1;   

for i=1:N
Y=P(:,i); % fitted one
C=AutoAndCrossCorr(i,:);
para=zeros(1,N);
lb= repmat(-inf,N,1);
ub= repmat(inf ,N,1);
parag=fminsearchbnd(@(para)abs(GError_function_Price(para,P,Y,t,T,tau,N,C)),para,lb,ub);
a(i,:)=parag;
end
 

Ответ №1:

Проблема, по-видимому, в том, что вы передаете результат вызова функции для минимизации, а не саму функцию. Аргументы передаются с помощью параметра args. Так что вместо:

 minimize(GError_function_Price(para,y,k,t,T,tau,N,C),para,method='SLSQP',bounds=B)
 

должно сработать следующее

 minimize(GError_function_Price,para,args=(y,k,t,T,tau,N,C),method='SLSQP',bounds=B)
 

Комментарии:

1. Привет @eeegnu, спасибо за предложение. После исправления аргумента, как вы сказали, теперь появляется следующая ошибка: Ошибка ValueError: Целевая функция должна возвращать скаляр

2. @MMKarim Я заметил, что вы не добавили оператор return в опубликованную вами целевую функцию. Вы возвращаете gerr (если он не возвращает ничего)?

3. Привет @eeegnu, еще раз спасибо. Я отредактировал код в соответствии с вашим предложением. Вы можете увидеть код в отредактированной версии моего вопроса. Теперь он работает. Однако это должно дать мне оптимизированный параметр массива (N на N), содержащего оптимизированные значения. Но, за исключением первого столбца, он дает нули другим. Что — то не так.

4. @MMKarim, вам, вероятно, следует сохранить ошибку в своем сообщении, чтобы не смущать будущих читателей вашего вопроса! Немного сложно сказать, в чем причина вашей проблемы, но можно предположить, что вы передаете один и тот же x0 (пункт) на каждом шаге, который выглядит как проблема.

5. Привет @eeegnu. Я нашел проблему. Проблема заключается в отступе. Последняя строка позиции основной функции return Price должна совпадать с позицией for-loop. Теперь я ставлю его чуть ниже Price=temp , из-за этого он повторяет те же результаты , а не следует циклу for. В Matlab такой проблемы нет, я не знал о проблеме отступа.