関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
<< LuceneとSennaの比較:検索性能・・・? | main | EndecaやFASTを検討し、最終的にSolrに行き着いて満足した人 >>
類義語検索とオントロジー
LuceneやSolrを使った類義語検索では類義語辞書が必要となるが、弊社がコンサルする場合、これは今のところ顧客自身に用意してもらっている。会社名など(「松下電器産業」と「パナソニック」など)汎用的なものもあるが、それよりも顧客の事業ドメイン独特の専門用語とその略語などをサポートすることが重要な場合が多く、広くカバーされた汎用的な類義語辞書が強く求められる場面にはあまり遭遇しない。企業内検索では社内・部内専門用語の略語で検索したとき、その用語の(略語ではなく)正式名称を含むWordファイルがヒットしてその部分がハイライトされようものなら、それだけで結構喜んでもらえるものだ。

類義語検索を発展させたものとして、オントロジーを使った検索というものがある。類義語辞書では登録された用語はフラットであるが、オントロジーでは用語の概念を考慮した階層構造を形成する。たとえば、「動物」「爬虫類」「哺乳類」「犬」「猫」という用語をオントロジー辞書に登録するとした場合、次のようになる:



動物
|
+------------------+
| |
哺乳類 爬虫類
|
+-------------+
| |
犬 猫



そうしておいて「犬」で検索されたときに適当な条件に符合した場合は「哺乳類」や「動物」などにキーワードを拡大して検索したり、場合によってはその兄弟の「猫」というキーワードを使って検索する、ということをおこなう。

オントロジーを使った検索はそれなりに可能性を感じさせるが、類義語辞書を作るよりもコストが高くなるのが難点だ。その割りに効果が定量的にわかりにくい(費用対効果がはっきりしない)。

類義語のソリューションはオントロジーほどエレガントではないものの、その効果は非常に大きい。

たとえば不動産屋のサイトで、「ペット可」「犬猫可」というような用語を含む賃貸物件の説明文が文書に含まれているとする。オントロジー辞書では「ペット」の下に「犬」と「猫」を配置することになるだろう。類義語ではもっと単純で:



ペット, 犬, 猫



と定義する。こうしておいて犬を飼える賃貸物件を探しているサイト訪問者が「犬」というキーワードで検索すると、「犬」の他「ペット」を含む物件が検索でき、「ペット」がハイライト表示される。もちろん、「猫」もハイライト表示されてしまうが、なにしろここは不動産屋の物件情報サイトだ。目くじらを立てて怒るユーザはいないだろう。これがペットショップのサイトや動物図鑑のサイトならまずいかもしれないが。しかしそもそもペットショップや動物図鑑サイトなら上記のような類義語定義はありえないだろう。

類義語機能は類義語を「展開」するだけでなく片方向にマッピングする「正規化」もある。こういった機能をうまく組み合わせれば案件ごとになんとか抜け道も見つけられるものだ。

類義語検索機能を導入することで、ユーザは似た用語を自分で捻出しながら何度も検索を繰り返すことなく探している文書にたどり着くことができるようになり、利便性が増してユーザのサイトへの信頼感を高める効果がある。まだ導入していないサイトは導入を検討してみるとよいだろう。
| 関口宏司 | その他(分類不能) | 15:11 | comments(7) | trackbacks(0) |
初めてコメントさせていただきます。
現在、Luceneで検索機能を構築しようと思っています。
類義語検索も検索機能に含めたいと考えているのですが、Java初心者+Luceneも最近知ったばかりなので是非ご教授いただければと思います。
知りたいことは、
・類義語検索用のAPIはLuceneに準備されているのか?それとも自作の必要があるのか?
・辞書の保持方法とは?
(DBで保持するものなのか、それともファイルで保持?)
ということです。
全くの初心者なので、実はチンプンカンプンの質問になっているかもしれませんが。。。
申し訳ございませんが、よろしくお願いいたします。
| 初心者 | 2010/01/20 8:14 PM |
Java初心者・・・だとLuceneよりもSolrがおすすめですよ。類義語検索も最初からあります(プログラミング不要)。Solrの場合、類義語辞書はテキストファイルで用意する感じです。
| 関口 | 2010/01/20 10:48 PM |
こんにちは

ApacheSolr入門を購入して、勉強しながら、作業をしています。
いつもごブログを拝見させていただいて、助かりました。


同義語について、質問させていただきます。
solr3.6.2を使っています。
ソースorg.apache.solr.analysis.SynonymFilterFactoryを見たら、LUCENE_34以降の場合、
FSTSynonymFilterFactoryを使います。
前の同義語はSlowSynonymFilterFactoryになりました。

FSTSynonymFilterFactory create⇒org.apache.lucene.analysis.synonym.SynonymFilter
SlowSynonymFilterFactory create⇒org.apache.solr.analysis.SlowSynonymFilter

同義語:
パスタ,スパゲッティ,スパゲティー
ホワイト,ブラック

分析方法:
bigram

パスタホワイトを分析
旧同義語:
1: [パス:0->3:ngram] [スパ:0->3:ngram] [スパ:0->3:ngram]
2: [パゲ:0->3:ngram] [パゲ:0->3:ngram] [スタ:0->3:ngram]
3: [ゲッ:0->3:ngram] [ゲテ:0->3:ngram]
4: [ティ:0->3:ngram] [ッテ:0->3:ngram]
5: [ティ:0->3:ngram] [ィー:0->3:ngram]
6: [タホ:2->4:ngram]
7: [ホワ:3->7:ngram] [ブラ:3->7:ngram]
8: [ラッ:3->7:ngram] [ワイ:3->7:ngram]
9: [イト:3->7:ngram] [ック:3->7:ngram]
10: [ト:6->7:ngram]

新同義語:
1: [パス:0->2:SYNONYM] [スパ:0->2:SYNONYM] [スパ:0->2:SYNONYM]
2: [スタ:1->3:SYNONYM] [パゲ:1->3:SYNONYM] [パゲ:1->3:SYNONYM]
3: [タホ:2->4:ngram] [ゲッ:2->4:SYNONYM] [ゲテ:2->4:SYNONYM]
4: [ッテ:3->5:SYNONYM] [ティ:3->5:SYNONYM] [ホワ:3->5:SYNONYM] [ブラ:3->5:SYNONYM]
5: [ティ:4->6:SYNONYM] [ィー:4->6:SYNONYM] [ワイ:4->6:SYNONYM] [ラッ:4->6:SYNONYM]
6: [イト:5->7:SYNONYM] [ック:5->7:SYNONYM]
7: [ト:6->7:ngram]

旧の場合、同義語はどこからどこまでは分かります。
1-5 6 7-10
同義語のstartOffsetは同じです。
同じ位置に、termが一つの場合、これは同義語ではないと分かります。
同じ位置に、termが二つ以上の場合、これは同義語だと分かります。

新の場合、同義語はどこからどこまでは分からないです。
どんな方法で分かりますか?
新の場合、同じ位置に混在しています。
同義語の最後のtermを判別したいですが、教えていただけますか。

長く書いてすいません。

よろしく、お願いいたします。
| よう | 2013/06/26 3:39 PM |
ようさん、こんにちは。

すみませんが、図の読み方がよくわかりませんでした。SYNONYMかオリジナルの単語かをstartOffsetから判別しようとしている、ということでしょうか。

新しいFSTベースのSynonymFilterは性能優先でオフセットの出力を犠牲にしており、問題が多いです。旧の動作がよいのなら、LUCENE_33で使うのが無難です。
| 関口 | 2013/06/28 8:35 PM |
関口さん、こんにちは。
ご回答ありがとうございました。

>すみませんが、図の読み方がよくわかりませんでした。

図を説明しなくて、すみません。
各termの属性(TermAttribute、PositionIncrementAttribute、OffsetAttribute、TypeAttribute)を出力した図です。
出力形式:
position:[term:startOffset->endOffset:type]

実は下記のことを対応しています。
ApacheSolr入門の10.2シノニムのN-gramでの注意点
index
新東/東京/京国/国際〜 新東/とう/うき/きょ/ょう/京国/国際〜
query
新と/とう/うき/きょ/ょう 新と/東京
ヒットしないです。
同義語の最初と最後のtermを判別して、「新と」を「新と」「新東」に置換すれば、ヒットします。


旧同義語の場合、startOffsetと同じ位置のterm数から、同義語の最初と最後のtermを判別することができますが、
新しい同義語の場合、同じ位置に同義語が混在しますし、startOffsetも同じではないので、
同義語の最初と最後のtermが分からなくなりました。

>新しいFSTベースのSynonymFilterは性能優先でオフセットの出力を犠牲にしており、問題が多いです。
これは原因ですね。

>旧の動作がよいのなら、LUCENE_33で使うのが無難です。
新しいFSTベースのSynonymFilterはメモリ使用量は減少するので、使おうとしています。
問題があれば、旧同義語を使うしかないです。

新同義語に対して、上記のシノニムのN-gramでの注意点を解決する方法がありますか?

よろしく、お願いします。
| yo | 2013/07/01 12:49 PM |
関口さん、こんにちは。

上記質問した新同義語について、最後使用するのをやめました。

別の同義語問題を聞かせてください。

分割方法:
bigram

現象:
同義語に同義語が含まれる場合、ヒットしない場合がある。

同義語:
カレーライス,インド
ライス,トチオトメ

【INDEX】
カレーライス

【Query】
ライス

結果:ヒットしないです。

解析:
【INDEX分割】
(カレ、イン)(レー、ンド)(ーラ)(ライ)(イス)

【Query分割】
(ライ、トチ)(イス、チオ)(オト)(トメ)

indexのライスのterm数は2
queryのライスのterm数は4
2:4でヒットしないです。


indexのTokenizerの分割結果:
カレ レー ーラ ライ イス

同義語map
カレ=<{レー=<{ーラ=<{ライ=<{イス=<[カレ,イン,ンド,レー,ーラ,ライ,イス],null>}>}>}>}>
SlowSynonymFilterの処理では、
「カレ」から、「イス」まで、[カレ,イン,ンド,レー,ーラ,ライ,イス]synoymsを展開しています。

カレーライス(同義語)中のライス(同義語)は同義語展開しないのは仕様らしいです。

solrのバグですか?
何かアドバイスをいただければ、助かります。

よろしく、お願いいたします。
| yo | 2013/07/24 3:36 PM |
yoさん、こんにちは。

copyFieldを使ってSynonym展開しないフィールドを作り、dismaxでそちらも検索するようにしたらいかがでしょうか。
| 関口 | 2013/07/26 1:27 AM |









http://lucene.jugem.jp/trackback/198
+ Solrによるブログ内検索
+ PROFILE
1234567
891011121314
15161718192021
22232425262728
293031    
<< October 2017 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS