LoginSignup
2
7

More than 3 years have passed since last update.

RでBayesLiNGAM

Last updated at Posted at 2020-05-07

RでBayesLiNGAM

07May'20: Written

はじめに

現在、因果探索アプローチに用いられるLiNGAMはRおよびPythonで実装されている。

いろいろなLiNGAMモデルのR and/or Python
https://sites.google.com/site/sshimizu06/lingam

今回はその中でもBayesLiNGAMを用いたモデルをRで使用してみる。
原理は以下の文章に記載されている。

https://pdfs.semanticscholar.org/7122/03d0696feb5f03b1d046e6db59f7e4087cff.pdf
https://www.jstage.jst.go.jp/article/pjsai/JSAI2014/0/JSAI2014_2G13/_pdf

導入環境

OS: Mojave (version; 10.14.6)
R version: 3.6.3 (2020-02-29)
R Studio version: 1.2.5033

手順

  1. パッケージのダウンロード・解凍
  2. ソースコードの書き換え
  3. 実行に必要な他のパッケージのインストール
  4. 動作確認

パッケージのダウンロード・解凍

以下のサイトの「Code Package」から「Version 1.1」をダウンロード(07May'20)。
https://www.cs.helsinki.fi/group/neuroinf/lingam/bayeslingam/

「bayeslingam.tar.gz」がダウンロードされるので、これを解凍。
→ 「bayeslingam」

ソースコードの書き換え

このままRで起動しようとしてもErrorになるので、一部ソースコードを書き換える。
書き換えるものは2つ。
・loud.R
・loadbayeslingam.R

loud.R

bayeslingam/main/loud.Rの一部を書き換え。
元は以下。

cauzality_path<<-"./../.."

修正後は以下。

cauzality_path<<-"/Users/(作業ディレクトリ)/bayeslingam"

作業ディレクトリには任意で。

loadbayeslingam.R

bayeslingam/bayeslingam/loadbayeslingam.Rの一部を書き換え。
元は以下。

common_dir<-sprintf("%s/trunk/common",cauzality_path)

bayeslingam_dir<-sprintf("%s/trunk/bayeslingam",cauzality_path)    

rbayeslingam_dir<-sprintf("%s/trunk/bayeslingam/rbayeslingam",cauzality_path)

rlingam_dir<-sprintf("%s/trunk/rlingam",cauzality_path)

rdeal_dir<-sprintf("%s/trunk/rdeal",cauzality_path)

rpc_dir<-sprintf("%s/trunk/rpc",cauzality_path)

etudag_dir<-sprintf("%s/trunk/ETUDAG",cauzality_path)

trunk/を消去する。
修正後は以下。

common_dir<-sprintf("%s/common",cauzality_path)

bayeslingam_dir<-sprintf("%s/bayeslingam",cauzality_path)    

rbayeslingam_dir<-sprintf("%s/bayeslingam/rbayeslingam",cauzality_path)

rlingam_dir<-sprintf("%s/rlingam",cauzality_path)

rdeal_dir<-sprintf("%s/rdeal",cauzality_path)

rpc_dir<-sprintf("%s/rpc",cauzality_path)

etudag_dir<-sprintf("%s/ETUDAG",cauzality_path)

実行に必要な他のパッケージのインストール

以下のパッケージをインストールする。
今回は'fastICA'のみでも可能。

Package Feature
deal GH-algorithm
mclust MoG Bayeslingam
combinat PC-algorithm
ggm PC-algorithm
fastICA Standard LiNGAM
gtools Some method's in ETUDAG use this package (not used by BL)
install.packages('PACKAGE')
library(PACKAGE)

動作確認

RStudioでbayeslingamを読み込む。

setwd(~/作業ディレクトリ)
library('fastICA')
source('bayeslingam/main/loud.R')
loud()

試しに実行してみる。
今回は以下の因果グラフを推定してみる。

image.png

まずはデータ生成。

x1 <- runif(5000, 0, 1)
x2 <- x1 + runif(5000, 0, 1)
x3 <- x1 + x2 + runif(5000, 0, 1)
x4 <- x1 + x3 + runif(5000, 0, 1)

データフレームに格納し、BayesLiNGAMを実施。

d <- data.frame(x1=x1, x2=x2, x3=x3, x4=x4)
result <- bayeslingam(d)

DAGsをみてみる。

> result$DAGs
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
  [1,]    1    2    3    4    0    0    0    0    0     0
  [2,]    1    2    3    4    0    0    0    0    0     1
  [3,]    1    2    3    4    0    0    0    0    1     0
  [4,]    1    2    3    4    0    0    0    0    1     1
  [5,]    1    2    3    4    0    0    0    1    0     0

1列目から4列目: 各変数の並び順。
e.g.)  [2,]はx1,x2,x3,x4を表す。

5列目から10列目: 有向線の有無を0,1で表す。1列目〜4列目で並べた変数から左の変数への有向線の有無を表す。
e.g.)  [5,]では[,5]はx1からx2への有向線なし。[,6]はx1からx3への有向線なし。[,7]はx1からx4への有向線なし。[,8]はx2からx3への有向線あり。[,9]はx2からx4への有向線なし。[,10]はx3からx4への有向線なし。

また、result$probはその行が表す因果グラフである推定確率を表す。

最後に、因果グラフを作る。

library(igraph)
par(mfrow=c(2,3))
prob <- round(result$prob,digits=4) * 100
n.node <- max(result$components$node)
case <- nrow(result$DAGs)
node <- result$DAGs[,1:n.node]
res <- as.matrix(result$DAGs[,-c(1:n.node)],nrow=case)
name <-paste("X",1:n.node,sep="")

for(i in order(prob,decreasing=T)[1:6]){
    amat <- matrix(0,n.node,n.node)
    index <- node[i,]
    amat[lower.tri(amat,diag=FALSE)] <- res[i,]
    amat <- t(amat[index,index])
    g <- graph.adjacency(amat,mode="directed")
    E(g)$label <- NA
    pos <- layout.circle(g)
    rot <- matrix(c(0,1,-1,0),nrow=2,byrow=T)
    la <- pos %*% rot
    if(n.node == 2)la <- matrix(c(-1,0.5,1,0.5),,nrow=2,byrow=T)
    plot(g,layout=la,vertex.size=70,vertex.label=name)
    mtext(paste(prob[i],"%"),line=0)
}

この結果が以下。

98%で因果グラフを特定することができた。

おわりに

基本的には、@m__k さんの「LiNGAMのベイズ的アプローチであるBayesLiNGAMを動かして見た」(https://qiita.com/m__k/items/288910248efafa106863)に沿って実行したらうまくいった。
あと、因子が5つ以上の場合に「greedybayeslingam()」を使用するらしいがうまくいかなかった。

参照

・LiNGAMのベイズ的アプローチであるBayesLiNGAMを動かして見た (@m__k さん)
https://qiita.com/m__k/items/288910248efafa106863
・NagoyaR19_因果分析 LiNGAMを試してみた (吉野睦 さん)
https://drive.google.com/file/d/0B5obiqfxcbRcNWZCaTloQlhoai1FN1JJRWJFUk9wSmRTdVFZ/view
・A→Bなのか、B→Aなのかをデータから見抜くことはできるだろうか?(LiNGAMのシミュレーションをしてみた)
https://blog.albert2005.co.jp/2015/02/24/a%E2%86%92b%E3%81%AA%E3%81%AE%E3%81%8B%E3%80%81b%E2%86%92a%E3%81%AA%E3%81%AE%E3%81%8B%E3%82%92%E3%83%87%E3%83%BC%E3%82%BF%E3%81%8B%E3%82%89%E8%A6%8B%E6%8A%9C%E3%81%8F%E3%81%93%E3%81%A8%E3%81%AF/
・BayesLiNGAM (IMOTO Yusuke さん)
https://sites.google.com/view/y-imoto/%E5%82%99%E5%BF%98%E9%8C%B2/bayeslingam

2
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7