MeCabをLambdaに動かすメモ

絶対忘れるので覚えるうちにメモをとります。 基本的はhttp://dev.classmethod.jp/cloud/aws-lambda-with-mecab/に沿って進めますが、ダウンロードURLが死んだり、pipのインストールパス変わったりしました。

0. Lambdaと同じ環境のEC2インスタンスを作る

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html
サポートAMIが時々変わるようなので作るときは必ずチェックしておきましょう。

これからはEC2上に作業します。 LambdaはPython2.7しか使えないのでPython2.7.12を使いました。

1. プロジェクトの作成

$ mkdir $HOME/preprocessing
$ PROJECT_HOME=$HOME/preprocessing

2. MeCab のインストール

HPのこちらのリンクからダウンロードできます。
GoogleDriveなのでwgetが使えないからMacに保存して、scpすればいいでしょう。例えば$HOMEに保存します。

$ cd ~
$ tar zvxf mecab-0.996.tar.gz
$ cd mecab-0.996
$ ./configure --prefix=$PROJECT_HOME/local --enable-utf8-only
$ make && make install

3. MeCab辞書のインストール

mecab-ipadic-neologdを使いたかったですが、 Lambdaの容量制限超えてしまうので、IPA辞書を使います。ダウンロードリンクもMeCabと同じページにあります。

$ tar zvxf mecab-ipadic-2.7.0-20070801.tar.gz
$ cd mecab-ipadic-2.7.0-20070801
$ export PATH=$PROJECT_HOME/local/bin:$PATH
$ ./configure --prefix=$PROJECT_HOME/local --enable-utf8-only
$ make && sudo make install

4. MeCab Python バインディングのインストール

これは元の記事の方法には動かなかったので、別のpipパッケージをインストールします。

$ cd $PROJECT_HOME
$ virtualenv env
$ source env/bin/activate
$ pip install mecab-python3

インストール終わってもpython consoleから使えないです。

>>> import MeCab
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>
ImportError: No module named MeCab  

これを無視にしても良いですが、もしテストしたいなら$PROJECT_HOME/env/local/lib64/python2.7/dist-packages/*から$PROJECT_HOME/env/local/lib/python2.7/dist-packages/に移動(またはコピー)したらconsoleの中から使えるようになります。mecabrc見つからないよとかのエラーが出たら-rでファイルの場所を指定すればよいです。

5. lambda関数サンプル

## coding=utf-8
from __future__ import print_function

import os  
import ctypes

libdir = os.path.join(os.getcwd(), 'local', 'lib')  
libmecab = ctypes.cdll.LoadLibrary(os.path.join(libdir, 'libmecab.so'))

import MeCab

## MeCab
dicdir = os.path.join(os.getcwd(), 'local', 'lib', 'mecab', 'dic', 'ipadic')  
rcfile = os.path.join(os.getcwd(), 'local', 'etc', 'mecabrc')  
mecab = MeCab.Tagger("-d{} -r{} -Owakati".format(dicdir, rcfile))

def lambda_handler(event, context):  
  content = '今日はいい天気です'.encode('utf-8')
  result = mecab.parse(content)
  print(result)
  return result

if __name__ == "__main__":  
  lambda_handler(None, None)

6. zip化

*.dist-info/*
*.egg-info
*.pyc
env/*  
*~
exclude.lst  
make_zip.sh  
preprocessing.zip  
lib/*  
local/bin/*  
local/include/*  
local/libexec/*  
local/share/*  
PROJECT_HOME=$HOME/preprocessing  
ZIP_FILE=$PROJECT_HOME/preprocessing.zip

rm ${ZIP_FILE}  
zip -r9v ${ZIP_FILE} * -x@exclude.lst  
cd $PROJECT_HOME/env/lib/python2.7/dist-packages/  
zip -r9v ${ZIP_FILE} .  --exclude \*.pyc  
cd $PROJECT_HOME/env/lib64/python2.7/dist-packages/  
zip -r9v ${ZIP_FILE} .  --exclude \*.pyc  

zip化スクリプト実行:

$ cd $PROJECT_HOME
$ bash make_zip.sh

出来上がったzipファイルをLambdaに上げたら完了!