Elasticsearch 分類予測 More Like This編

Kunihiko Kido
Hello! Elasticsearch.
7 min readSep 14, 2015

--

機械学習せずに新しいドキュメントの分類を予測する。More Like This編

これまで、機械学習を使った分類予測Percolatorを使った分類予測を紹介してきました。今回は Elasticsearch の More Like This Query を使ってもっと簡単に分類予測する方法について紹介したいと思います。

More Like This Queryとは?

More Like This Query とは、Elasticsearchが提供するいわゆる類似文書検索です。基本的な考え方は、単語の順序は気にせず、同じ語を多く含む文書は類似文書であるというものです。Bag of words によるベクトル空間モデルを基本的な考え方としているそうです。

ElasticsearchのMore Like This Queryは以下の3つの方法で類似する文書を検索することができます。

  • 任意のテキストに対する類似文書検索
  • 任意のドキュメントに対する類似文書検索
  • インデックス済みの任意のドキュメントに対する類似文書検索

今回は2番目にあげた「任意のドキュメントに対する類似文書検索」を使用します。

準備

特に準備というほどではないのですが、分類済みのドキュメントをインデックスしておきます。

重要なポイントは、More Like This Query の分析スピードを向上させるため、使用するフィールドの term_vector オプションを有効にします。これを有効にするとインデックス時に各フィールドのベクトル値を格納しておくことができるため、類似文書検索時の分析のスピード向上につながるようです。

分類済みドキュメントの内容

{
"title": "原油安の「マイナス面」無視できず…"
"contents": "原油相場の下落が続いている。21日のニューヨーク市場で原油先物相場は国際指標の米国産標準油種(WTI)が …"
"category": "経済"
}

マッピング例

PUT /index-news-ja/
{
"mappings": {
"posts": {
"properties": {
"title": {"type": "string", "term_vectors": "yes"},
"contents": {"type": "string", "term_vectors": "yes"},
"category": {"type": "string", "index": "not_analyzed"},
}
}
}
}

今回は、``title`` フィールドと ``contents`` フィールドを使うので、その両方の term_vector オプションを有効にしています。

分類予測

今回紹介する分類予測 More Like This 編の考え方は、新しいドキュメントの内容に類似したドキュメント群を検索し、そのドキュメントの集合を表す重要なカテゴリが分類するべきカテゴリであるというものです。

ドキュメントの集合から重要なカテゴリの集計するには、これまでも紹介してきた Significant Terms Aggregation を使用します。

これをクエリーで表すと

POST /index-news-ja/posts/_search?search_type=count
{
"query": {
"more_like_this": {
"fields": ["title", "contents"],
"docs": [{
"doc": {
"title": "クラウドファンディング家電~自宅の様子が外出先...",
"contents": "「クラウドファンディング」とは、製品開発など..."
}
}]
}
},
"aggs": {
"categories": {
"significant_terms": {"field": "category"}
}
}
}

このクエリーの実行結果からは、類似したドキュメントの集合から以下のような重要なカテゴリがランキングされた結果を得ることができます。

{
...
"hits": {"total": 84, "max_score": 0, "hits": []},
"aggregations": {
"categories": {
"doc_count": 84,
"buckets": [
{
"key": "IT・科学",
"doc_count": 38,
"score": 0.87510582010582,
"bg_count": 300
},
{
"key": "経済",
"doc_count": 18,
"score": 0.004726890756302499,
"bg_count": 408
}
]
}
}
}

ちなみに、Significant Terms Aggregation の代わりに、単語の集計でよく使われるTerms Aggregation を使用した結果は以下のようになりました。

{
...
"hits": {"total": 84, "max_score": 0, "hits": []},
"aggregations": {
"categories": {
"doc_count": 84,
"buckets": [
{
"key": "IT・科学",
"doc_count": 38,
},
{
"key": "経済",
"doc_count": 18,
},
{
"key": "エンタメ",
"doc_count": 17,
}
{
"key": "スポーツ",
"doc_count": 11,
}
]
}
}
}

サンプルの類似文書検索の結果には、関連性の低い「エンタメ」や「スポーツ」のドキュメントも含まれていますが、Significant Terms Aggregationを使うことで、うまいこと重要なカテゴリのみ集計されているのがわかりますね。

チューニング

今回紹介した方法のチューニングは、More Like This Query の各種パラメータを調整して、類似文書検索の精度を向上させることで、分類予測の精度も向上するはずです。

今回のチューニングで使用しそうなパラメータをピックアップしましたので、詳しくはリンク先を確認してください。

Term Selection Parameters

  • max_query_terms
  • min_term_freq
  • min_doc_freq
  • min_word_length
  • stop_words

Query Formation Parameters

  • minimum_should_match

Example

POST /index-news-ja/posts/_search?search_type=count
{
"query": {
"more_like_this": {
"fields": ["title", "contents"],
"docs": [{
"doc": {
"title": "クラウドファンディング家電~自宅の様子が外出先...",
"contents": "「クラウドファンディング」とは、製品開発など..."
}
}],
"min_term_freq": 1,
"min_word_length": 2,
"minimum_should_match": "40%"
}
},
"aggs": {
"significantCategories": {
"significant_terms": {"field": "category"}
}
}
}

まとめ

今回紹介した方法は、これまでに紹介した方法に比べ分類予測のためのトレーニングが全く必要ないという特徴があります。どの方法を採用するかは悩ましいところですが、検証してみた感じでは、

精度:

More Like This < Percolator < 機械学習

お手軽度:

機械学習 < Percolator < More Like This

という感じです。個人的にはPercolatorバージョンに落ち着きそうな感じがします。

--

--