アセットマネージャーのためのファイナンス機械学習:ポートフォリオの構築 クラスタを使ったポートフォリオ構築 NCOアルゴリズム

マコーウィッツ解の不安定性は、相関行列内の支配的なクラスターに起因する。よって、この支配的なクラスターを個別に最適化することにより、この不安定性が抑制され、ポートフォリオも安定するはずである。この視点から、導入されたのが、Nested Cluster Optimization NCOである。
NCOの手順は、3つに分けられる。

相関行列のクラスタリング

 $${T/N}$$比が大きい場合、ノイズによる不安定性さを除くために、相関行列のノイズ除去を行う。ノイズ除去関数のdeNoiseCovに渡すqは、$${q=T/N}$$である。
 ノイズ除去した共分散行列をクラスタリングに渡す(スニペット7.3)

import ONC as NC
nBlocks, bSize, bCorr = 2, 2, .5
q = 10.0
np.random.seed(0)
mu0, cov0 = MP.formTrueMatrix(nBlocks, bSize, bCorr)
cols = cov0.columns
cov1 = MP.deNoiseCov(cov0, q, bWidth=.01) 
cov1 = pd.DataFrame(cov1, index=cols, columns=cols)
corr1 = MP.cov2corr(cov1)
corr1, clstrs, silh = NC.clusterKMeansBase(corr1, 
                      maxNumClusters=int(corr0.shape[0]/2),n_init=10)
clstrs
クラスタリングの結果

 単一要素のクラスタは条件数を変化させないから、考慮するのはサイズ2以上のクラスタのみである。ここで、相関行列をそのままクラスタリングするか、絶対値を取ってからクラスタリングするかの問題があるが、負の相関係数が多い場合は、両方取り、モンテカルロなどで性能を評価した方が良い。

クラスタ内のウェイト

 ノイズ除去された共分散行列cov1を元に、クラスタごとにクラスタ内での最小分散最適配分を計算し(スニペット7.4)、クラスタ間相関の新たな縮小共分散行列cov2を作成する。

wIntra = pd.DataFrame(0, index=cov0.index, columns=clstrs.keys(),dtype='float64')

for i in clstrs:
    cov=cov1.loc[clstrs[i], clstrs[i]]
    wIntra.loc[clstrs[i], i] = MP.optPort(cov).flatten()
        
cov2 = wIntra.T.dot(np.dot(cov1, wIntra))

 ここで使用しているoptPortは、最小分散ポートフォリオがデフォルトだが、引数muに平均リターンの$${\mu}$$を指定すれば、最大シャープレシオポートフォリオも得られる。

def optPort(cov, mu=None):
    inv=np.linalg.inv(cov)
    ones=np.ones(shape=(inv.shape[0],1))
    if mu is None: mu=ones
    w=np.dot(inv,mu)
    w/=np.dot(ones.T, w)
    return w

クラスタ間のウェイト

 縮小共分散行列cov2を用いて得られたクラスタ間最適配分を、クラスタ内ウエイトにかけて、各証券の最終的なウエイト(wAll0)となる(スニペット7.5)。

wInter = pd.Series(MP.optPort(cov2).flatten(), index=cov2.index)
wAll0 = wIntra.mul(wInter, axis=1).sum(axis=1).sort_index()
wAll0
各証券の最終ウエイト


この記事が気に入ったらサポートをしてみませんか?