2015年12月27日日曜日

[Rの]Andrew先生の機械学習2-2[練習]




2回目後半は線形分離できない2次元データのロジスティック回帰。
黄色○と+を識別したいが、どう見ても直線では識別できなさそう。




n次の空間に射影し、(n + 2)!/(n! * 2!)次元空間で線形分離する。
講義の問題と同様n = 6としてみる

R
ex2_2 <- function()
{
    # ----- load data -----
    data = read.csv('ex2data2.txt', header = F)
    X <- data[, 1:2]
    y <- data[, 3]
   
    # ----- plot -----
    plot(0, 0, type = "n", xlim = c(0.9 * min(X[, 1]), 1.1 * max(X[, 1])), ylim = c(0.9 * min(X[, 2]), 1.1 * max(X[, 2])),xlab = "x1", ylab = "x2")   
    points(X, col = ifelse(y == 1, "black", "yellow"), pch = ifelse(y == 1, 3, 16))
    legend("topleft", legend = c("y = 1", "y = 0"), pch = c(3, 16), col = c("black", "yellow"))
    par(new = T)
   
    # ----- variables -----
    mappedX = mapFeature(X[, 1], X[, 2])
    m = length(mappedX[,1])
    n = length(mappedX[1,])

    # ----- mapFeatureでバイアス項が足されている
    initial_theta = rep(0, n)

    # ----- optimize -----
    print("start optimization")
    lambda = 1
    result <- optim(par = initial_theta, fn = costFunctionReg, gr = costGr, method = "CG", X = mappedX, y = y, lambda = lambda)
    theta = result$par   
    plotDB2(theta, X, y)

    p = round(sigmoid(mappedX %*% theta))
    cat("Train Accuracy : ", mean(p == y) * 100, "\n")
    return(result)
}

mapFeature <- function(X1, X2)
{
    degree = 6
    out = matrix(1, length(X1), 1)
    for (i in 1 : degree) {
        for (j in 0 : i) {
            out = cbind(out, X1 ^ (i-j) * X2 ^ j)
        }
    }
    return(out)
}

costFunctionReg <- function(theta, X, y, lambda)
{
    m = length(y)
    predicts = X %*% theta
   
    probs = sigmoid(predicts)
    costs = -y * log(probs) - (1 - y) * log(1 - probs)
    J = sum(costs) / m

    # ----- regularize -----
    J = J + lambda / (2 * m) * sum(theta[-1] ^ 2) # theta[-1]は1番目以外の要素
    return(J)
}
costGr <- function(theta, X, y, lambda)
{
    m = length(y)
    predicts = X %*% theta
   
    probs = sigmoid(predicts)
    grad = (t(X) %*% (probs - y)) / m + lambda / m * theta
    grad[1] = (t(X)[1, ] %*% (probs - y)) / m
    return(grad)
}

plotDB2 <- function(theta, X, y)
{
    num_points = 50
    u <- seq(0.9 * min(X[, 1]), 1.1 * max(X[, 1]), length = num_points)
    v <- seq(0.9 * min(X[, 2]), 1.1 * max(X[, 2]), length = num_points)
    z <- matrix(0, nrow = length(u), ncol = length(v))
    for (i in 1 : length(u)) {
        for (j in 1 : length(v)) {
            z[i, j] = mapFeature(u[i], v[j]) %*% theta   
        }
    }
    contour(u, v, z, xlim = c(0.9 * min(X[, 1]), 1.1 * max(X[, 1])), ylim = c(0.9 * min(X[, 2]), 1.1 * max(X[, 2])))
   
}
optim関数にmethod = "CG"を指定しているのは、デフォルトだと識別があまりよくならなかったため。

結果
Train Accuracy :  83.05085



n = 2でやってみた

  Train Accuracy :  81.35593
こっちでもいいんでないかという気もするレベル。
nを決めるには横軸n、縦軸TrainAccuracyのグラフを描いてみれば いいんだったか。
あるいは縦軸は汎化能力か

コスト関数の値と勾配を別の関数で計算しているせいで、無駄な計算をしている。
matlabの最適化関数では、関数の返り値を多次元にして勾配を返してやるとそれを使って最適化してくれていたのだけど、Rのoptimは同じことはできないらしい。

fn
A function to be minimized (or maximized), with first argument the vector of parameters over which minimization is to take place. It should return a scalar result.

2015年12月23日水曜日

[Rの]Andrew先生の機械学習2-1[練習]





2回目のお題はロジスティック回帰
簡単な関数いくつか作って、後はRの最適化関数を使うだけ

ex2 <- function()
{
    # ----- load data -----
    data = read.csv('ex2data1.txt', header = F)
    X <- data[, 1:2]
    y <- data[, 3]
   
    # ----- plot -----
    plot(0, 0, type = "n", xlim = c(0.9 * min(X[, 1]), 1.1 * max(X[, 1])), ylim = c(0.9 * min(X[, 2]), 1.1 * max(X[, 2])),xlab = "x1", ylab = "x2")   
    points(X, col = ifelse(y == 1, "black", "yellow"), pch = ifelse(y == 1, 3, 16))

    # ----- variables -----
    X_mat <- cbind(X[, 1],X[, 2])
    m <- length(X[,1])
    n <- length(X[1,])

    # ----- add bias -----
    initial_theta <- rep(0, n + 1)
    X_mat <- cbind(rep(1, m), X_mat)

    # ----- optimize -----
    result <- optim(par = initial_theta, costFunction, X = X_mat, y = y)
    theta <- result$par
    plotDecisionBoundary(theta, X, y)
}

sigmoid <- function(x)
{
    return(1 / (1 + exp(-x)))
}

costFunction <- function(theta, X, y)
{
    m <- length(y)
    predicts <- X %*% theta
   
    probs <- sigmoid(predicts)
    costs <- -y * log(probs) - (1 - y) * log(1 - probs)
    J <- sum(costs) / m

    return(J)
}

plotDecisionBoundary <- function(theta, X, y)
{
    # ----- plot -----
    plot(0, 0, type = "n", xlim = c(0.9 * min(X[, 1]), 1.1 * max(X[, 1])), ylim = c(0.9 * min(X[, 2]), 1.1 * max(X[, 2])),xlab = "x1", ylab = "x2")
    points(X, col = ifelse(y == 1, "black", "yellow"), pch = ifelse(y == 1, 3, 16))
    par(new=T)

    x1 <- c(min(X[, 1]), max(X, 1))
    x2 <- -1 / theta[3] *( theta[2] * x1 +theta[1])
    plot(x1, x2, ,type = 'l', xlim = c(0.9 * min(X[, 1]), 1.1 * max(X[, 1])), ylim = c(0.9 * min(X[, 2]), 1.1 * max(X[, 2])))
}


















----- 追記 -----
ちなみにglm関数を使うと
ex2_glm <- function()
{
    # ----- load data -----
    data = read.csv('ex2data1.txt', header = F)
    X <- data[, 1:2]
    y <- data[, 3]
   
    # ----- GLM -----
    fit <- glm(formula = y ~ V1 + V2 + 1, family = binomial, data = X)
    theta <- fit$coef
    plotDecisionBoundary(theta, X, y)
    print(summary(fit))   
    return(fit)
}


2015年12月21日月曜日

[Rの]Andrew先生の機械学習1[練習]

折角Andrew先生の講義を一通り終えたので、復習とRの練習のため、練習問題をRに移植。
matlabに慣れていたのもあって、講義の問題はだいたい2時間以内で終わっていたけれども、Rではもっと時間がかかりそう。最後まで続けられるか微妙。

最初のお題は線形回帰
Rの組み込み関数lmを使った。
plot関数を重ねて使うとあまりよくないらしい。

ex1 <- function()
{
    data = read.csv('ex1data1.txt', header = F)
    X <- data[, 1]
    y <- data[, 2]
    plot(X, y, xlim = c(0.9 * min(X), 1.1 * max(X)), ylim = c(0.9 * min(y), 1.1 * max(y)))
    par(new=T)

    m = length(y) # number of training examples
    fit <- lm(y ~ X)
    theta <- c(coef(fit))
    print(theta)
   
    xx <- c(min(X), max(X))
    yy <- theta[2] * xx + theta[1]
    # if it were not for xlim & ylim the plotted axis is worngly overlapped
    plot(xx, yy, type = 'l', xlim = c(0.9 * min(X), 1.1 * max(X)), ylim = c(0.9 * min(y), 1.1 * max(y)), xlab = "", ylab = "")
}






















bloggerでは手軽にコードを記載する方法が見つからなかった。
はてなではとても簡単にコードを色分けして表示できそうでかっこよかった。

2015年11月8日日曜日

scale = Tの場合

主成分分析prcompの引数scaleをTRUEにすると、各列のデータが分散1となるようにスケールしてくれるらしい

R
> result  <- prcomp(swap, scale = T)
> result
Standard deviations:
[1] 2.38336807 0.44870618 0.33360252 0.06090642 0.04466024 0.03499461

Rotation:
           PC1         PC2         PC3        PC4         PC5         PC6
X2y  0.3944065  0.73027653  0.27008073 -0.4856403  0.02406269 -0.04207786
X3y  0.4136078  0.32720443 -0.19850391  0.7396029  0.36517548 -0.04578781
X4y  0.4152639 -0.02031179 -0.41385405  0.0495695 -0.79549497 -0.14352265
X5y  0.4124038 -0.26645040 -0.40798735 -0.3319752  0.30071768  0.62596724
X7y  0.4111544 -0.43751365  0.04357652 -0.2235952  0.31526598 -0.69874707
X10y 0.4022476 -0.31113805  0.74028699  0.2334129 -0.20840310  0.30895263
> summary(result)
Importance of components:
                          PC1     PC2     PC3     PC4     PC5     PC6
Standard deviation     2.3834 0.44871 0.33360 0.06091 0.04466 0.03499
Proportion of Variance 0.9467 0.03356 0.01855 0.00062 0.00033 0.00020
Cumulative Proportion  0.9467 0.98030 0.99885 0.99946 0.99980 1.00000

結果は第三主成分まででほぼ表せることは変わらず。累積寄与率少し落ちてるけど

第一主成分の各年限の値がほぼ一定になっている。まさにパラレルシフト。
どうやらスワップレートは幅変化でなく、率変化においてパラレルシフトをしているらしい。

スワップレートを主成分分析[R]


スワップレートは下記から取得
http://www.tr.mufg.jp/houjin/derivatives/kinri_data.html
使ったのは2012/10/26~2015/11/4のスワップレート
特に工夫もなく手動でコピペしてcsvファイル作成。

R
> swap <- read.csv("swap.csv",header = T)
> swap <- swap[2:7]
> result <- prcomp(swap, scale = F)

やっていること
・csv読み込み
・日付は使わないので省く
・主成分分析(scaleはデフォルトでFALSEだが、今回は明示的にFALSEにしている)

結果の確認
> result
Standard deviations:
[1] 0.221107220 0.036991786 0.026278991 0.004032331 0.003264767 0.002929029

Rotation:
           PC1         PC2         PC3        PC4         PC5         PC6
X2y  0.1940473  0.18504988  0.71773570 -0.5458590 -0.29544235 -0.16646151
X3y  0.2432946  0.34313881  0.38514304  0.2358646  0.56752629  0.54498636
X4y  0.2989262  0.43578320  0.02328193  0.4545954  0.08673305 -0.71134694
X5y  0.3609295  0.43281078 -0.29591390  0.1146100 -0.64858753  0.40129601
X7y  0.4976880  0.08724279 -0.47358006 -0.6002431  0.39014859 -0.08893542
X10y 0.6601765 -0.68056508  0.15535492  0.2575298 -0.10111081  0.01783152
> summary(result)
Importance of components:
                          PC1     PC2     PC3      PC4      PC5      PC6
Standard deviation     0.2211 0.03699 0.02628 0.004032 0.003265 0.002929
Proportion of Variance 0.9589 0.02684 0.01355 0.000320 0.000210 0.000170
Cumulative Proportion  0.9589 0.98576 0.99930 0.999620 0.999830 1.000000

第3主成分までで99.9%が説明できている。
主成分の解釈はよく言われるように、
第一主成分:パラレルシフト
第二主成分:フラットニングorスティープニング
第三主成分:カーブの曲率変化
と言ってよさそう。

横軸:時間
縦軸:主成分得点


第一主成分が最近減少しているのは、金利低下を表している。
第二主成分が大きくなるとフラットニング、小さくなるとスティープニングを表す。ちょこちょこ変動しているのがわかる。
第三主成分は3年前は動いていたが、最近はあまり動いていない。
第三主成分以降は割とどうでもいい。

感想
ブログっぽい記法ができるようになりたい。
第一主成分がパラレルシフトとか言ったけど、全然パラレルではない。
フォワードレートで計算したらどうなるか。

 おわり

2015年10月3日土曜日

matlabでよく使うショートカット


エクセルやvisual studioと似ているが、メモ

・コマンドウインドウやエディタ間の遷移
ctrl + tab / ctrl + shift + tab

・エディタのタブ間の遷移
ctrl + page up / down

・エディタのタブやfigureのウインドウを消す
ctrl + w

・コメントアウト /  コメントアウト解除
ctrl + r / ctrl + t

・ブレークポイント設定/解除
F12

・ステップ
F10

・ステップイン/ステップアウト
F11 / shift + F11

・デバッグ中止
shift + F5

・計算中止
ctrl + c

2015年9月21日月曜日

small time expansion


 ZABR - Expansions for the Masses December 2011 by Jesper Andreasen and Brian Huge.
の前半1/4くらいがとても簡単そうだったのでグラフを書いてみた。



パラメータがずれている影響でオリジナルと少し違うけど、ほぼ再現できた。

small time expansionによって満期についての情報が失われているけれど、ほんの数行のコードでHagan公式に近いスマイルが描けている。

2015年7月19日日曜日

よくやる近似式

xが十分小さいときによく使う近似式

\begin{equation}
(1+x)^{\beta} \sim 1 + \beta * x
\end{equation}

をグラフにしてみた。
オーダーは$O(x^{\beta - 1})$なのでbeta = -2の方がずれが大きい。
しかしやはり可視化したほうがわかりやすい。


2015年4月12日日曜日

データ解析のための統計モデリング入門

読んだ。

Rで書いてあるコードを自分でも再現しながらやるつもりだったけど、結局途中から読むだけになってしまった。以下メモ

・やりたいのは、多数のデータのふるまいを少数のパラメータによって表現すること

・GLMでは確率分布・リンク関数・線形予測子によってモデルが構成される

・最小二乗法は、確率分布に正規分布を仮定したときの最大尤度

・観測にかからない影響をモデルに組み入れたのがGLMM

・GLMMでは過分散を説明するようなモデルも作ることができる

・階層ベイズモデルでは、モデルのパラメータ自体も確率分布する量としてさらにモデル化する →局所的なパラメータを大域的なパラメータで代表させてパラメータを減らす

↑ここまでモデルの話

↓ここから推定の話

・得られたパラメータから後続のデータを予測する際にはどんなモデルが良いか?→AIC基準といものがある(唯一ではないと思うがわかりやすい基準)

・より複雑な統計モデルのあてはめに効果的なのがMCMC

・MCMCサンプリングで得られるのは現在得られたデータから得られるモデルパラメータの定常分布

2015年4月5日日曜日

メタ関数 is_same

template <typename, typename>
struct is_same : public false_type {};

template <typename Type>
struct is_same<Type, Type> : public true_type {};
 
1つ目はfalse_typeを継承したis_same。
テンプレート引数2つがどんな組み合わせでも実体化されうる 
したがって
次に定義する特殊化されたis_sameが選ばれなければis_sameはfalse_typeを継承する。
 
2つ目は2つのテンプレート引数が同一だった場合の特殊化。これが選ばれるとtrue_typeを継承する。
  
 

2015年3月8日日曜日

ポアソン分布

試行回数N、確率pのコイン投げで表がk回出る確率は二項分布
\begin{equation}
p(k) = _N C_kp^k(1-p)^{N - k}
\end{equation}
に従う。

これをN→∞として連続化したものがポアソン分布。
ただしこのとき平均$Np$も同時に無限に発散してしまわないよう、$Np = \lambda$と固定しておく。
こうして平均$\lambda$を持つポアソン分布ができる。
\begin{equation}
f(x) = \frac{e^{-\lambda}\lambda ^x}{x!}
\end{equation}
ポアソン分布:単位時間当たり平均$\lambda$回起こる事象が単位時間に$x$回起こる確率

ポアソン分布の特徴として
・平均と標準偏差がともに$\lambda$。(両方が$\lambda$ということより、分布が$\lambda$というただひとつのパラメータによって決定されることに注目)
・「回数」を表現する分布のため正の値しかとらない。分布の形が非対称。
・指数分布との関係


参考URL
http://www.slideshare.net/teramonagi/ss-11296227