HOJI-CHAN’s diary

自己学習の備忘録

ナイーブベイズ

教師あり学習の一種であるナイーブベイズについて、少し簡単なメモを残しておきます。

分類器の目標は、特徴変数{ X_1,X_2,\cdots,X_n}が与えられた時に、このデータがどの分類に属すか({ C=0? or 1? or 2?})を判定することです。
(たとえば、irisデータの場合、{ X_i}に相当するものがsepal length sepal width, petal length, petal width
{C}に相当するものが、species。)

条件付き確率({ P(C=i|X_1,X_2\cdots,X_N)(i=0,1,2)}:すなわち、データが与えられた時に{C=i}である確率)をモデル化する手法の一つがナイーブベイズです。
(詳細は割愛しますが、モデル化の際にベイズの定理を用いていているものです。)

SVMも有名ですが、これは識別関数を求めにいくという部分で手法が異なります。

irisのデータで確認してみます。

from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.naive_bayes import GaussianNB
import matplotlib.pyplot as plt

# import iris data 
iris = datasets.load_iris()
X = iris.data
Y = iris.target

#訓練データとテストデータを作成
X_train, X_test, y_train, y_test = train_test_split(X,Y,test_size=0.5,random_state=0)

nb=GaussianNB()
nb.fit(X_train,y_train)

y_pred=nb.predict(X_test)

fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)

ax1.scatter(X_test[:, 0], X_test[:, 1], c=y_pred)
ax1.set_xlabel('x1')
ax1.set_ylabel('x2')
ax1.set_title("Predict")

ax2.scatter(X_test[:, 0], X_test[:, 1], c=y_test)
ax2.set_xlabel('x1')
ax2.set_ylabel('x2')
ax2.set_title("Actual")
fig.tight_layout()

※実際は、特徴変数は2変数ではありませんが、簡単のため2軸でプロットしています。
f:id:HOJI-CHAN:20170905121635p:plain

正解率(=(正しく分類できた数)/(全体数))=94.667%

nb.score(X_test, y_test)

CVAについて

<参考>「XVA モデルの理論と実務」土屋修(https://store.kinzai.jp/public/item/book/B/12889/


CVAとは、カウンターパーティーがデフォルトした時、そのエクスポージャーに対し損失するリスク。

実際にはネッティングセットで考える(ポートフォリオ全体で考える)ため、ポートフォリオ全体で計算する必要がある。計算負荷が高いといわれている理由の一つである。

そのため、1つの取引Aに対するCVAを計算したかったら、「(ポートフォリオのCVA)-(取引Aを除くポートフォリオのCVA)」を計算する必要がある。

通常のプライシングの際には個々の商品にフィットするように、カリブレーションを行うが、ポートフォリオの最大満期に合わせて、一番影響の大きい商品に合わせてカリブレーションを行うなどの工夫が必要である。

パス生成の際に、すべての商品の利払い日に合わせてグリッドを生成するのは負荷がかかるため、代表的なグリッドで生成しておいてstub調整(グリッドの補間)をするのかなと思います。(どちらにしても大変そう。。)

ハザードレートと生存確率について

土屋さんの「XVA モデルの理論と実務」(きんざいストア)を読んでいくつか気になった部分をメモにまとめておこうと思います。
知識が足りず理解が足らない部分もありますが、全体的に丁寧でわかりやすいと思いました。

2-2章一部抜粋
時点0に観測する時点{t}まで法人Aのデフォルトが起きない確率(生存確率){ P^A(0,t)}は期間{[0,t]}を微小な時間間隔に{[u_0=0,u_1=0,\cdots,u_n=t]}と分割することにより、{ P^A(0,t)=\lim_{n\to\infty}\Pi_{j=0}^n(1-\lambda^A(u_j)du)=\exp(-\int_0^t\lambda^A(u)du)}


この部分について、自分なりの理解(「第1項=第2項」は直感的に理解できたので割愛する。)

T:デフォルト時点

 \begin{align} 
\lambda^A(u) &= \lim_{du\to 0}\frac{1}{du}P(t< T < t+du | T > t)\\\ 
&= \lim_{du\to 0}\frac{1}{du}\cdot \frac{P( (t< T < t+du) \& (T > t) )}{P(T>t)}\\\
&= \lim_{du\to 0}\frac{1}{du}\cdot \frac{P( t< T < t+du )}{P(T>t)}
 \end{align}

{P^A(0,t)= P(t < T)=1-P(T \leq t)=:1-F(t)}であるから、

 \begin{align} 
\lambda^A(u) &= \lim_{du\to 0}\frac{1}{du}\cdot \frac{P( t< T < t+du )}{P(T>t)} \\\
&=  \lim_{du\to 0}\frac{-P^A(0,t+du)+P^A(0,t)}{du}\cdot \frac{1}{P^A(0,t)} \\\
&= - \frac{d \log(P^A(0,t))}{dt}
 \end{align}

積分して、

{ P^A(0,t)=\exp(-\int_0^t\lambda^A(u)du)}

高次元データの次元削減


高次元データの可視化として次元削減手法もいろいろあるんだなということで、いくつか整理して違いを試してみようと思います。

実際に、pythonを使ってirisのデータで確認してみます。(Python3.5)

from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
Y = iris.target


1)主成分分析(PCA)
・分散を最大にするように、軸を決めていく手法。(ざっくりすぎる説明)

import numpy as np
import matplotlib.pyplot as plt

cov_mat=np.cov(X.T)
eigen_vals,eigen_vecs = np.linalg.eig(cov_mat)
var_exp=[(i/sum(eigen_vals)) for i in sorted(eigen_vals, reverse=True)]
cum_var_exp=np.cumsum(var_exp)

eigen_pairs=[(np.abs(eigen_vals[i]),eigen_vecs[:,i]) for i in range(len(eigen_vals))]
eigen_pairs.sort(reverse=True)
w=np.hstack((eigen_pairs[0][1][:,np.newaxis],eigen_pairs[1][1][:,np.newaxis]))

X_pca=X.dot(w)
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=Y, cmap=plt.cm.Paired)
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.show()

グラフはこんな感じです。
f:id:HOJI-CHAN:20170830111110p:plain


2)t-SNE
参考:
t-distributed stochastic neighbor embedding - Wikipedia
http://jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf

・PCAと違い非線形に対応可。
・高次元での確率分布で見た距離と低次元での確率分布で見た距離が一致するように、決める。
・距離は、KL (カルバック・ライブラー)情報量で決定(いつも覚えられない。。)

SNEとt-SNEとの違い
・t-SNEは、低次元での確率分布を自由度1のt分布としている。(SNEは、正規分布
・SNEは条件付き確率を使用しているが、t-SNEは対称となるように修正している。(これにより、コスト関数がシンプルになるため計算しやすい)

from sklearn.manifold import TSNE
#
model = TSNE(n_components=2, perplexity=30, n_iter=500, random_state=1)
X = model.fit_transform(X)

plt.clf()
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)
plt.xlabel('tsne1')
plt.ylabel('tsne2')
plt.show()

グラフはこんな感じです。
f:id:HOJI-CHAN:20170830110350p:plain
ちなみに、perplexity=50とするとこんな感じです。
f:id:HOJI-CHAN:20170830110357p:plain

いまいち。。。
パラメータperplexityの決め方や、その他の手法についてはまた後日。

はてなブログでソースコードをかく

これから、勉強したことを少しづつここでまとめていこうと思います。(なんで今までやらなかったんだろう。)

まずは初歩的なところから、ソースコードの書き方もわからない。。ということで調べました。

1)設定>編集モードで「はてな記法モード」を選択

2)例えば、「import numpy as np」をコードとしてかくには
 >|python|
import numpy as np
 ||<

と書けばいいだけ。なんだ簡単!

import numpy as np