アセットマネージャーのためのファイナンス機械学習:ノイズ除去 ノイズを含んだサンプルデータ
市場観測データからなる相関行列は、何かの情報を持っているシグナルとランダムなシグナルからくるノイズが混ざっている。
Marchenko-Pasturの確率密度関数に当てはまるのはこのうちのノイズであることから、カットオフの固有値$${\lambda_{+}}$$を求められる。
このノイズ除去を実装するために、サンプルデータのランダム変数とシグナルを含んでいる完全にランダムでない共分散行列を、スニペット2.3で作成する。
共分散行列の$${nCol}$$個のランダム変数の内、$${nFact}$$個がシグナルを含み、ノイズは$${\alpha}$$の重みで、シグナルは$${1-\alpha}$$の重みで足し合わされ、サンプルデータの共分散行列とされる。
def getRndCov(nCols, nFacts):
w=np.random.normal(size=(nCols,nFacts))
cov=np.dot(w,w.T)
cov+=np.diag(np.random.uniform(size=nCols))
return cov
def cov2corr(cov):
std=np.sqrt(np.diag(cov))
corr=cov/np.outer(std,std)
corr[corr<-1],corr[corr>1] = -1,1
return corr
alpha,nCols, nFact,q=0.995,1000,100,10
cov=np.cov(np.random.normal(size=(nCols*q,nCols)),rowvar=0)
cov=alpha*cov+(1-alpha)*getRndCov(nCols,nFact)
corr0=cov2corr(cov)
eVal0,eVec0=getPCA(corr0)
ここで、cov2corrは共分散行列から相関行列を作る関数で、まず最初の正規分布乱数で作られている$${1000\times10, 1000}$$行列の共分散行列と相関行列は同じ($${\sigma^2=1}$$)であっても、getRndCovで作られている共分散行列は、明らかに相関行列と同じにはならない。ゆえに、ここで分散を計算し直して、相関行列にする必要がある。
ノイズが重み$${\alpha}$$で、シグナルの共分散行列が$${1-\alpha}$$で足されているこの共分散行列の相関行列の固有値分布は、以下のようになる。
getPCA()は、スニペット2.2で与えられている関数で、行列から固有値と固有ベクトルを取得し、固有値を降順にソートして、固有値とペアになっている固有ベクトルも固有値順にし、固有値はnp.diagflat()で2次元対角行列にして返す。
def getPCA(matrix):
eVal,eVec=np.linalg.eigh(matrix)
indices=eVal.argsort()[::-1]
eVal,eVec=eVal[indices],eVec[:,indices]
eVal=np.diagflat(eVal)
return eVal, eVec
固有値の分布のグラフにおいて、左の大きな山がノイズであり、シグナルは、右の固有値の中に埋もれている。
この記事が気に入ったらサポートをしてみませんか?