マルコフ連鎖に今頃はまる

2010年 01月 22日

    まずChaSenをlocalにインストール。
    今回はcygwin面倒なので、ココからchasen233_031208.exe をダウンロードして実行。

    WIN用のものはSJIS。
    linux用のはEUC-JP。

    次にこのディレクトリにPATHを通す必要があるので、環境変数から指定してください。
    そうしたら、コマンドプロンプトで実行して使えるようになる。

    XREA上では、PHPをCGI版で実行するので、プログラムが存在するディレクトリに.htaccessにて以下を忘れずに。

    AddHandler application/x-httpd-phpcgi .php
    

    XREA上のChaSenのパスは以下で、どちらも動くらしいです。

    /usr/local/bin/chasen
    /usr/local/php/bin/chasen
    

    【参照】
    あいねこの館様

    文章のピックアップに困りRSSより語彙を取得して生成することにしてみた。

    <?php
    
    //PEAR
    require_once("XML/RSS.php");
    
    if($_POST["markov"] != "" && $_POST["url"] != ""){
    	// ChaSenのパス
    	$chasen = '/usr/local/php/bin/chasen';
    
    	// RSSのパス
    	$url = $_POST["url"];
    
    	$wakatigaki = array();
    	$markov = array();
    
    	$RSS = & new XML_RSS($url);
    	$RSS->parse();
    
    	// 形態素解析を行う文章
    	$rand = array_rand($RSS->items);
    	$str = $RSS->items[$rand]["description"];
    
    	// 形態素解析をしたい文章を渡しながら、ChaSenへのハンドルオープン
    	$handle = popen("echo '$str' | $chasen ", 'r');
    
    	// 結果を1行ずつ取得
    	while ($get_chasen = fgets ($handle)){
    		// ChaSenの結果がTAB区切りなので\tで分解
    		$kaiseki = split ("\t", $get_chasen);
    
    		// $wakatigaki 配列へ 分ち書きしたデータを格納
    		$wakatigaki[] = $kaiseki[0];
    	}
    
    	//ハンドルを閉じ
    	pclose ($handle);
    
    	if (count($wakatigaki) > 2) {
    		//2語の接頭語と1語の接尾語のマルコフ連鎖テーブルを作成
    
    		for ($i = 2 ; $i < count($wakatigaki) ; $i++) {
    			if ($i < count($wakatigaki)) {
    				$markov{$wakatigaki[$i-2]}{$wakatigaki[$i-1]}[] = $wakatigaki[$i];
    			}
    		}
    
    	} else {
    		print "データが少ないのでマルコフ連鎖が行えません。<br />";
    		exit();
    	}
    
    	// *マルコフ連鎖で文章生成--
    	// 文章出だしを接頭語前に
    	$pre1 = $wakatigaki[0];
    
    	// 接頭語後ろは、接頭語前に続く文字からランダム選択
    	$pre2 = array_rand ($markov{$pre1});
    
    	// 接尾語は選択できる中からランダムに選択
    	$rand = rand (0, (count ($markov{$pre1}{$pre2}) - 1));
    	$suf1 = $markov{$pre1}{$pre2}[$rand];
    
    	$res = $pre1.$pre2.$suf1;
    
    	for ($i=0 ; $i<1000 ; $i++) {
    		$pre1 = $pre2;
    		$pre2 = $suf1;
    		// 接尾語は選択できる中からランダムに選択
    		$rand = rand (0, (count ($markov{$pre1}{$pre2}) - 1));
    		$suf1 = $markov{$pre1}{$pre2}[$rand];
    
    		if ($suf1 == "EOS\n") {
    			break;
    		}
    
    		$res .= $suf1;
    	}
    	//--
    
    }
    ?>
    

    「.cgi」で使用する場合は以下を先頭に記述(<?phpの前に)
    #!/usr/local/bin/php

    #!/usr/local/bin/php
    <?php
    

    こんな感じ

    フェードなどのxmlデータをPOSTで受け取り、語の区切りを自動で読み込み
    再文章化して$resで返します。

    マルコフ連鎖サンプル

    冒頭で、「まずChaSenインストール」などと言っているが、これだけでかなりの記事が書けそう。
    これ凄いなー。

    ★☆★☆★☆ ナウでヤングなレンタルサーバー!ロリポップ! ☆★☆★☆★
    月額105円~容量最大30GB!WordpressやMovable Typeの簡単インストール付★

    Post a Comment