Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

Elasticsearchを用いた日本語検索システムの理論と設定

Elasticsearchと対話Botによる対話型の検索システム 第1回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2016/10/06 14:00

 本連載は、対話インターフェースを利用して新しい形の検索システムを体験してもらうことを目的としています。今回は日本語検索システムでよく用いられるElasticsearchを紹介します。Elasticsearchは大規模なデータに対しても適用可能な検索機能を提供している全文検索エンジンです。特徴としてスケーラブル、検索速度の速さ、検索結果の分析のしやすさ、開発者にとって使いやすいRESTfulなAPIが挙げられます。今回の記事はElasticsearchを用いた日本語検索システムの仕組みから設定の部分までを記述し、次回の記事で実際に動作させてもらいます。

目次

本連載の内容

 本連載で紹介予定の内容は次のとおりです。

Step1:Elasticsearchを用いた日本語検索システム

 対話型の検索システムを作成するためのStep1として、Elasticsearchを用いた日本語検索システムの構築方法を紹介します。Elasticsearchの検索における仕組みから構築のポイントとなるElasticsearchの設定ファイル、登録用のテンプレート、辞書について解説します。

Step2:Elasticsearchへの大量データ登録の効率化

 日本語検索システム作成の際に大量データ登録をする場合、シーケンシャルにデータを登録すると時間がかかってしまいます。そこで並列処理を用いて効率よくデータを登録する方法を紹介します。

Step3:検索システムを使いたくなるUI提供:Slack対応

 検索システムを社内に導入しても、UIが適切でないと使ってもらえません。システムの本質は使ってもらうことにより価値が出ます。そこでSlackをインターフェースに挟むことにより、ユーザーが使いやすい検索システムの提供を試みます。Step3ではSlackのインターフェースを利用した簡単なBotの作成を行います。

Step4:SlackとElasticsearchを連携し、聞きやすく使いたくなる検索システムの提供

 Step1、Step2の記事で実現した検索システムとStep3の記事で実現したSlackインターフェースをつなげることを試みます。インターフェースにはSlackを使用し、ElasticsearchのDockerコンテナとSlack対応BotのDockerコンテナを用意してSlack対応Bot、Elasticsearchのコンテナを変更できるようにして柔軟性に富んだ構成を目指します。

対象読者

  • 現場の技術者で自社や自身のプロジェクトで検索システムを作成する必要のある方
  • 環境差異の少ない検索システムを作成したい方

検証環境

 この記事では、以下の環境でサンプルの動作を確認しています。

  • Elasticsearch 2.3.0
  • Vagrant 1.8.5
  • Ubuntu Trusty 14.04 (LTS):Vagrant上での動作OS
  • Docker 1.12

Elasticsearchについて

 Elasticsearchとは、Elastic社のもとでOSSとして開発されている、大量にある文書の中から目的のワードを持つ文書を検索するための検索エンジンのことです。

 OracleやPostgreSQLなどのRDBMSのデータベースとElasticsearchとの違いは、RDBMSは条件にマッチしたデータを正確に返すのと比べ、Elasticsearchは条件との関係性の高いデータを返すという点があります。

 今回Elasticsearchを採用する理由は登録する文書は自然言語であり、自然言語は人によって記述に違いがあり、完全一致で検索する場合に目的のものを検索するのが難しいためです。

 以下ではElasticsearchの検索機能にのみフォーカスして説明します。Elasticsearch 2.3.0時点での機能を想定しています。

 Elasticsearchでは以下の2点の工夫をして検索機能の提供をしています。

  1. 文書を検索に適した形で保存。
  2. スコアリングによる検索結果の提示

文書を検索に適した形で保存

 文章を直接保存せずに転置インデックスという手法を使用して文書を保存しています。転置インデックスとは、図1のように単語が登録されている文書の番号を保存しておくことで、検索の際に文書の中身を検索せずに該当文書を返す手法です。

図1 Elasticsearchに文書を登録する際の処理
図1 Elasticsearchに文書を登録する際の処理

 処理の流れは下記です。

  1. 文書から単語を抽出
  2. 単語からストップワードと呼ばれる「は」や「で」などの機能語を外す
  3. 登録処理

 登録されたTermと呼ばれる単語を例を挙げて説明すると、「Elastic」は「Document1」にしか存在しませんが、「OSS」は「Document1」と「Document2」に存在しています。

 「Elastic」で検索すると「Document1」を返し「OSS」で検索すると「Document1」と「Document2」を返すようになっています。こうすることで、すべての文書を検索することなく高速で結果を返す仕組みを実現しています。

スコアリングによる検索結果の提示

 先ほどの転置インデックスだけの検索では同一の文書の番号のものが複数出てきます。その結果に差異をつけるためにスコアリングという手法を使用しています。

 スコアリングは下記の式で成り立ちます(デフォルト)。

score(q,d) =
            queryNorm(q)
          * coord(q,d)
          * SUM (
                tf(t in d),
                idf(t)2,
                t.getBoost(),
                norm(t,d)
                        ) (t in q)

 「q」が検索クエリを表し「d」は対象の文書を表します。

 検索クエリの例:

  • 単語:「Docker」
  • 複数単語:「Docker Elasticsearch」
  • 文章:「DockerでElasticsearchの環境構築」

 上から順に説明すると、次のとおりです。

  • score(q,d)は最終的に出したいスコアです。
  • queryNorm(q)は検索クエリのスコアが不当に高くならないように調整する係数です。
  • coord(q,d)は文書と検索クエリの同時出現数です。
  • SUM(足し算)を行っている理由は検索クエリは単語だけではなく複数語や文章の場合もあります。そのため検索クエリを単語単位で区切って計算するためSUM(足し算)の処理を行っています。
    • tf(t in d)は文書中に出てきた単語の頻度です。
    • idf(t)は多くの文書に出てくる”私”などの単語は重要でないと判断するために使用する指標です。
    • t.getBoost()"は各単語のBoost値を取得します。これは長い文の方が評価が高くなりやすいのでそれを避けるために設定されている値です。
    • norm(t,d)は頻度は少ないが文書の特徴を表す重要な単語に対するスコアが小さくならないように調整する指標です。

 これらの指標を用いて上記の結果を算出します。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2016/10/11 11:57 サンプルファイルを差し替えました。

  • 2016/10/09 18:16 Page 1 検証環境を追記

  • 2016/10/09 18:16 ElasticsearchCode/elasticsearch.ymlの「min_gram」と「max_gram」を同一の値である2に修正

  • 2016/10/09 18:15 Page 3 「2gramの例」 例を「これは例文です。→ これ は例 文で す。」から「これは例文です。→ これ れは は例 例文 文で です す。」に修正

  • 2016/10/09 18:15 Page 3 「mecab」を「kuromoji」に修正

  • 2016/10/09 18:15 Page 3 「mecab neologd」を「kuromoji neologd」に修正

  • 2016/10/09 18:15 Page 2 ステミングの設定 kuromoji_neologd_stemmerの例をカタカナの長音をステミングするための設定に修正

著者プロフィール

  • WINGSプロジェクト 大串 正矢(オオグシ マサヤ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:Elasticsearchと対話Botによる対話型の検索システム
All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5