ランサーズ(Lancers)エンジニアブログ > DevOps > ランサーズの仕事を機械学習で分類する – 2. 分かち書き –

ランサーズの仕事を機械学習で分類する – 2. 分かち書き –

s.t|2017年07月10日
DevOps

分かち書きとは

分かち書きとは、テキストを空白区切りにしたものです。
テキストを機械学習させるには前段階としてテキストを分かち書き状態にする必要があります。

なんで休みなく働いている人が偉いの?
このテキストの分かち書き状態は下記の通りです。単語の意味ごとに空白で区切られます。
なんで 休み なく 働い て いる 人 が 偉 いの ?

分かち書き状態にするには、どれが日本語として意味をなしている単語なのかを見分ける必要があります。例えば、な んで 休 みな く働い てい る人が 偉い の? この状態だと分かち書きにはなっていますが、分割されている1つ1つの単語が日本語としては意味をなしていないので、情報としては無益です。なんでという単語が日本語として意味をなしているかどうかを判別するためには形態素解析エンジンを使います。形態素とは、言葉が意味をなす最小単位のことです。
英語は標準で分かち書きスタイルの言語なので、日本語のように手間をかけて分かち書きにする必要がありません。
日本語を分かち書きするには、MeCabという形態素解析エンジンを使います。MeCabよりも高機能を謳っているJUMAN++という形態素解析エンジンもありますが、辞書を使えばそればそれほど大きな差はないように感じるので、本ブログではMeCabを使います。

mecab本体のダウンロード

  • macOS Sierraの場合
brew install mecab
brew install mecab-ipadic
  • Ubuntu 16.04の場合
apt-get update && apt-get upgrade -y
apt-get install -y gcc g++ libmecab-dev mecab mecab-ipadic-utf8

辞書のダウンロード

MeCab本体には固有名詞が多くは入っていないので辞書をダウンロードします。
mecab-ipadic-NEologdというMeCab推薦の辞書があるのでこれを使います。

-n: 最新版をダウンロード
-a: 全部入り状態でダウンロード
-p: ダウンロードするパスを指定

任意の場所にダウンロードすればよいですが、例えば、~/mecab-ipadic-neologd/mecab-ipadic-neologdにダウンロードするよう指定します。
2GB以上の容量があるので、ネットワーク環境によっては少々時間がかかることもあります。

ダウンロードの途中でyesの入力が求められるので、yesと入力してください。

git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd -n -a -p ~/mecab-ipadic-neologd/mecab-ipadic-neologd

ダウンロードが完了したら、動くか試してみます。

  • 業務委託C言語 というテキストをMeCab本体だけで形態素解析した場合。mecabコマンドを実行すると入力待ち状態になるので 業務委託C言語 と入力し、Enterを押します。すると、入力したテキストが形態素解析されます。
mac:~ lancers$ mecab
業務委託C言語
業務  名詞,一般,*,*,*,*,業務,ギョウム,ギョーム
委託  名詞,サ変接続,*,*,*,*,委託,イタク,イタク
C      名詞,一般,*,*,*,*,*
言語  名詞,一般,*,*,*,*,言語,ゲンゴ,ゲンゴ
EOS
  • 業務委託C言語 というテキストをmecab-ipadic-neologd辞書を用いて形態素解析した場合。業務委託、C言語を1つの言葉として認識してくれます。
mac:~ lancers$ mecab -d ~/mecab-ipadic-neologd/mecab-ipadic-neologd
業務委託C言語
業務委託	名詞,固有名詞,一般,*,*,*,業務委託,ギョウムイタク,ギョームイタク
C言語     名詞,固有名詞,一般,*,*,*,C言語,シーゲンゴ,シーゲンゴ
EOS

PythonからMeCabを使用するパッケージのインストール

MeCabが使えるようになったので、次にPythonから使えるようにします。

pip install mecab-python3

MeCabをインポートして何もエラーが発生しなければインストール完了です。

mac:~ lancers$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type 'help', 'copyright', 'credits' or 'license' for more information.
>>> import MeCab

PythonからMeCabを使う

テキストを機械学習させるための前段階としての分かち書き処理は次のステップを経ます。

  1. MeCabモジュールのTaggerクラスをインスタンス化
  2. 分かち書きにしたいテキストを正規化
  3. 形態素解析する
  4. 形態素解析された結果から機械学習に使いたい単語を抜き出す
  5. 抜き出した単語を1つの文字列として分かち書き状態にする

Taggerクラスをインスタンス化する際には次の2つのパラメータを渡します。
-Ochasen: -Ochasenを指定することでtab区切りになり、返り値が扱いやすくなります。-Ochasenを指定すると次のようになります。
[‘C言語\tシーゲンゴ\tC言語\t名詞-固有名詞-一般\t’]
-d: 使用する辞書を指定します。mecab-ipadic-neologdをダウンロードしたパスを指定してください。

それでは、Pythonで形態素解析します。

# -*- coding: utf-8 -*-

import os, MeCab

document = 'なんで休みなく働いている人が偉いの?'
neologd_path = os.path.expanduser('~') + '/mecab-ipadic-neologd/mecab-ipadic-neologd'
tagger = MeCab.Tagger('-Ochasen -d %s' % neologd_path)
docs = tagger.parse(document)

print(docs)
なんで	ナンデ	なんで	副詞-一般		
休み	ヤスミ	休み	名詞-一般		
なく	ナク	ない	形容詞-自立	形容詞・アウオ段	連用テ接続
働い	ハタライ	働く	動詞-自立	五段・カ行イ音便	連用タ接続
て	テ	て	助詞-接続助詞		
いる	イル	いる	動詞-非自立	一段	基本形
人	ヒト	人	名詞-一般		
が	ガ	が	助詞-格助詞-一般		
偉い	エライ	偉い	形容詞-自立	形容詞・アウオ段	基本形
の	ノ	の	助詞-終助詞		
?	?	?	記号-一般		
EOS

tagger.parseの返り値は以下の特徴を持ちます。この4点を踏まえて機械学習に使いたい単語を抜き出します。  

  • 1つの文字列として返る
  • 1つの単語とその詳細が1行となっている
  • 1つ1つの要素はーOchasenを指定したのでタブで区切られている
  • 末尾にはEOSが入る

形態素解析を実行するメソッドにはtagger.parseToNodeというものもありますが、返り値の扱いがややこしいのでtagger.parseを使います。どちらを使っても結果は同じです。

まず、全体を1行ごとに区切り、リストにします。

str.split(sep): strをsepで区切り、リストで返します。

words = docs.split('\n')

print(words)
['なんで\tナンデ\tなんで\t副詞-一般\t\t', '休み\tヤスミ\t休み\t名詞-一般\t\t', 'なく\tナク\tない\t形容詞-自立\t形容詞・アウオ段\t連用テ接続', '働い\tハタライ\t働く\t動詞-自立\t五段・カ行イ音便\t連用タ接続', 'て\tテ\tて\t助詞-接続助詞\t\t', 'いる\tイル\tいる\t動詞-非自立\t一段\t基本形', '人\tヒト\t人\t名詞-一般\t\t', 'が\tガ\tが\t助詞-格助詞-一般\t\t', '偉い\tエライ\t偉い\t形容詞-自立\t形容詞・アウオ段\t基本形', 'の\tノ\tの\t助詞-終助詞\t\t', '?\t?\t?\t記号-一般\t\t', 'EOS', '']

必要な単語を抜き出して、1つの文字列として分かち書き状態にします。

str.join(iterable): iterable内の文字列をstrで結合して、文字列として返します。

res = []
for word in words:
    # EOS, ''の場合は無視
    if word == 'EOS' or word == '':
        continue

    # タブで区切り、リストにします
    word_info = word.split('\t')

    # 4番目に何詞かが格納されています。動詞と名詞だけを対象にします。
    if word_info[3][0:2] in ['動詞', '名詞']:
        # 3番目に基本形が格納されています
        res.append(word_info[2])

wakati = ' '.join(res)

# 1つの文に対して名詞と動詞の基本形だけが分かち書きされた状態になりました。
print(wakati)
休み 働く いる 人

分かち書きの実装は以上で完了です。これに正規化の処理を加えて、クラス化します。
コードはこちらにまとめました。

正規化に関してはこちらのページを参照してください。形態素解析の精度を落とさないようにするために全角・半角、記号等の扱いを適切にするのが正規化の目的です。

本章で実装した分かち書き処理を使って次章以降を進めます。
3. 特徴化へ続く(Coming soon)

Posted by Shigeomi Takada