...

類似文字列検索エンジンApporo の応用

by user

on
Category: Documents
20

views

Report

Comments

Transcript

類似文字列検索エンジンApporo の応用
類似文字列
検索エンジン
Apporo の応用
@overlast
アジェンダ
• プロトタイプ開発と Perl
• Apporo とは
• Apporo の使いどころ
• 使用例(コマンドライン、Perl)
• まとめ
• 当日の資料を改変しました。大筋は同じ内容です。
@overlast の自己紹介
• さとう としのり
柔軟
• blog : http://diary.overlasting.net/
• 普段やっていること
• 企業でスペルミスを訂正する手法を研究開発
• 例 : 入力 : aiphone => 出力 : iphone では?
• 近況
• 類似文字列検索エンジン Apporo の開発
• DSIRNLP 勉強会を主催
• データ構造・検索・自然言語処理・機械学習
• Mining the Social Web の監訳に参加
プロトタイプ開発
と
Perl
要素技術の開発には試作が必須
• 要素技術 = 製品を構成する要素に関わる技術
– 妥当な性能を達成していることを要求される
– 例 : 話しことばで検索できる質問応答掲示板
• 要素技術「形態素解析」「全文検索」は使えて当然
• 要素技術開発の最初のゴール = 性能の達成(not 仕様の達成)
– 世の中には、仕様が無いがゴールだけ明確な場合がある案件がある
– 例 :
• 研究(この世に無い技術を生む or 関連研究以上の性能を出す)
• デザイン(アピール力があり、クライアントが納得する形を生む)
• 仕様が無い案件 = 調査、分析、試作を繰り返す必要がある
– 仕様がないので、妥当な設計の発見を繰り返す
• 駄目な設計は将来の悲劇を生むので、最初は方向性だけ決めよう
• 汎用性は、複数の固有の事例の共通部分から見出そう
• 必要な技術の開発期間や依存関係を考慮して計画をたてよう
要素技術を4Stepで開発する例
• 0. 解決したい問題(テーマ)を決める
• 1. 発見
– 問題解決に使える技術・理論を探して、発見する
– 価値ある発見の後、試作して少量の問題を解く
• 2. デモ
– ブラウザからいじれる最小限のデモを作る
• 適用先のデータを使い、試作者以外とも議論
• 使い方と使われ方のギャップを埋めて大きな失敗を防ぐ
• 3. 判断
– 完成した時期に実用した際の有益度を判断する
• 実用的か? 応用しやすいか? 伸びしろはあるか?
• 4. 開発 or 封印
– 有益度高 : 本気の開発を始める
– 有益度低 : 捨てる、作り直る、テーマを変える
Perl でプロトタイプを作る利点
• まったく、Perl は最高だぜ!と僕が感じるポイント
– 柔軟な文法
• 作るべきモノがハッキリしない時期に最適
• 技術を考慮しないリクエストに素早く対処できる
– 高い移植性
• 計算機クラスタごとにOSが違っても書き換えなくてOK
– 環境に依存するモジュールは使いにくいけど
– 再利用性
• コードを書いた時期より後にリリースされた Perl 5 で動く
– 他の言語を見てるとバージョンアップしても動くってすごい
– 数年前に試作したコードをそのまま利用出来る
– 人
• 豊富な CPAN モジュールと格好良いコミュニティ
– 友人や知人の作った実装を使えるのは、気持ち良い
Perl だけで要素技術を開発しきれる?
• No !!! それは無理だ !!!
• Perl だけではやりにくいことの例
– a. 複雑で高速な大規模データ処理をしたい
• Perl はメモリの消費量多く、変数のデータ構造が冗長
• データを複雑 or 高速に処理するならC/C++から逃げられない
– b. Perl で書かれていない有益な実装を使いたい
• 例 : Hadoop, Luceneは Java 以外からはヘビーに使いにくい
– c. 新しい計算機クラスタが必要になった
• 自分で構築した方がコストが低い場合も多い
• 他人に任せるなら、設定ミスを発見できる能力が必要
– d. この世になかった技術を形にしたい
• 例えばたまたま、まだOSSになっていない技術が必要になった
– Perl だけに詳しくても新しいものは作れない
– コンピューターサイエンスを必要に応じて学ぶべき
Perl から C/C++ への置き換え例
• 自然言語処理・検索などで使う技術
– 複雑で高速な大規模データ処理が必要 => いつかはC/C++化
• 要素技術開発の利益最大化
– 試作から最速で実用化 => 高精度化・高速化 => 整理整とん
• とあるアプリケーションを全部 C++ で書き換えるまでのStep例
– Perl スクリプト 1 ファイルのデモを作成
– 設計を大雑把に考えて Perl モジュール化
– 実際のデータを使って不具合を発見し、修正する
– パフォーマンス測定をする
– ボトルネックな部分をC/C++化しつつ、Perl で新機能を足す
• このあたりで実用化できることが多い
– 徐々に C/C++ 率を上げつつ、XSを書く & まだ Perl からも呼ぶ
– すべての Perl コードを C/C++ に置き換え + XS からのみ呼ぶ
プロトタイプ開発と Perl のまとめ
• 要素技術を開発するときは、いきなり全部作らない
– 駄目設計の汎用ライブラリは悲劇を生む
– 必要性を予測して、事前に調査・試作・検討
– 最初は汎用性を高めすぎないことも大切
• 試作は Perl でやっておくと良いかも
– 経験上、一度書いたコードを長年使いまわせた
– デモへの突然の注文を反映するコストが低かった
• なんでも Perl で(単一言語で)やるのは最適でない
– 開発速度とメンテナンス頻度のバランスをとろう
– 複雑な処理は、後でC/C++で書きなおして高速化
Apporoとは
Apporo の概要
• 開発の経緯
– 求める機能をもつ手軽なライブラリがない
• 目標
– お手軽で高速な類似文字列検索を実現したい
• どんな感じか
– 準備 : 辞書を用意し、事前に indexing する
– 入力 : 任意の文字列
– 出力 : 入力と文字列距離の近い辞書エントリ
– Perl から利用できる(Perl で試作してたので)
Apporo の技術的な情報
• 開発言語 C++(Perl 拡張を用意)
• indexのデータ構造
– Suffix Array / [今後]転置index
• SA の場合は任意の文字N-gramで検索できる
• 検索に使えるクエリの情報
– クエリの(表層|[開発中]読み|[今後]ローマ字)
• 候補をランキングするスコア
– Bit Parallel Matching法による編集距離計算
Apporo の競合との比較
Apache Lucene
SimString
検索indexの データ構造
転置index
転置index
検索速度
チューニング次第 爆速
Apporo
Suffix Array (今後、転置index
も)
実用的な速度 (今後さらに速く)
indexファイルの量 Segmentの設定次 辞書エントリの最
第
大バイト長 * N
2
取得した候補の あり
リランキング機能
なし
あり
検索に使える クエリの情報
頑張り次第
表層
表層 / (開発中)読
み/(今後)ローマ字
開発言語
Java
C++(Python, Ruby) C++(Perl, Python)
実装を選択する 妥当な理由
Luceneを使用(して 取得候補のリラン
いる|する予定) キングが不要
それ以外なら Apporo を試して!
ソースコード(New BSDライセンス)
http://code.google.com/p/apporo/
Apporo
の
使いどころ
Apporo の使いどころ(1/2)
• 例1 : 検索結果ゼロ件の検索クエリに対処できる
• 「人間なら分かるクエリ」は修正すべき
検索クエリの訂正は必須
• 今や訂正は、やって当たり前
• 特にモバイル向けでは必須
• 移動中の正確な入力は大変
ユーザー :
(ですよね。)
ユーザー :
「見つかりません」??
何を言ってるの(怒)
• 顧客の入力に未対処 = それってバグと言えるのでは?
• 検索結果ゼロ件のクエリを集計して観察しよう
• 観察に基づき類似文字列検索を適用し顧客のストレスを減らそう
Apporo によるクエリ訂正
• 例1 : 誤りを含むクエリに近い正しいクエリを探す
• Step1. 最初にクエリログを2種類に分けて集計する
• a. 正しいクエリ : 検索結果を得られた
• b. 誤りを含むクエリ : 検索結果を得られなかった
• Step2. 検索結果を得られたクエリのリストをindexing
• Step3. 試してみて、パラメタを調整する
• 誤りを含むクエリのリストで性能をテスト
• 例2 :誤りを含むクエリに近いタイトルを探す
• Step1. 検索対象の文書からタイトルを抽出しリスト化
• Step2. Step1で得たリストをindexing
• Step3. 試してみて、パラメタを調整する
• 別途集計した誤りを含むクエリのリストでテスト
Apporo の使いどころ(2/2)
• 例2 : 辞書メンテナンスコストの軽減できる
• 異表記を列挙せず類似文字列検索をする
• 異表記を列挙するコストを新語登録に回せる
• 事例
• a. 薬事法違反のテキストを探す
• 辞書中に「たった1回でツルツル」があれば
• 「たった1回でトゥルトゥル」も見つかる
• b. 援助交際関連の発言を探す
• 辞書中に「苺」があれば
• 「いちご」「イチゴ」「一護」も見つかる
• c. ビル名やランドマーク名を探す
• 辞書中に「六本木ヒルズ森タワー」があれば
• 「ヒルーズ」「六本木ひるず」も見つかる
Apporo に関するまとめ
• 「類似文字列検索」という要素技術がある
– 「近似文字列照合」などでググってみよう
– この技術で検索ヒット数ゼロ件を回避しよう
• 類似文字列検索エンジン Apporo がある
– 以下の条件を満たすなら利用を検討して損はない
• Lucene(Solr)を使う必要がない or 使っているが苦手
• 検索クエリとの編集距離が近い順で結果を得たい
• Apporo は今後「読み仮名やローマ字での検索」や「強力
な文字列正規化」を実装し、安定させ、高速化する
Apporo
の
使用方法の例
デモ(インストール)
• tsubomi (Suffix Array ライブラリ)のインストール
svn checkout http://tsubomi.googlecode.com/svn/trunk/ tsubomi
cd tsubomi
make; sudo make install
• Apporo のインストール
svn checkout http://apporo.googlecode.com/svn/trunk/ apporo
cd apporo/src
make; sudo make install
• Apporo の Perl 拡張のインストール
cd apporo/perl/Apporo
perl Makefile.pl
make; sudo make install
デモ(index作成用のコマンド)
• apporo_indexer コマンド
– 以下を実行すれば検索用の索引ができる
– UTF-8 文字列を含むファイルのindexing
• apporo_indexer -i ./address.tsv -bt –u
• apporo_indexer -i ./address.tsv –d
– ASCII 文字列だけ含むファイルのindexing
• apporo_indexer -i ./address.tsv –bt
• apporo_indexer -i ./address.tsv –d
デモ(index するファイル : yapc.txt)
デモ(設定ファイル : demo.conf)
ngram_length
2
is_pre false
is_suf false
is_utf8 true
dist_threshold 0.0
index_path
/path/to/your/file/which/already/indexed/yapc.txt
dist_func
dice
entry_buf_len
1024
複雑そうだけど、
engine tsubomi
検索を効率よく行うには、
result_num
5
bucket_size
2000
一定量のパラメタが必要。
is_surface
true
is_kana false
is_roman
false
設定ファイルがあると、
is_mecab
false
APIを綺麗に作りやすい。
is_juman
false
is_kytea
false
アプリごとに書くと良い。
デモ(検索用の2種類のコマンド)
• apporo コマンド
– 設定ファイルのパスとクエリを引数で与える
• apporo ./demo.conf “クエリ”
• apporo_searcher コマンド
– すべてのパラメタを必要に応じて指定する
– UTF-8文字列のindexを検索するときは –u が必要
• apporo_searcher -i ./address.tsv –u ¥
-q クエリ –n 2 –d dice –t 0.6 –r 10
– ASCIIの時は-uを付けない。それ以外はUTF8と同じ
• apporo_searcher -i ./address.tsv ¥
-q クエリ –n 2 –d dice –t 0.6 –r 10
デモ(yapc.txt を検索)
• 文字index作成、行index作成、indexの確認、検索を実行
– indexしたのはYAPC::Asia TOKYO 2011 の発表タイトルリスト
– 検索クエリは「Apporo」を「Aporo」と間違えている
– 狙いどおり、Apporoでクエリに類似するエントリを発見できた
デモ(Perl でApporoを使う : demo.pl)
#!/usr/bin/env perl
use
use
use
use
strict;
warnings;
utf8;
YAML;
use Apporo;
my $config_path = $ARGV[0];
my $query = $ARGV[1];
my $app = Apporo->new($config_path);
my @arr = $app->retrieve($query);
print Dump \@arr;
デモ(Perl から yapc.txt を検索)
• 先程の設定ファイルをapporoコマンドと同様に利用
• demo.plの中では use Apporo; してる程度
• apporo_searcherのコマンドと同様の結果を得た
• 結果は今のところ文字列の配列で返していますけど、
今後、安定性が増したらハッシュの配列にする予定です
まとめ
まとめ
• 要素技術は、いきなり作らないで試作しよう
– Perl は要素技術の試作に最適だと僕は思います
– 試作したら他部署・職種の方からも意見をもらおう
• 計画策定や機能の取捨選択は主担当者がやるしかない
• 類似文字列を検索しない時代は終わった
– だいぶ枯れた技術だから、実際に使ってみよう
• 類似文字列検索が必要なときは Apporo を試してみよう
– Apporo は Perl のおかげでスムーズに開発できました
– 徐々に、便利に、安定させて、速くします
• デモ失敗に関するApporo 由来の原因は解消しました
ご清聴ありがとうございました
@overlast でした。
http://code.google.com/p/apporo
Fly UP