のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Elasticsearchを使ってWikipediaで遊んでみました。

Sponsored Links

今日はElasticsearchを使ってWikipediaの類似記事や重要語の抽出に勤しんでみました。

皆さんこんにちは
お元気ですか。コーヒーうまい。

Elasticsearchについて

www.elastic.co

Elasticsearchはluceneベースの全文検索エンジンです。

特徴として、拡張性が容易と言われている分散型の検索システムです。
APIも非常に豊富であり、FluentdやKibanaと連携して可視化することができ、
ログ可視化や検索に組み込まれていることが多いです。

本日はこれを扱ってみます。

Install

Mac
brew install elasticsearch
Ubuntu

Fluentd、ElasticSearch、Kibana4によるログ分析環境の構築 | hrendoh's memohrendoh's memoを参考にさせて頂きました。
ただし、このコマンドだと、立ち上げが sudo service elasticsearch startになります。

sudo add-apt-repository -y ppa:webupd8team/java
sudo apt-get update
sudo apt-get -y install oracle-java8-installer
wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb http://packages.elastic.co/elasticsearch/1.7/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-1.7.list
sudo apt-get update && sudo apt-get install elasticsearch

Wikipediaデータをpluginを使って解析する。

River pluginを使うと、WIkipediaのデータを流しこむことができます。

plugin -install elasticsearch/elasticsearch-river-wikipedia/2.0.0
plugin -install elasticsearch/elasticsearch-analysis-kuromoji/2.0.0

kuromoji pluginを使ってテキストの形態素解析を実施します。

curl -XPUT 'http://localhost:9200/ja-wikipedia-kuromoji/' -d'
{
    "index":{
        "analysis":{
            "tokenizer" : {
                "kuromoji_user_dict" : {
                   "type" : "kuromoji_tokenizer",
                   "mode" : "extended",
                   "discard_punctuation" : "false"
                }
            },
            "analyzer" : {
                "my_analyzer" : {
                    "type" : "custom",
                    "tokenizer" : "kuromoji_user_dict"
                }
            }

        }
    }
}

以下のコマンドでriverを開始します。

curl -XPUT localhost:9200/_river/ja-wikipedia/_meta -d '
{
    "type" : "wikipedia",
    "wikipedia" : {
        "url" : "file:/Users/Tereka/Programing/Data/jawiki-latest-pages-articles.xml.bz2"
    },
    "index" : {
        "bulk_size" : 1000
    }
}'

riverをすると長い時間かかりますが一定の時間でやめましょう。

curl -XDELETE 'localhost:9200/_river/ja-wikipedia-kuromoji/'

データ取得確認

curl -XGET 'localhost:9200/ja-wikipedia-kuromoji/_search?pretty' -d '
{
  "query":{
    "query_string":{
      "default_field":"page.title",
      "query":"アニメ"
    }
  }
}'

データ全体を見たい場合は、head pluginを使ってみましょう。

elasticsearch/bin/plugin -install mobz/elasticsearch-head

標準設定の場合は localhost:9200/_plugin/head/ にアクセスしてみると以下の画面を見ることができます。

f:id:tereka:20151012103345p:plain
f:id:tereka:20151012103356p:plain

様々なクエリを投げてみる。

ここまでだと殆ど、先人を踏襲し、取得しただけなので、面白くありません。
そこで、elasticsearchのAPIを使って解析してみます。

more_like_this

more like thisは似ているドキュメントを検索する為のAPIです。

curl -XGET 'localhost:9200/ja-wikipedia-kuromoji/_search?pretty' -d '
{
  "query":{
    "more_like_this":{
      "like_text":"ハリー・ポッター",
      "min_term_freq":1,"fields":["title","text"],"max_query_terms":1
    }
  }
}'

レスポンスはあまりに長い為、表示しませんが類似しているドキュメントを検索することができています。

aggregation

特に今回はsignificant terms aggregationについて行おうと思います。
significant terms aggregationは検索された中で重要なワードを検出するAPIです。

curl -XGET 'http://localhost:9200/ja-wikipedia-kuromoji/_search?pretty' -d '{
  "query":{
    "match":{
      "text":"ハリーポッター"
    }
  },
  "aggregations": {
    "significantCrimeTypes": {
      "significant_terms": {
        "field": "text"
      }
    }
  }
}
'

上記のcurlのリクエストの応答の一部が以下になります。ハリーポッターを見たことがある人
ならばわかると思いますが、よく見るワードが出力されています。

  "aggregations" : {
    "significantCrimeTypes" : {
      "doc_count" : 8,
      "buckets" : [ {
        "key" : "ハリーポッター",
        "doc_count" : 7,
        "score" : 12124.546875,
        "bg_count" : 7
      }, {
        "key" : "sorcerers",
        "doc_count" : 4,
        "score" : 3463.90625,
        "bg_count" : 8
      }, {
        "key" : "deathly",
        "doc_count" : 3,
        "score" : 3117.5906250000003,
        "bg_count" : 5
      }, {
        "key" : "goblet",
        "doc_count" : 3,
        "score" : 2597.9296875,
        "bg_count" : 6
      }, {
        "key" : "hallows",
        "doc_count" : 3,
        "score" : 2226.743303571429,
        "bg_count" : 7
      }, {
        "key" : "azkaban",
        "doc_count" : 3,
        "score" : 1948.353515625,
        "bg_count" : 8
      }, {
        "key" : "アズカバン",
        "doc_count" : 3,
        "score" : 577.0260416666666,
        "bg_count" : 27
      } ]
    }
  }

感想

実は1.5G付近のデータがあるので速度面厳しいと思ったのですが、
案外速かったのには驚きです。
APIもまだまだ沢山あるので、全然追いかけられていませんが組み合わせると非常に面白いことができそうです。