マルコフ連鎖モンテカルロ法入門-1
- 17. お天気推移モデルの不変分布をRで見るー2
#数日後の天気確率計算関数
#weather.initial_:
#transition.matrix_:お天気遷移行列
#size_:何日間の遷移を計算するのか
TranslateWeather <- function(weather.initial_,transition.matrix_,size_){
result <- matrix(NA, nrow = size_ + 1, ncol = nrow(weather.initial_))
result[1,] <- t(weather.initial_)
weather.day <- weather.initial_
for(day in 1:size_){
weather.day <- transition.matrix %*% weather.day
result[day + 1,] <- t(weather.day)
}
return(result)
}
#状態遷移行列として以下のような遷移確率
#晴⇒晴:1/2、晴⇒雨:1/2、雨⇒晴:2/3、雨⇒雨:1/3
transition.matrix <- matrix(c(1/2,1/2,2/3,1/3), nrow = 2, ncol = 2)
#今日の天気(初期状態)としては晴を指定
weather.initial <- matrix(c(1.0,0.0),nrow = 2)
#天気の推移計算
size <- 10
weather.transition <- TranslateWeather(weather.initial, transition.matrix, size)
matplot(weather.transition,lwd = 3, ylab="確率", xlab="何日後", type = "l", lty = 1, col=c("red","blue"))
legend(nrow(weather.transition)- 4, 1, legend = c("晴","雨"), col=c("red","blue"), lty = 1)
- 20. お天気推移モデルの不変分布をRで見るー5
#数日後の天気確率計算関数
#weather.initial_:
#transition.matrix_:お天気遷移行列
#size_:何日間の遷移を計算するのか
TranslateWeather <- function(weather.initial_,transition.matrix_,size_){
result <- matrix(NA, nrow = size_ + 1, ncol = nrow(weather.initial_))
result[1,] <- t(weather.initial_)
weather.day <- weather.initial_
for(day in 1:size_){
weather.day <- transition.matrix %*% weather.day
result[day + 1,] <- t(weather.day)
}
return(result)
}
#状態遷移行列として以下のような遷移確率
#晴⇒晴:1/2、晴⇒雨:1/2、雨⇒晴:2/3、雨⇒雨:1/3
transition.matrix <- matrix(c(1/2,1/2,2/3,1/3), nrow = 2, ncol = 2)
#今日の天気(初期状態)として以下を指定
c(0.5,0.5)
weather.initial <- matrix( ,nrow = 2)
#天気の推移計算
size <- 10
weather.transition <- TranslateWeather(weather.initial, transition.matrix, size)
matplot(weather.transition,lwd = 3, ylab="確率", xlab="何日後", type = "l", lty = 1, col=c("red","blue"))
legend(nrow(weather.transition)- 4, max(weather.transition), legend = c("晴","雨"), col=c("red","blue"), lty = 1)
- 30. マルコフ連鎖から得られるサンプルの意味
2章の結果から「マルコフ連鎖に従っ
てお天気をどんどん生成していって、
ある程度日数が経過した後には、晴
か雨のお天気が出る確率は、日にち
が経過しても変わらない不変分布に
従っている」ということがわかっていた
ある程度日数が経過した後、マルコフ連鎖から得られ
るお天気は不変分布からサンプリングしたもの(不変
分布に従う乱数!)と見做して良い
- 33. ~不変分布からのサンプリングの実装-1~
1:if-elseで不変分布を既知としてサンプリング
#サンプリング回数
size <- 10000
#サンプリング."晴"が4/7の確率で出るようにしている。逆に雨は3/7の確率
result <- ifelse(runif(size) > 3/7, "晴", "雨")
#結果表示、標本から確率を計算
print(sum(result=="晴")/size)
print(sum(result=="雨")/size)
計算結果
> print(sum(result=="晴")/size)
[1] 0.5775
> print(sum(result=="雨")/size)
[1] 0.4225
- 34. ~不変分布からのサンプリングの実装-2~
2:お天気推移モデルを使ってサンプリング
#晴⇒晴:1/2,雨⇒雨:1/3な推移確率
transition <- c(Fine=1/2,Rain=1/3)
size <- 10000 #サンプリング回数
result <- c() #結果格納
weather.now <- "晴" #現在のお天気
#マルコフ連鎖の生成&不変分布からのサンプリング.
for(i in 1:size){
result <- c(result,weather.now)
#現在の状態に応じて次の状態を決める⇒マルコフ連鎖の生成
if(weather.now=="晴"){
weather.now <- ifelse(runif(1) > transition["Fine"],"晴","雨")
}else if(weather.now=="雨"){
weather.now <- ifelse(runif(1) > transition["Rain"],"晴","雨")
}
} > print(sum(result[-(10:1)]=="晴")/(size-10))
#結果表示、標本から確率を計算
#初めの10個は不変分布に達してないと思って捨てる [1] 0.5705706
print(sum(result[-(10:1)]=="晴")/(size-10)) > print(sum(result[-(10:1)]=="雨")/(size-10))
print(sum(result[-(10:1)]=="雨")/(size-10)
[1] 0.4294294
- 43. 詳細釣り合いの条件からメトロポリス法へ
■お天気モデルの詳細釣り合いの条件再掲
不変分布 晴⇒雨の 不変分布 雨⇒晴の
晴の確率 推移確率 雨の確率 推移確率
■未知数2つ(推移確率)に式1本(詳細釣り合いの
条件)なんで、推移確率が一意に決まらない
決め方にも種類が色々。代表的な推移確率の決め方として
1:メトロポリス法
2:熱浴法(ギブスサンプラー)
3:メトロポリス・ヘイスティング法
がある。ここではメトロポリス法だけ紹介。
- 47. メトロポリス法をRでやってみる-2
#不変分布を返す関数
InvariantDistribution <- function(weather){
ifelse(weather=="晴",4/7,3/7)
} 結果
#推移したい次の天気を返却
NextWeather <- function(weather){
> print(sum(result[-(10:1)]=="晴")/(size-10))
return(ifelse(weather=="晴","雨","晴")) [1] 0.5691692
}
size <- 10000 #サンプリング回数 > print(sum(result[-(10:1)]=="雨")/(size-10))
result <- c() #結果格納 [1] 0.4308308
weather.now <- "晴" #現在のお天気
#メトロポリス法によるマルコフ連鎖の生成&不変分布からのサンプリング
for(i in 1:size){
result <- c(result,weather.now)
#遷移したい次の天気を指定(一般化したときのためにこう書いてる)
weather.next <- NextWeather(weather.now)
#メトロポリス法による推移確率の計算
transition.probability <- min(1,
InvariantDistribution(weather.next)/InvariantDistribution(weather.now))
#推移確率に応じて状態を推移
weather.now <- ifelse(transition.probability > runif(1),weather.next,weather.now)
}
#結果表示、標本から確率を計算
print(sum(result[-(10:1)]=="晴")/(size-10))
print(sum(result[-(10:1)]=="雨")/(size-10))
- 56. メトロポリス法をRでやってみる-2
#不変分布を返す関数
InvariantDistribution <- function(weather){
ifelse(weather=="晴",4/7,ifelse(weather=="雪",2/7,1/7)) > print(sum(result[-(10:1)]=="
}
#推移したい次の天気を返却 晴")/(size-10))
NextWeather <- function(weather){ [1] 0.5690691
#今の天気以外の天気を作成、1/2で選択 > print(sum(result[-(10:1)]=="
weathers <- c("晴","雪","雨") 雪")/(size-10))
weathers <- weathers[weathers!=weather] [1] 0.2917918
return(weathers[round(runif(1))+1]) > print(sum(result[-(10:1)]=="
} 雨")/(size-10))
size <- 10000 #サンプリング回数
result <- c() #結果格納 [1] 0.1391391
weather.now <- "晴" #現在のお天気
#メトロポリス法によるマルコフ連鎖の生成&不変分布からのサンプリング
for(i in 1:size){
result <- c(result,weather.now)
#遷移したい次の天気を指定
weather.next <- NextWeather(weather.now)
#メトロポリス法による推移確率の計算
transition.probability <- min(1,
InvariantDistribution(weather.next)/InvariantDistribution(weather.now))
#推移確率に応じて状態を推移
weather.now <- ifelse(transition.probability > runif(1),weather.next,weather.now)
}