CRF++

  • 暫定版 11/09
    	$file = "";#タグ付データ
    	$fileOut = "";#CRF++形式のファイルへ変換
    	
    	open(IN,$file);
    	open(OUT,">$fileOut");
    	while(<IN>){
    	chomp;
    	#タグを削除する
    	$after = $before  =$_;
    	print "[前]$before\n";
    	$after =~ s/<.*?>//g;
    	print "[後]$after\n";
    	#タグが付いている単語を格納する。
    	@tmp = split(/<\//);
    	undef %NE;
    	foreach(@tmp){
    		if(/^(.*)<(.*?)>(.*?)$/){
    			$pre  =$1;
    			$name  =$2;
    			$value =$3;
    			$NE{$value} .= "$name";
    		}
    	}
    	#タグを削除したデータを形態素解析する。
    	open(MECAB,">mecab.input");
    	print MECAB "$after";
    	close(MECAB);
    	#Mecab実行
    	@M = `/usr/local/bin/mecab -Ocrf < mecab.input`;
    	chomp @M;
    	#IOBタグ
    	#B: チャンクの先頭
    	#E: チャンクの末尾
    	#I : チャンクの内部
    	#S: 一つの語でチャンクを構成する
    	#O: チャンクの外部
    	undef $comb;
    	undef @Mp;#IOBタグ格納
    	for($i=0;$i<@M;$i++){
    		@Ms = split(/\s/,$M[$i]);
    		#print "$i $Ms[0] --> $M[$i]\n";
    		#マッチングのために結合
    		$comb .= "$Ms[0] ";
    		@combs = split(/ /,$comb);
    		#後ろから結合してマッチした単語にIOBタグを付与(暫定版)
    		undef $comb2;
    		for($j=@combs-1;$j>=0;$j--){
    			#$i までの状態を後ろから結合
    			$comb2 = $combs[$j] . $comb2;
    			#タグ付けされた単語と一致した場合、IOBタグを付与する。
    			if($NE{$comb2}){
    				$n = @combs - $j -1; 
    				#Bタグだけは最初につける	
    				$Mp[$i-$n] = "B-$NE{$comb2}";
    				#IタグはBタグの後につける
    				for($k=$i-$n+1;$k<=$i;$k++){
    					$Mp[$k] = "I-$NE{$comb2}";
    				}
    				last;
    			}
    		}
    	}
    	#print OUT "\n$before\n";
    	for($i=0;$i<@M;$i++){
    		if($Mp[$i]){
    			print OUT "$M[$i] $Mp[$i]\n";
    		}
    		else{
    			#タグが付けられていない場合、Oタグをつける
    			print OUT "$M[$i] O\n";
    		}
    	}
    	}
    	close(OUT);
    	close(IN);