OSDN Git Service

ver1.1
[nysol/mining.git] / take / bin / mitemset.rb
diff --git a/take/bin/mitemset.rb b/take/bin/mitemset.rb
new file mode 100755 (executable)
index 0000000..53c24c6
--- /dev/null
@@ -0,0 +1,158 @@
+#!/usr/bin/env ruby
+# encoding: utf-8
+
+require "fileutils"
+require "rubygems"
+require "traDB.rb"
+require "taxonomy.rb"
+require "cls.rb"
+require "caep.rb"
+
+def help
+
+STDERR.puts <<EOF
+----------------------------
+mitemset.rb version 1.0
+----------------------------
+概要) LCMにより多頻度アイテム集合を列挙する
+特徴) 1) 分類階層を扱うことが可能
+      2) 頻出パターン, 飽和頻出パターン, 極大頻出パターンの3種類のパターンを列挙可能
+      3) クラスを指定することで、上記3パターンに関する顕在パターン(emerging patterns)を列挙可能
+書式) mitemset.rb i= [x=] [c=] [O=] [tid=] [item=] [taxo=] [class=] [type=] [s=] [S=] [l=] [u=] [top=] [-replaceTaxo] [T=] [-debug] [--help]
+
+例) mitemset.rb i=basket.csv tid=traID item=商品
+
+  ファイル名指定
+  i= : アイテム集合データベースファイル名【必須】
+  c= : クラスファイル名【オプション】*1
+  x= : taxonomyファイル名【オブション】*1
+  O= : 出力ディレクトリ名【オプション:default:./take_現在日付時刻】
+
+  項目名指定
+  tid=   : トランザクションID項目名(i=上の項目名)【必須】
+  item=  : アイテム項目名(i=上の項目名)【必須】
+  class= : クラス項目名(c=上の項目名)【オプション:default="class"】
+  taxo=  : 分類項目名を指定する(x=上の項目名)【条件付き必須:x=】
+
+  列挙パラメータ
+  type= : 抽出するパターンの型【オプション:default:F, F:頻出集合, C:飽和集合, M:極大集合】
+  s=    : 最小支持度(全トランザクション数に対する割合による指定)【オプション:default:0.05, 0以上1以下の実数】
+  S=    : 最小支持度(件数による指定)【オプション】
+  l=    : パターンサイズの下限(1以上20以下の整数)【オプション:default:1】
+  u=    : パターンサイズの上限(1以上20以下の整数)【オプション:default:4】
+  p=    : 最小事後確率【オプション:default:0.6】
+  g=    : 最小増加率【オプション:default:1.5】
+  top=  : 列挙するパターン数の上限【オプション:default:10000】*2
+          0を指定すると制限なしとなる。
+
+  その他
+  -replaceTaxo : taxonomyを置換する
+  T= : ワークディレクトリ(default:/tmp)
+  -debug : デバッグモード(メッセージを詳細に出力し,ワークファイルを消去しない)
+  --help : ヘルプの表示
+
+  注釈
+  *1 x=が指定されたとき、itemに対応するtaxonomyをトランザクションに追加して実行する。例えば、アイテムa,bのtaxonomyをX、c,dのtaxonomyをYとすると、あるトランザクションabdはabdXYとなる。
+     ただし-replaceTaxoが指定されると、taxonomyは追加ではなく置換して実行する。前例ではトランザクションabdはXYに置換される。
+  *2 top=が指定された時の動作: 例えばtop=10と指定すると、支持度が10番目高いパターンの支持度を最小支持度として頻出パターンを列挙する。よって、同じ支持度のパターンが複数個ある場合は10個以上のパターンが列挙されるかもしれない。
+
+# より詳しい情報源 http://www.nysol.jp
+# LCMの詳しい情報源 http://research.nii.ac.jp/~uno/codes-j.htm
+# Copyright(c) NYSOL 2012- All Rights Reserved.
+EOF
+exit
+end
+
+help() if ARGV.size <= 0
+
+args=MCMD::Margs.new(ARGV,"i=,c=,x=,O=,tid=,item=,class=,taxo=,type=,s=,S=,g=,p=,-uniform,l=,u=,top=,T=,-replaceTaxo,--help,-debug")
+help() if args.bool("--help")
+
+iFile   = args.file("i=","r")
+cFile   = args.file("c=","r")
+xFile   = args.file("x=","r")
+
+t=Time.now
+outPath = args.file("O=", "w", "./take_#{t.year}#{t.month}#{t.day}#{t.hour}#{t.min}#{t.sec}")
+
+idFN   = args.field("tid=",     iFile, "tid"  )
+itemFN = args.field("item=",    iFile, "item" )
+clsFN  = args.field("class=",   cFile, "class")
+taxoFN = args.field("taxo=",    xFile, "taxo" )
+idFN   = idFN["names"].join(",")   if idFN
+itemFN = itemFN["names"].join(",") if itemFN
+clsFN  = clsFN["names"].join(",")  if clsFN
+taxoFN = taxoFN["names"].join(",") if taxoFN
+
+eArgs=Hash.new
+eArgs["type"   ] = args.  str("type=","F" )
+eArgs["minSup" ] = args.float("s="   ,0.05 ,0  ,1      ) # 最小サポート
+eArgs["minCnt" ] = args.  int("S="   ,0    ,0          ) # 最小サポート件数
+eArgs["minProb"] = args.float("p="   ,0.6  ,0.5,1      ) # 最小事後確率
+eArgs["minGR"  ] = args.float("g="   ,nil  ,1.0,nil    ) # 最小GR
+eArgs["uniform"] = args. bool("-uniform") # クラス事前確率を一様と考えるかどうか
+eArgs["minLen" ] = args.  int("l="   ,1    ,1  ,20     )
+eArgs["maxLen" ] = args.  int("u="   ,5    ,1  ,20     )
+eArgs["top"    ] = args.  int("top=" ,10000,0  ,1000000)
+
+eArgs["nomodel"] = true
+
+if ["F","C","M"].index(eArgs["type"]) == nil then
+       raise "type= takes one of values: 'F', 'C', 'M'"
+end
+
+if eArgs["minLen"] > eArgs["maxLen"] then
+       raise "u= must be greater than or equal to l="
+end
+
+if eArgs["type"]=="M" then
+       eArgs["top"]=0
+end
+
+# 実行環境の設定
+# KG_VerboseLevel: スクリプト内部で利用するMCMDの表示メッセージ
+# KG_ScpVerboseLevel: スクリプトの表示メッセージ
+if args.bool("-debug") then
+       ENV["KG_VerboseLevel"]    = "4"
+       ENV["KG_ScpVerboseLevel"] = "4"
+else
+       ENV["KG_VerboseLevel"]    = "2"
+       ENV["KG_ScpVerboseLevel"] = "4"
+end
+
+#ワークファイルパス
+if args.str("T=")!=nil then
+       ENV["KG_TmpPath"] = args.str("T=").sub(/\/$/,"")
+end
+
+# V型DBの読み込み
+db=TAKE::TraDB.new(iFile,idFN,itemFN)
+
+# クラスファイルがあれば読み込み
+cls=nil
+if cFile!=nil then
+       cls=TAKE::Cls.new(cFile,idFN,clsFN,nil)
+end
+
+# taxonomyのセット
+taxo=nil
+if xFile!=nil then
+       taxo=TAKE::Taxonomy.new(xFile,itemFN,taxoFN)
+       if args.bool("-replaceTaxo") then
+               db.repTaxo(taxo) # taxonomyの置換
+       else
+               db.addTaxo(taxo) # taxonomyの追加
+       end
+end
+
+# モデル構築
+model=TAKE::Caep.new(db,cls,eArgs)
+
+# 出力
+system("mkdir -p #{outPath}")
+model.output(outPath)
+
+MCMD::msgLog("The final results are in the directory `#{outPath}'")
+
+# 終了メッセージ
+MCMD::endLog("#{$0} #{args.argv.join(' ')}")