2016-05-25 22 views
0
Arbeiten

ich die Minimierung unter renne:Scipy minimieren Nicht

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() 

Die Zielfunktion ein offensichtliches Minimum zeigt (es ist quadratisch):

objective function

Aber die Minimierung Ausgabe sagt mir die minimal ist, bei 0,1, der Anfangspunkt:

minimization output

Ich kann nicht herausfinden, was falsch läuft. Irgendwelche Gedanken?

Antwort

2

w1 wird als ein (einzelner Eintrag) Vektor und nicht als Skalar von der minimize Routine übergeben. Versuchen Sie, was passiert, wenn Sie w1 = np.array([0.2]) definieren und dann w = np.array([w1, 1.0 - w1]) berechnen. Sie werden sehen, dass Sie eine 2x1-Matrix anstelle eines 2-Eintragsvektors erhalten.

Damit Ihre Zielfunktion w1 als Array handhaben kann, können Sie einfach eine explizite Konvertierung in float w1 = float(w1) als erste Zeile von Rlzd_Vol1 vornehmen. Dadurch erhalte ich das richtige Minimum.

Beachten Sie, dass Sie stattdessen lieber scipy.optimize.minimize_scalar verwenden möchten, wenn Sie in der Lage sind, dort einzugrenzen, wo Sie mindestens sein werden.