トリコロールな猫/セキュリティ

思いついたことをぼちぼち書いてます。

MeCab用のセキュリティ用語辞書を作っています

日本語形態素解析システム「MeCab」を使って楽しく形態素解析をしているわけですが、セキュリティ用語が意外と辞書にないようで、期待通りの結果が出ないことが多いため、自分で作ってみることにしました。

とりあえずアウトプットしないと始まらないので、まだ102単語しか書いていないのですが公開します。

https://github.com/nekotricolor/mecab-it-security-dictionary

以下、苦労話です。読まなくてもいいですが読んだ上で褒めてほしい。

やりたいこと

たとえば「サイドチャネル」を解析してみると:

サイドチャネル
サイド   名詞,一般,*,*,*,*,サイド,サイド,サイド
チャネル    名詞,一般,*,*,*,*,チャネル,チャネル,チャネル
EOS

これを

サイドチャネル   名詞,固有名詞,一般,*,*,*,サイドチャネル,サイドチャネル,サイドチャネル

と一単語として認識するようにします。

MeCab入りのDockerイメージを作る

Ubuntu 18.04にRubyとMeCabを入れた環境を作ります。nattoはbundlerで。

Gemfileは以下の通り。

source "https://rubygems.org"

gem 'mecab'
gem 'natto'

Dockerfileは以下の通り。

FROM ubuntu:18.04
ENV LANG=C.UTF-8
ENV WORK_DIR /work
RUN mkdir -p ${WORK_DIR}
WORKDIR ${WORK_DIR}

RUN apt-get update && apt-get upgrade -y

# basic tools
RUN apt-get install -y git gdb file vim
RUN apt-get install -y curl wget ruby ruby-dev

# install mecab
RUN apt-get install libmecab2 libmecab-dev mecab mecab-ipadic mecab-ipadic-utf8 mecab-utils
RUN apt-get install -y make xz-utils build-essential

ADD Gemfile Gemfile
RUN gem install bundler
RUN bundle install

LANG環境変数の設定をしないと以下のようなMeCabのエラーがでます。すっごくハマりました。

/var/lib/gems/2.5.0/gems/natto-1.2.0/lib/natto/natto.rb:423:in `rescue in block (2 levels) in initialize': MECAB_NBEST request type is not set (Natto::MeCabError)

これでイメージを作ります。

% docker build -t mecab-ruby:basic .

シェルで作業したいのでDocker起動用に以下のようなシェルスクリプトを作りました。/Users/nekotricolor/Documents/mecab-it-security-dictionaryフォルダを/root/shareとしてマウントしています。

docker run --rm -it --name mecab-ruby -v /Users/nekotricolor/Documents/mecab-it-security-dictionary:/root/share mecab-ruby:basic /bin/bash

単語のリスト作り

Googleスプレッドシートで単語のリストを作ります。MeCabの辞書のフォーマットは以下の通り。

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音

品詞細分類はIPA品詞体系に基づくものです。定義通りに書いておかないとコンパイルできないので注意。

www.unixuser.org

今回は全て以下に統一しています。

  • 品詞:名詞
  • 品詞細分類1:固有名詞
  • 品詞細分類2:一般

例えば「サイドチャネル」の場合(左/右文脈IDとコストは後述):

サイドチャネル,1288,1288,20,名詞,固有名詞,一般,,,*,サイドチャネル,サイドチャネル,サイドチャネル

左/右文脈IDとコストはあとで入力するとして、とりあえず表層形・品詞・品詞細分類1・原形・読み・発音を埋めます。

単語登録の参考にさせていただいたサイトは以下の通りです。ありがとうございました。

www.atmarkit.co.jp

enterprisezine.jp

左/右文脈IDの決定

以前のバージョンでは左/右文脈IDは空欄にしておくと自動でつけてくれていたのですが、最新バージョンでは自分でつける必要があります。IDは、以下のファイルで定義されています。

  • left-id.def
  • right-id.def

該当部分はここ。左右同じでした。

1288 名詞,固有名詞,一般,,,,

ということで、左/右文脈IDは1288でいいみたいですね。

この記事が大変参考になりました。

kento1109.hatenablog.com

rooter.jp

辞書のコンパイルと追加

辞書のスプレッドシートを「mecab-it-security-dic.csv」という名前でcsv形式でダウンロードし、MeCabのmecab-dict-indexというコマンドを使ってコンパイルします。

システム辞書があるディレクトリを渡す必要があるのでそれを調べます。

$ mecab -D
filename:   /var/lib/mecab/dic/debian/sys.dic
version:    102
charset:    UTF-8
type:   0
size:   392126
left size:  1316
right size: 1316

「/var/lib/mecab/dic/debian/」ですね。

$ /usr/lib/mecab/mecab-dict-index -d /var/lib/mecab/dic/debian -u mecab-it-security-dic.dic -f utf8 -t utf8 mecab-it-security-dic.csv

これで、カレントディレクトリに「mecab-it-security-dic.dic」というファイルができます。/etc/mecabrcに以下を追加。

userdic = /root/share/mecab-it-security-dic.dic

「サイドチャネル」を解析してみると、無事一単語として認識されました。

サイドチャネル
サイドチャネル   名詞,固有名詞,一般,*,*,*,サイドチャネル,サイドチャネル,サイドチャネル
EOS

辞書の作成と、mecabのユーザ辞書への追加は以下の本家の記事を参考にしました。

taku910.github.io

これを使ってやりたいこと

  1. 登録単語数を増やすために、いろいろな記事を形態素解析してみて出てこない単語を拾う
  2. 表記の揺れをなんとかしたい(「水飲み場"型"攻撃」と「水飲み場攻撃」とか)
  3. 4年前から溜め込んでいるセキュリティ系ニュースのフィードを解析して何か面白い結果が出るか見たい
  4. 形態素解析する必要はなくて、今回作った辞書の単語でパターンマッチすればいいだけかも・・・