2016-05-25 1 views
0

Je suis en la minimisation ci-dessous:Scipy Réduire au minimum ne fonctionne pas

from scipy.optimize import minimize 
import numpy as np 
import math 
import matplotlib.pyplot as plt 

### objective function ### 
def Rlzd_Vol1(w1, S): 
    L = len(S) - 1 
    m = len(S[0]) 

    # Compute log returns, size (L, m) 
    LR = np.array([np.diff(np.log(S[:,j])) for j in xrange(m)]).T 

    # Compute weighted returns 
    w = np.array([w1, 1.0 - w1]) 
    R = np.array([np.sum(w*LR[i,:]) for i in xrange(L)]) # size L 

    # Compute Realized Vol. 
    vol = np.std(R) * math.sqrt(260) 

    return vol 

# stock prices 
S = np.exp(np.random.normal(size=(50,2))) 

### optimization ### 
obj_fun = lambda w1: Rlzd_Vol1(w1, S) 
w1_0 = 0.1 

res = minimize(obj_fun, w1_0) 
print res 


### Plot objective function ### 
fig_obj = plt.figure() 
ax_obj = fig_obj.add_subplot(111) 
n = 100 
w1 = np.linspace(0.0, 1.0, n) 
y_obj = np.zeros(n) 
for i in xrange(n): 
    y_obj[i] = obj_fun(w1[i]) 
ax_obj.plot(w1, y_obj) 
plt.show() 

La fonction objective montre un minimum évident (il est du second degré):

objective function

Mais la sortie de minimisation me dit la le minimum est à 0,1, le point initial:

minimization output

Je n'arrive pas à comprendre ce qui ne va pas. Des pensées?

Répondre

2

w1 est transmis en tant que vecteur (entrée unique) et non en tant que scalaire de la routine minimize. Essayez ce qui se passe si vous définissez w1 = np.array([0.2]) puis calculez w = np.array([w1, 1.0 - w1]). Vous verrez que vous obtenez une matrice 2x1 au lieu d'un vecteur 2 entrées. Pour que votre fonction objectif puisse gérer w1 en tant que tableau, vous pouvez simplement mettre une conversion explicite à float w1 = float(w1) comme première ligne de Rlzd_Vol1. Ce faisant, j'obtiens le minimum correct.

Notez que vous voudrez peut-être utiliser scipy.optimize.minimize_scalar à la place, surtout si vous pouvez placer là où vous serez le minimum.