Elasticsearchから取り出してsklearnでテキストデータをゴニョゴニョするときにPython側ではIgoを使って形態素解析とかしていたけど、Elasticsearchでやっている形態素解析と一致しないのもなんだし、Igoを直読みするよりパフォーマンスは落ちると思うけど、辞書管理等々考えるとElasticsearchのanalyze APIを使って形態素解析しちゃった方がシンプルかなっと思い、まとめておく。
まず、PythonでElasticsearchのAnalyze APIが呼べることを以下で確認する。ここでは、Python 2.7を利用している。elasticsearch-pyもインストール済みな想定で、Elasticsearchも起動しておく必要がある。
$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding("utf-8")
>>> from elasticsearch import Elasticsearch
>>> es = Elasticsearch(hosts="localhost:9200")
>>> text=u"今日の天気は晴れです。"
>>> es.indices.analyze(index=u"sample",body=text,params={u"field":u"message"})
{u'tokens': [{u'end_offset': 2, u'token':...
Python2の問題だけど、setdefaultencodingでセットしないとエラーになる。
エンコーディングさえ問題なければ、上記ではsampleインデックスのmessageフィールドのAnalyzerでtextをトークナイズできる。
まぁ、Ubuntuとかであれば、/etc/python2.7/sitecustomize.py の先頭に
import sys
sys.setdefaultencoding("utf-8")
を追加してdefaultencodingをutf-8にしてしまっても良いのかも。(最適な対応方法はわからない…) ほかの環境であれば、/usr/lib/python*/site-packages/sitecustomize.pyあたりに記述すればよい。
ここまで、できてしまえば、sklearnとかで使いたいなら、
class Analyzer:
"""Analyzer"""
def __init__(self, es, index, field):
self.es = es
self.index = index
self.field = field
def __call__(self, text):
if not text:
return []
data = self.es.indices.analyze(index=self.index,
body=text, params={"field":self.field})
tokens = []
for token in data.get("tokens"):
tokens.append(token.get("token"))
return tokens
というような感じで、Analyzerクラスを作っておいて
es = Elasticsearch(hosts="localhost:9200") analyzer = Analyzer(es, "sample", "message") vectorizer = TfidfVectorizer(analyzer=analyzer)
みたいな感じで呼べば、いろいろなVectorizerで利用できると思います。