2
1

More than 3 years have passed since last update.

GolangでMeCab+NEologdが使えるDockerイメージ作成してみた

Last updated at Posted at 2021-03-19

はじめに

社内のサーバーサイド公式言語であるGolangで、
形態素解析ライブラリのMeCab+NEologdを試したいな〜
という情熱が燃えたぎったので、挑戦してみました。

Dockerfile、初体験であります。(ドキドキ)

TL;DR

  • main.goの用意
  • docker-compose.ymlの用意
  • Dockerfileの作成
  • startup.shの作成

main.go

go ginのフレームワークを使って、REST APIを作成し、テキストを受け取るとともにMeCabによる形態素解析の結果を返すmain.goです。
(※エディタはgolandを使いました。Go Modulesとかの管理が楽)

main.go
package main

import (
    "fmt"
    "log"
    "net/http"

    mecab "github.com/bluele/mecab-golang"
    "github.com/gin-gonic/gin"
)

const (
    ipadic = "/usr/local/lib/mecab/dic/mecab-ipadic-neologd"
)

func main() {
    // Start HTTP server
    r := gin.Default()
    r.POST("/analyze", morphologicalAnalyze)
    if err := r.Run(":8080"); err != nil {
        log.Fatal(err)
    }
}

func morphologicalAnalyze(c *gin.Context) {
    text := c.PostForm("text")
    // mecab here
    mecab, err := mecab.New("-Owakati")
    if err != nil {
        panic(err)
    }
    defer mecab.Destroy()
    data := parseToNode(mecab, text)
    if err != nil {
        c.JSON(http.StatusInternalServerError, "Something went wrong")
        return
    }
    c.IndentedJSON(http.StatusOK, data)
}

func parseToNode(m *mecab.MeCab, text string) []map[string]interface{} {
    tg, err := m.NewTagger()
    if err != nil {
        panic(err)
    }
    defer tg.Destroy()
    lt, err := m.NewLattice(text)
    if err != nil {
        panic(err)
    }
    defer lt.Destroy()
    node := tg.ParseToNode(lt)

    data := make([]map[string]interface{}, 0)
    for {
        entry := make(map[string]interface{})
        fmt.Printf("%s\t%s\n", node.Surface(), node.Feature())
        entry[node.Surface()] = node.Feature()
        data = append(data, entry)
        if node.Next() != nil {
            break
        }
    }
    return data
}

※動かなかったらごめんなさいorz

docker-compose.yml

goのAPIサーバーのコンテナを立ち上げるdocker-composeファイルです。
超軽量のAlpine LinuxGo 1.15.10のイメージを使ってコンテナを立ち上げます。

docker-compose.yml
version: "3.8"

services:
api:
    image: go-mecab-challenge:golang-1.15.10-alpine3.12
    build:
      context: ./docker/go
      dockerfile: Dockerfile
    container_name: api
    ports:
      - 8080:8080
    volumes:
      - ./api:/go/src/github.com/go-mecab-challenge/api
      - /Users/username/go:/go
    working_dir: /go/src/github.com/go-mecab-challenge/api/src
    environment:
      - APP_STAGE=local
      - LOG_LEVEL=debug

必要なフォルダをdocker側にマウントする。

Dockerfile

まずDockerfileをビルドして、コンテナを立ち上げる事前準備をします。
(※ちょっと時間かかる)

$ docker build ./docker/go # Dockerfileのあるディレクトリ指定

Alpine Linuxは超軽量なので、無駄なコマンドやファイル等が削られている状況。
なので、必要なコマンドであったりをapk addでインストールしてカスタマイズが必要。
※下記、不要なものもあるはずなので、ご査収下さい。

Dockerfile
FROM golang:1.15.10-alpine3.12

ENV MECAB_VERSION 0.996
ENV IPADIC_VERSION 2.7.0-20070801
ENV MECAB_URL https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE
ENV IPADIC_URL https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM

RUN apk update && \
    apk upgrade && \
    apk add --no-cache build-base curl git bash openssl openssh-client sudo && \
    curl -SL -o mecab-${MECAB_VERSION}.tar.gz ${MECAB_URL} && \
    tar zxf mecab-${MECAB_VERSION}.tar.gz && \
    cd mecab-${MECAB_VERSION} && \
    ./configure --enable-utf8-only --with-charset=utf8 && \
    make && \
    make install && \
    cd && \
    curl -SL -o mecab-ipadic-${IPADIC_VERSION}.tar.gz ${IPADIC_URL} && \
    tar zxf mecab-ipadic-${IPADIC_VERSION}.tar.gz && \
    cd mecab-ipadic-${IPADIC_VERSION} && \
    ./configure --with-charset=utf8 && \
    make && \
    make install && \
    cd && \
    git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git /mecab-ipadic-neologd && \
    /mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -a -y -p /usr/local/lib/mecab/dic/mecab-ipadic-neologd && \
    echo "dicdir = /usr/local/lib/mecab/dic/mecab-ipadic-neologd" > /usr/local/etc/mecabrc && \
    rm -rf \
      mecab-${MECAB_VERSION}* \
      mecab-${IPADIC_VERSION}* \
      /mecab-ipadic-neologd

COPY startup.sh /startup.sh
RUN chmod 744 /startup.sh
CMD ["/startup.sh"]

解説

  • 環境変数として、MeCabや辞書ipadicの情報を設定
  • alpineのパッケージ管理コマンドapkで必要なコマンド、ファイル等をインストール
    • コマンドたち:curl git bash openssl sudo
    • openssh-client: ssh接続に使える ssh hostnameとか
    • build-base: binutils, file, gcc, g++, make, libc-dev, fortify-headers, patch を含む
      • binutils: GNUが提供しているツールのうち、バイナリのプログラミングを実装するためのツール
      • gcc: GNU Compiler Collection (グニューコンパイラコレクション) のこと
      • g++: GNU C++コンパイラ
      • libc-dev: Linux カーネル由来のユーザスペースヘッダ群を提供するパッケージ。インストール済みの GNU libc 用ヘッダやほかの システムライブラリ用ヘッダで利用するそう
  • MeCabが保存されているgoogle driveに直接アクセスしてtar.gzをとってくる - tar.gzを解凍して展開
  • MeCabのコンパイル用の設定(configure)をして、コンパイル(make)→インストール(make install)
  • ipadicのインストール。MeCabと同じ手順
  • NeoLogdのインストール:gitリポジトリをとってきて、その中のコマンドを叩いてダウンロードする
  • 一旦不要になったフォルダやファイルをrmする
  • startup.shでAPIサーバー起動

ローカルへのMeCabインストールはこちらを参考ください

立ち上げCMDはShellScriptに別で記述

startup.sh
#!/bin/bash
export CGO_LDFLAGS="-L/usr/local/Cellar/mecab/0.996/lib -lmecab -lstdc++"
export CGO_CFLAGS="-I/usr/local/Cellar/mecab/0.996/include"
go run main.go --host 0.0.0.0 --port 8080

解説と懸念点

  • MeCab自体はC言語で書かれたライブラリらしく、go言語で使用する時にはCGOという機能を使う必要があり、二つのパスをexportさせてからGo実行している。
  • 実際にローカルでメカブを$ go get github.com/bluele/mecab-golangするときも、上記のexportが必要。
  • ただ、実行しているdockerコンテナ上に上記のパスがなかったんだけど、やってる意味あるのかなあ。。。という懸念点です。(要調査)
$ docker exec -it api /bin/bash # apiはコンテナ名。実行しているコンテナ内に潜り込む

形態素解析「すもももももももものうち」

いざ桃太郎、出陣!!
goのAPIを叩いて、すももちゃんを投げてみる。

スクリーンショット 2021-03-19 18.23.28.png

おお、できた。
ああ、でも、NEologdをつかったら、なんだか一つの固有名詞になっちゃった。

実際にローカルで普通に やってみると(ipadic)

$ echo "すもももももももものうち" | mecab
すもも   名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
うち  名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

ってなったのになあ。

辞書の使い分けが必要っぽいなこれ。

もうひとつw

スクリーンショット 2021-03-19 18.59.01.png

「サンタさん立ったのたったの三本指で」

まとめ

[GO+MeCab+Neologd+Docker]という念願のアプリケーションを作ることができました。
まあ実用化には一切届かないけど、やっぱり立ち上げって大変だ。けど、面白い。

あとは想像力と努力で、アプリケーションを育てていくしかない。(∵)

例えば、各単語をポイント付けして、
固有名詞だけ重くして、バズりワードの解析とか、やったら面白そう。

以上ありがとうございました。

こちらを参考にDockerfile作成させていただきました♪

わかりやすかったです。
参考:Alpine LinuxでMeCab with NEologd
参考:DockerでMeCab / Word2Vecの環境を構築する

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1