stanで重回帰分析をしようとすると、こんな感じのモデルを書くことになる。
data { int<lower=0> N; //データ数 int<lower=0> M; //説明変数の数 real X[N, M]; real Y[N]; } parameters { vector[M] b; real<lower=0> sigma; } model { Y ~ normal (X*b, sigma); }
このXbはちゃんと書くとこんな感じになる。
訳あってこれのXをvectorに変えたらエラーが出た。
data { int<lower=0> N; int<lower=0> K; vector[K] X; // matrix -> vectorに変更 vector[N] Y; } parameters { vector[K] b; real<lower=0> sigma; } model {
for (n in 1:N){
Y[n] ~ normal (X*b, sigma);
} }
Ill-typed arguments supplied to infix operator *. Available signatures:
(int, int) => int
(real, real) => real
(row_vector, vector) => real
(real, vector) => vector
(vector, real) => vector
(matrix, vector) => vector
(complex, complex) => complex
(complex_row_vector, complex_vector) => complex
(real, row_vector) => row_vector
(row_vector, real) => row_vector
(row_vector, matrix) => row_vector
(real, matrix) => matrix
(vector, row_vector) => matrix
(matrix, real) => matrix
(matrix, matrix) => matrix
(complex, complex_vector) => complex_vector
(complex_vector, complex) => complex_vector
(complex_matrix, complex_vector) => complex_vector
(complex, complex_row_vector) => complex_row_vector
(complex_row_vector, complex) => complex_row_vector
(complex_row_vector, complex_matrix) => complex_row_vector
(complex, complex_matrix) => complex_matrix
(complex_vector, complex_row_vector) => complex_matrix
(complex_matrix, complex) => complex_matrix
(complex_matrix, complex_matrix) => complex_matrix
Instead supplied arguments of incompatible type: vector, vector.
要は「*」を使って演算の出来る型はこれだけだから、vector*vectorは無理だぞ、って話なんですが、下記のような形のベクトル同士の掛け算は数学的にも出来ないぞ、っていう話でもある。
じゃあどうするかというと数学的に正しい記載になるのが良くて列ベクトルと行ベクトルの掛け算にするか内積を求めればちゃんと計算ができるようになる。ちなみにこの時Xbは実数(スカラー)が返ってくる。
分かれば当たり前なのだが躓いたのでここに記しておく。
ちなみにstanのコードは以下の通り。
row_vectorで定義する
data { int<lower=0> N; int<lower=0> K; row_vector[K] X; // vector -> row_vectorに変更 vector[N] Y; } parameters { vector[K] b; real<lower=0> sigma; } model {
for (n in 1:N){
Y[n] ~ normal (X'*b, sigma);
} }
vectorを「'」で転置する
data { int<lower=0> N; int<lower=0> K; vector[K] X; vector[N] Y; } parameters { vector[K] b; real<lower=0> sigma; } model {
for (n in 1:N){
Y[n] ~ normal (X'*b, sigma); // X -> X' に変更
} }
dot_productで内積を求める
data { int<lower=0> N; int<lower=0> K; vector[K] X; vector[N] Y; } parameters { vector[K] b; real<lower=0> sigma; } model {
for (n in 1:N){
Y[n] ~ normal (dot_product(X,b), sigma); X*b -> dot_product(X,b)に変更
} }