Chapter9 一歩進んだ文法
(前半)
@ito_yan
2018.12.14
NagoyaStat #12
今回の発表内容
• 9.1 型とインデックス
• 9.2 ベクトル化による高速化
• 9.3 ベクトルや行列の数学的性質の利用
2
9.1 型とインデックス
• 8章まではint(整数)、real(実数)の基本形とその
配列のみ利用
• 他の型を利用した方がコードが簡潔、計算が安
定、高速になる場合がある
• Stanの変数の型は3つに分けられる
• 基本型(整数、実数)
• 列ベクトル(vector)、行ベクトル(row_vector)、行
列型(matrix)
• 任意の型を複数格納する配列
• Rのlistに近い
3
変数の宣言例(1)
型の例 宣言例 説明
整数 int N 整数の変数
実数 real Y 実数の変数
整数の配列 int Y[N] N個の整数を要素とする配列
実数の配列 real Y[N,M,L] N×M×L個の実数を要素とする配列
4
• 変数の型は3つに分けられる
• 基本型の場合
変数の宣言例(2)
• ベクトルと行列は実数のみを要素として保持する
• 整数は持てない
• ベクトルは1次元、行列は2次元だが、配列は任
意の次元を持つことができる
• 配列はベクトル演算や行列演算には使えない
5
型の例 宣言例 説明
ベクトル vector[K] V 1個の長さKのベクトル
ベクトルの配列 vector[K] V[N] N個の長さKのベクトル
ベクトルの配列 vector[K] V[N,M] N×M個の長さKのベクトル
行列 matrix[J,K] X 1個のJ×Kの行列
行列の配列 matrix[J,K] X[N] N個のJ×Kの行列
添字を用いたアクセス(1)
• Rに近い記述でアクセス可能
• 基本型とベクトルの場合
6
宣言例 アクセス例 得られる型 意味
real Y[3] Y[2] real 2番目の要素
Y[2:3] real[2] 2、3番目の要素
real Y[N,M,L] Y[n] real [M,L] M×Lの実数を要素とす
るn番目の2次元配列
vector[K] V V[k] real k番目の要素
V[1:(K-1)] vector[K-1] Vの1~K-1番目までのベ
クトル
添字を用いたアクセス(2)
• 行列の場合
• Stanのmatrixは列優先でメモリに格納されている
ので、列ごとにアクセスすると高速化できる
7
宣言例 アクセス例 得られる型 意味
matrix[J,K] X X[j]、X[j,]、X[j,:] row_vector[j] j行目の行ベクトル
X[j,k] real Xのj行k列目の要素
X[,k] vector[J] k列目の列ベクトル
X[1:2,1:2] matrix[2,2] 2行2列の部分行列
matrix[J,K] X[N] X[n] matrix[J,K] n番目の行列
添字を用いたアクセス(3)
• vector[K] V
• 長さKのベクトルV
• int<lower=1, upper=K> Index[J]
• 長さJの整数型1次元配列
とした場合、
• V[Index]というアクセスができる
• 型はvector[J]になる
• Indexの各要素がインデックスになってVにアクセス
• 155ページのmodel8-4b.stanで使われる
8
添字が配列の場合の具体例
• 先ほどのスライドの表記に従うと、
9
RとStanのデータ型の対応表
変数の次元 Rの型 Stanの型
1 vector
1次元のarray
基本型の1次元配列
vector型
row_vector型
2 matrix
2次元のarray
data.frame
vectorのlist
基本型の2次元配列
vector型の1次元配列
row_vector型の1次元配列
matrix型
3 3次元のarray
matrixのlist
基本型の3次元配列
vector型の2次元配列
row_vector型の2次元配列
matrix型の1次元配列
10
• RからStanに渡す時に型を考慮する必要がある
9.2 ベクトル化の基本
• ベクトル化
• 高速化のためにvector型やvector型に対応した分
布関数を使ってコードを書くこと
• 最初は可読性の高い方法で記述してモデルを構
築し、デバッグを終えたところでベクトル化する
11
4.4節の単回帰のベクトル化
• 配列を列ベクトルに変換
(赤矢印)
• ベクトル化によりfor文を
書かずに処理(青矢印)
• muの各要素毎にループ
を回すより、まとめて計
算した方が速い
12
関数の定義を調べるには
• 関数のベクトル化の対応状況はオフィシャルサイ
トに当たるのが一番
• 対数正規分布については以下の通り
• http://mc-stan.org/docs/2_18/functions-
reference/lognormal.html
• 引数のrealsはreal、vector、row_vector、real型の
1次元配列に対応していることを表している
13
内部的にはnormal_lpdfを呼んでいるので
この関数を調べている(33ページ目)
8.1節の階層モデルのベクトル化
14
1次元配列のベクトル化
1次元配列のベクトル化
for文のベクトル化
要素毎の掛け算を行う演算子
modelブロックの計算に時間がかかるので、ここをベクトル
化し、それに合わせて他の項目をベクトル化していく
9.2.3 非線形階層モデルのベクトル化
15
1,2次元配列のベクトル、行列化
1次元配列のベクトル化
for文のベクトル化
for文のベクトル化
次のスライドで説明
matrixのベクトル化
• normal関数はvector型に対応しているので、
modelで使うmatrix型のYとmuをベクトルに変換
したい
• to_vector関数は2次元配列を列優先でvectorに
変換する
16
改良前のモデル
ベクトル化後のモデル
to_vector関数のイメージ
17
(1)(2)(3)(4)
(1)
(2)
(3)
(4)
M×Nの行列
to_vector関数
(M*N)×1の列ベクトル
M
N
下に続けて
9.3.1 多変量正規分布
• 50m走のタイムと走り幅跳びで飛んだ距離
• 2変量正規分布に従うと仮定
• 誤差項を消去すると
• 平均ベクトルと分散共分散行列の事前分布には無
情報事前分布を設定する
• Stanのコードとしては特に何も記述しない
18
データの特徴
• 50m走のタイム(Y1)が遅くなると、走り幅跳びの
跳躍幅(Y2)は短くなる
• 太めの人はタイムが大きな値となり、かつ跳躍距離
は短くなるという、負の相関関係があると想定され
るデータである
19
タイム(Y1)が大きいと、
跳躍幅(Y2)が小さくなる
仮定している確率密度
関数の等高線
実装コードの説明
• Dは多変量正規分布の生成するベクトル長で2
• YはN個の長さDのベクトル
• mnは平均パラメータで長さはD
• covは分散共分散行列で、cov_matrix型で宣言
すると、自動的に対称行列かつ半正定値になる
20
分散共分散行列の
半正定値性の導出
は補足を参照
とりあえず実行
21
• テキストの通りの結果が得られた
パラメータの事後平均
多変量正規分布関数のベクトル化
• http://mc-stan.org/docs/2_18/functions-
reference/multivariate-normal-distribution.html
• y、muはベクトル、Sigmaは行列でもOKと分かる
22
ここの引数の型に注目
9.3.2 行列演算を使った重回帰
• 5章の重回帰に説明変数(X3、X4)を追加
• 重回帰の式は行列で書ける
23
:回帰係数 :データ
重回帰のベクトル化
24
• 配列ではなく、matrixとvectorを使用している
for文のベクトル化
複数の1次元配列を
行列にまとめる
1次元配列のベクトル化
基本型変数のベクトル化
for文のベクトル化
X*bは行列の積
Stanのコードを呼び出す側
• dataブロックのN、D、X、Yを作成する
• d$Scoreはスケーリングでパラメータの大きさを他
の変数と合わせる(58ページ目)
• Xのcbindの1は切片項、-ncol(d)は応答変数を説
明変数から外している
• 「RとStanのデータ型の対応表」のスライドに照らし
合わせて渡すデータの型が妥当かチェック
25
まとめ
• modelの項目に計算時間がかかるので、model
の内容に応じてベクトルや行列を使おう
• Stanのマニュアルで関数がベクトルに対応している
か調べよ
• 説明変数が増えてもStanのコードは変わらない
のがベクトルや行列を使う利点である
• 重回帰の例ではdataブロックでA[n]、Score[n]、X3、
X4…のように変数を増やさなくてもよい
26
補足
27
exp関数のベクトルへの適用例
• https://mc-stan.org/docs/2_18/functions-
reference/fun-vectorization.html
28
ベクトルに対して指数関数が
使えることが示されている
分散共分散行列の半正定値性の導出
• 任意の非零列ベクトルxに対して、 が
成り立つときに行列Mは半正定値という
• Mが分散共分散行列のときに半正定値性を示す
• 確率変数をY、平均をμ(共に列ベクトル)とする
29
(・,・) はベクトル
の内積
内積は順序の交換
が可能なので
xはYに関係なく、
中に入れられる

Chapter9 一歩進んだ文法(前半)