2012/04/05

名詞入れ替えで作文

EasyBotter.phpを以下のように改造して様子見中。あまり正規表現に詳しくないので悲惨なことになっております。

template.csvはあらかじめ作成していたものを、word.csvは、キーフレーズ抽出時にこっそり保存していたものを流用しています。

class EasyBotter {
  // キーフレーズ置換で発言を作る
  private function makeSwapKeyPhraseTweet() {
    $keyphrase = array();
    $poem = array();
    $table = "。";
    $status = "";
    // キーフレーズCSVを読み込み
    $fp = fopen('word.csv', 'r') or die('ファイルが開けません');
    while(($columns = fgetcsv($fp, 4096, ",", '"')) !== FALSE) {
      array_push($keyphrase, $columns[0]);
    }
    fclose($fp);
    shuffle($keyphrase);
    // 原文CSVを読み込み
    $fp = fopen('template.csv', 'r') or die('原文ファイルが開けません');
    while(($columns = fgetcsv($fp, 4096, ",", '"')) !== FALSE) {
      array_push($poem, array($columns[0], $columns[1]));
    }
    fclose($fp);
    // 名詞を適当に入れ替える
    $keyphrase_num = count($keyphrase);
    $rd_keys = array_rand(array_filter($poem, 'is_noun'), $keyphrase_num);
    for($i=0; $i<$keyphrase_num; $i++) {
      $poem[$rd_keys[$i]][0] = $keyphrase[$i];
    }
    // テーブル作成
    for($i=0; $i<count($poem); $i++) {
      $table .= $poem[$i][0];
    }
    // 一致している間は選びなおす
    $status_1 = "";
    $status_2 = "";
    while($status_1 === $status_2) {
      // キーフレーズを選出×2
      $rd_keys = array_rand($keyphrase, 2);
      
      $matches_1 = array();
      $matches_2 = array();
      
      $pattern_1 = '/^(.*)[。?](.*?)'.$keyphrase[$rd_keys[0]].'(.*?[。?])/u';
      $pattern_2 = '/^(.*)[。?](.*?)'.$keyphrase[$rd_keys[1]].'(.*?[。?])/u';
      
      preg_match_all($pattern_1, $table, $matches_1);
      preg_match_all($pattern_2, $table, $matches_2);
      
      $status_1 = $matches_1[2][0].$keyphrase[$rd_keys[0]].$matches_1[3][0];
      $status_2 = $matches_2[2][0].$keyphrase[$rd_keys[1]].$matches_2[3][0];
    }
    $status = "「".$status_1.$status_2."」";
    return $status;
  }

  // 途中省略

  private function makeReplyTweets($replies, $replyFile, $replyPatternFile){
    if(empty($this->_replyPatternData[$replyPatternFile]) && !empty($replyPatternFile)){
      $this->_replyPatternData[$replyPatternFile] = $this->readPatternFile($replyPatternFile);
    }
    $replyTweets = array();
    foreach($replies as $reply){
      $status = "";
      // 追加ここから
      if(strpos((string)$reply->text, "作文して") !== FALSE) {
        // キーフレーズで作文
        $status = $this->makeSwapKeyPhraseTweet();
      }
      // 追加ここまで
    // 以下省略
    }
  }
}

各データファイルの構造

word.csv

1行1カラムの単純なデータです。相手のキーフレーズ+定型文で作文 でこっそり保存していたものです。

"スカイツリー"
"お台場"
"実績取り"
"競合他社"
"以下略"
"デスマッチ"
"中心"
"沿岸部"

template.csv

元となる作文をあらかじめ形態素解析しておいたものです。この中から名詞をランダムに取り出して、word.csvの中身と入れ替えています。

"太陽系","名詞"
"に","助詞"
"生物","名詞"
"が","助詞"
"生息","名詞"
"する","助動詞"
"こと","名詞"
"を","助詞"
"奇跡的","形容動詞"
"に","助詞"
"可能","名詞"
"に","助詞"
"し","動詞"
"た","助動詞"
"惑星","名詞"
"、","特殊"
"それ","名詞"
"が","助詞"
"地球","名詞"
"で","助動詞"
"ある","助動詞"
"。","特殊"