チュートリアル:ぱらぱらめくる『ZDD Ruby Package Documentation』

  • 2.1 ZDDライブラリをrequireで取り込む
$ irb
    • として対話モードで始めてみる
    • 対話モードになったら、まず、zddをgemで入れた先をLOAD_PATHする
> $LOAD_PATH.push("/home/ryamada/.gem/ruby/2.2.0/gems/zdd-1.0.0-linux/lib/nysol/")
    • その上で
> require 'zdd'
  • 2.2 アイテム
    • ZDDはアイテムが順序を持って登録されているところに、2種類のエッジを使ってグラフを作るし、そのときに、アイテムがどういう順序になっているかが重要だから
    • まずは、アイテム登録が必要
    • 一つずつ登録するのがZDD::symbol()
    • 一度に複数登録するのがZDD::item()
    • ただし、アイテムには必須ではないが「値」を持たせることができて、値を任意に与えようと思ったらsymbol()を使う必要がある
    • symbol()を使って一つずつ登録してみる
      • まず、何も登録していない状態で、どんなアイテム・シンボルがあるかを訊いてみると、何もないので、空白行(何もなし)が返り、それを受けて=> nilというこのコマンドの実行結果が返っている
puts ZDD.symbol
irb(main):007:0> require 'zdd'
=> true
irb(main):008:0> puts ZDD.symbol

=> nil
      • では、一つずつ登録することにする。"p"を登録すると…
irb(main):009:0> ZDD.symbol("p")
=> true
irb(main):010:0> puts ZDD.symbol
p 
=> nil
      • 追加する
irb(main):011:0> ZDD.symbol("r")
=> true
irb(main):012:0> puts ZDD.symbol
p r 
=> nil
      • まとめて登録するにはZDD.itemset()を使う
irb(main):013:0> ZDD.itemset("s t y")
=> s t y
irb(main):014:0> puts ZDD.symbol
p r s t y 
=> nil
      • 下に付け加えられるだけなので、先頭に入れることにする(先頭か末尾にしか入れられない)
        • "top"を指定するときにZDD.symbol()を使うが、このときはアイテム名称に引き続いて、値を与え、第3引数として"top"を指定する
irb(main):015:0> ZDD.symbol("n","top")
RuntimeError: argument type error (arguments must be FLOAT or INT or NIL)
	from (irb):15:in `symbol'
	from (irb):15
	from /usr/bin/irb:11:in `<main>'
irb(main):016:0> ZDD.symbol("n",0.5,"top")
=> true
irb(main):017:0> puts ZDD.symbol
n p r s t y 
=> nil
    • アイテムセット
      • ZDDではオブジェクトはアイテムの全体集合の部分集合である。それをアイテム・セットと呼ぶ
      • すでにsymbol()やitemset()によってアイテム登録した中からアイテムを選んで、アイテムのセットis1とすることもできるし
irb(main):019:0> is1 =ZDD.itemset("p r")
=> p r
irb(main):020:0> is1
=> p r
irb(main):021:0> is1.show
 p r
=> p r
    • 未登録のアイテムを使ってアイテムセットのオブジェクトを指定すれば、アイテム登録を同時に行う
irb(main):022:0> is2 = ZDD.itemset("s t z")
=> s t z
irb(main):023:0> is2
=> s t z
irb(main):024:0> puts ZDD.symbol
n p r s t y z 
=> nil
  • 2.3 演算
    • ZDDには演算が定義されている。その詳細は次の記事「演算子・メソッド」で扱う
    • 基本的には、加算によって要素数が増え、乗算によって要素の次数が上がる。減算と除算はその逆の作用がある
  • 2.4 頻出アイテム集合
    • ZDDが得意な分野
    • 関連するものとして、頻出アイテム集合のほか、頻出極大アイテム集合、頻出飽和アイテム集合の3つがある
    • それぞれに関数があるとともに、3つをオプションで実行しわけるlcm()関数がある
      • lcm()関数はテキストファイル読み込みであること、要素が1,2,...と順序整数であること、という制約はあるものの、高速アルゴリズムで実装してある
      • 3タイプの頻出集合があり、それぞれの出力に「アイテムセット列挙」のみにするか、「アイテムセットの登場回数情報を付与して出力」するかの2通りがあり、都合、6通りの実行の方法がある
ZDD::lcm("F","trans.txt",2,"order.txt")
ZDD::lcm("M","trans.txt",2,"order.txt")
ZDD::lcm("C","trans.txt",2,"order.txt")
ZDD::lcm("FQ","trans.txt",2,"order.txt")
ZDD::lcm("MQ","trans.txt",2,"order.txt")
ZDD::lcm("CQ","trans.txt",2,"order.txt")
        • order.txt
1 2 3 4 5 6
          • trans.txt
1 2 3 6
4 5 6
1 2 4 6
2 4 6
1 2 4 5
    • メモ代わりのorder.txt,trans.txtファイルの作成Rコード
n.sample <- 200
n.gene <- 100
g <- matrix(sample(0:1,n.sample*n.gene,replace=TRUE,prob=c(0.7,0.3)),nrow=n.sample)

n.e <- 10
rs <- rpois(n.e,2)
effects <- sample(1:n.e)

cmb <- list()
for(i in 1:n.e){
  cmb[[i]] <- sample(1:n.gene,rs[i])
}

scores <- rep(0,n.sample)
for(i in 1:n.e){
  if(length(cmb[[i]])!=0){
    tmp <- matrix(g[,cmb[[i]]],nrow=n.sample)
    tmp2 <- apply(tmp,1,prod)
    tmp3 <- which(tmp2==1)
    if(length(tmp3)>0){
      scores[tmp3] <- scores[tmp3] + effects[i]
    }
  }
}

phenotype <- rep(0,n.sample)
phenotype[which(scores > quantile(scores,0.5))] <- 1

g. <- list()
for(i in 1:n.sample){
  if(phenotype[i]==0){
    g.[[i]] <- which(g[i,]==0)
  }else{
    g.[[i]] <- which(g[i,]==1)
  }
}

tab <- c()
for(i in 1:n.sample){
  ca= paste(g.[[i]], collapse=" ")
  tab <- append(tab,ca)
}
out <- file("trans.txt", "w")
write.table(tab,out,row.names=F,col.names=F,quote=F)

close(out)

order <- seq(1:n.gene)
order <- paste(order,collapse=" ")
out2 <- file("order.txt", "w")
write.table(order,out2,row.names=F,col.names=F,quote=F)

close(out2)

  • 2.5 キャスト
    • ZDDでは整数も文字列もすべてZDDオブジェクトにキャストされてZDD演算に乗せられている
a = ZDD::itemset("a")
a*3 # これはOK
2*a # これはエラーになるかもしれない…キャストできていないから?
  • 2.6 制御文を使ってより柔軟に