2つの仕事:最も低い点を探す、曲線がゼロを横切る点を探す
scipy.optimize は2種類の問題を解きます。1つ目は関数 f(x) の最小化、つまり出力が最も小さくなる入力を探すことです。minimize(f, x0) を呼び、x0 は最初の推測値です。BFGS は f の勾配に沿って下ります。Nelder-Mead は勾配が要らず、値を比べるだけです。SLSQP は、合計が1になる重みのような境界や制約も扱えます。答えは局所的な最小値、つまり出発した谷の底にすぎず、別の x0 なら別の答えになりえます。必ず res.success を確認してください。
2つ目の問題は根探し、つまり g(x)=0 を解くことです。brentq(g, a, b) は、両端で g の符号が逆になる区間(挟み込み)を必要とし、区間を何度も半分にして必ず根を見つけます。n 回半分にすると区間の幅は (b−a)/2n です。newton(g, x0, fprime) は g の傾きを使うのではるかに速いですが、良い出発点が必要で、傾きがほぼ平らだと遠くへ飛ぶことがあります。金融では債券の最終利回りが根です。債券の価格式を市場価格に等しくする利率 y のことです。ニュートン法の1歩は y新=y−g(y)/g′(y) です。
ynew=y−g′(y)g(y),g(y)=1+y5+(1+y)2105−98,width after n halvings=2nb−a(1) 2年債の利回りある債券は1年後に
5、2年後に
105 を支払い、価格は
98 です。
y=6% から始めます。価格式は
98.17 なので
g=0.17、傾きは
g′=−5/1.062−210/1.063=−180.8 です。ニュートン法の1歩で
y=0.06−0.17/(−180.8)=6.092% となり、区間
[0,0.5] の
brentq は根
6.0923% を確認します。区間
[0,1] の二分法で誤差を
0.001 以内にするには
2n≥1000 なので
n=10 回です。最小化の例として、ボラティリティが
20 と
10、相関が
0.2 の2資産の共分散は
40 で、最小分散の第1資産の重みは
(100−40)/(400+100−80)=0.143 です。実データでは、2005年2月からの
5,404 日で、SPYとTLTの年率ボラティリティは
19.0% と
14.6%、相関は
−0.30 です。最小分散のSPYの重みは
40% で、ボラティリティは
9.7% になります。谷が2つある関数
x4−3x2+x では、
minimize は
x0=2 から
1.13、
x0=−2 から
−1.30(より低い方)で止まります。
- 最小化か求解か:
minimize は低い点を、brentq と newton は関数がゼロになる点を探す。 - 挟み込みは保証:符号が違えば
brentq は必ず収束し、newton は速いが良い出発点が要る。 - 最小値は局所的かもしれない:複数の出発点を試し、
res.x を信じる前に res.success を読む。
ラボ:採点される内容
- ニュートン法の1歩15点
- 二分法の分割回数10点
- 最小分散の重み15点
- 仕事ごとの適切な道具15点
- インプライド・ボラティリティの手順10点
- 局所的かもしれない最小値10点
- なぜ挟み込みか、なぜニュートン法は失敗しうるか25点