goo blog サービス終了のお知らせ 

13F

備忘録

Apache LuceneのNGramTokenizer

2007-08-14 22:53:54 | Weblog
Apache Lucene で全文検索するようなアプリケーションを作成中。とりあえず CJKAnalyzer かと思っていたら こちら で NGramTokenizer という便利そうなものが紹介されていたので使おうとしてみた。

まず Analyzer が必要なので以下のようなものを作成。
public class NGramAnalyzer extends Analyzer {
  protected int minGram;
  protected int maxGram;

  public NGramAnalyzer(int minGram, int maxGram) {
    this.minGram = minGram;
    this.maxGram = maxGram;
  }

  public TokenStream tokenStream(String fieldName, Reader reader) {
    return new NGramTokenizer(reader, minGram, maxGram);
  }
}

インデックスの作成はこれでうまくいく。
Analyzer analyzer = new NGramAnalyzer(1, 3);
IndexWriter writer = new IndexWriter(new RAMDirectory(), analyzer);
// ドキュメントの追加...

ところが、検索のほうは minGram と maxGram が異なるケースではうまくいかない。
Analyzer analyzer = new NGramAnalyzer(1, 3);
QueryParser parser = new QueryParser(queryString, analyzer);
// queryString が 1文字の場合以外はマッチしない

ほんの少しソースを見ただけだけど、どうも QueryParserが、TokenStream が返す Token の位置情報を使わずに PhraseQuery を構築してしまっているのが原因っぽい気がする。

QueryParserをいじればいいんだけど、標準配布物をいじるのはどうも気が進まないので、家に帰ってからこんなのを捏造してみた(動作未確認)。
public class NGramAnalyzerForQuery extends NGramAnalyzer {

  public NGramAnalyzerForQuery(int minGram, int maxGram) {
    super(minGram, maxGram);
  }

  public TokenStream tokenStream(String fieldName, Reader reader) {

    int read = 0;

    try {
      char[] buf = new char[maxGram];

      // 検索語の文字数を確認する
      while (read < maxGram) {
        int c = reader.read();
        if (c == -1) {
          break;
        }
        buf[read] = (char)c;
        read++;
      }

      if (read > 0) {
        // 読んでしまった分を戻す
        PushbackReader pbReader = new PushbackReader(reader, read);
        pbReader.unread(buf, 0, read);
        reader = pbReader;
      }
    }
    catch (IOException e) {
      throw new RuntimeException(e);
    }

    if (read < maxGram) {
      return new NGramTokenizer(reader, read, read);
    }
    else {
      return new NGramTokenizer(reader, maxGram, maxGram);
    }
  }
}

基本は maxGram で分割し、検索語の長さが maxGram 未満の場合だけ、検索語の文字数で分割する(といっても1つのトークンになるだけ)。検索のときだけこっちを使うようにしたらうまくいけばいいなあということで明日試す。
Analyzer analyzer = new NGramAnalyzerForQuery(1, 3);
QueryParser parser = new QueryParser(queryString, analyzer);

東方体験版プレイ中

2007-08-14 00:31:43 | Weblog
相変わらず少しずつプレイ中。例のFlashから入ったのでなんとなく妖々夢から。でキャラは魔理沙が最多。

最初はコンティニュー全部使っても3面ボスまでたどり着けない状態だったけど、とりあえずNormalでは全キャラクタで3面までコンティニューなしで安定して制覇できるようになった。

* 弾幕を見ただけで避ける気をなくし、ああもう当たってもいいや的な心理状態で集中力を欠くプレイになり被弾
⇒ くじけないで弾幕を良く見る。ずっと低速だけではなくて、ボス戦でも時には高速移動で大きな回避をする。

* 魔理沙は攻撃範囲が狭いので、ボスを正面に捉えようと相手ばかり注目して弾に当たる
⇒ 基本は自機の周りに集中しつつ、下に出てくるボスX座標マーカーみたいのを視界の端で追って対応(「集中し、かつ心をひとつところにとどめぬこと」というどこかの漫画のような心構えで……)

* RPG的なアイテムホルダー癖が抜けず、ボム満タンのまま死亡
⇒ 危ないと思ったらすぐに使う。橙全般・仏蘭西人形・倫敦人形あたりは苦手なのであるだけ使う。苦手な攻撃でも、ボム満タンで絶対に死ねない!という状態より、ボムが切れてから気楽な気持ちで避けたほうがうまく避けられる気もする。

今のところの傾向と対策はこんなところか。シューティングは脳が活性化する気がする。

東方妖々夢とPC環境

2007-08-13 00:19:55 | Weblog
東方妖々夢の体験版での問題。

わたしの環境では、Stage1でボス音楽に切り替わるときにCPU使用率が異常に高くなってフリーズしてしまっていた。どうもオーディオドライバの不具合か何かだったらしく、マニュアルのFAQにある通りドライバを最新版に更新したらあっさり直った。

ちなみに、Windowsのオーディオデバイスの詳細で出てくる「SoundMAX」で検索してもドライバは全く出てこず。マザーボードのメーカーのサイト(ASUS)に行くのが正しかった。

このハードウェア音痴はどうにかしたいんだけど、こういうPC自作的な知識はどこで身につければいいのやら。

東方シリーズ買った

2007-08-12 23:04:33 | Weblog
* ニコニコ動画で「魔理沙は大変なものを盗んでいきました」を見て「東方Project」というものの存在を知る

* でもシューティング下手だしそんなに興味ないなあ

* 東方原曲ランキングを聴いて音楽の素晴らしさにびっくり。

* やっぱりゲームやってみるかと体験版ダウンロード。

* 適度に手ごたえがあって面白い。最近RPGばっかだったけど手軽にサクサクできるシューティングもいいなあ。でもキーボード操作つらい……

* とりあえず紅魔郷・妖々夢・永夜抄とゲームパッドコンバータを注文

いまここ。

同人ソフトはAmazonで売ってないので残念ながら市場には反映されないけど、ニコニコ動画は結構消費欲を刺激する。前から気にはなっていた「Ovlibion」だけど、「テクテク冒険記」見てXbox360の購入を真剣に検討中だし。