xonshで形態素解析
形態素解析
形態素解析は日本語の自然言語処理を行う上でよく使われる技術です。掻い摘んで言うと、文を品詞分解するというものです。 分解した後は文章を英語のようにスペースで区切る、所謂分かち書きを行ったり、単語の出現回数を数えたり、といった処理を行うことが出来ます。 そうして出来上がったデータは、LexRankや機械学習などに用いることが出来るのですが、今回は扱いません。 文章から単語を抽出するという処理だけでも、日常的に有用だと思ったので、形態素解析を気軽に使えるようなスクリプトを作りたいと思いました。
mecabインストール
形態素解析を行うためのパッケージとしてmecabを使用します。インストール方法については方方に情報があるので、コマンドだけ記載します。
sudo apt install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file swig sudo apt-get install mecab libmecab-dev mecab-ipadic mecab-ipadic-utf8 # ユーザー辞書をダウンロードしてインストールします。 # 辞書のアップデートに備えて覚えやすいディレクトリを作成して移動してから以下のコマンドを実行します。 git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git sudo ./bin/install-mecab-ipadic-neologd -n -a pip install mecab-python3
xonshスクリプト
mecabにはpython、コマンド実行とファイルアクセスにはシェルを使いたいのでxonshスクリプトを書きます。 スクリプトが書かれたxshファイルを、.xonshrcで起動時インポートするのが楽です。
カレントディレクトリを起点として再帰的に全てのファイルを連結する。
解析したいテキストを一つのファイルに集約するのも手間なので、コマンド一発でカレントディレクトリを起点にファイルを再帰的に検索して連結出来るようにします。
def _get_relative_path_tree(args, stdin=None): ''' sudo apt install tree ''' return $(tree -fi --noreport).split() aliases['get_relative_path_tree'] = _get_relative_path_tree def _cat_all(args, stdin=None): result = '' for item in _get_relative_path_tree([]): result += $(cat @(item)) return result aliases['cat_all'] = _cat_all
単語の抽出とカウント
文章から単語を抽出してカウントし、降順に並び替えた辞書を返却します。 第一引数は文字列、それ以降は、名詞、形容詞などといった品詞です。
def _node_freq_count(words, word): if word in words: words[word] += 1 else: words.setdefault(word, 1) def _mecab_analyze(args, stdin=None): import MeCab mecab_dir = $(mecab-config --dicdir).strip() + '/mecab-ipadic-neologd' mtag = MeCab.Tagger(f"-d {mecab_dir}") text = args[0] parts = args[1:] nodes = mtag.parseToNode(text) result = {} while nodes: if nodes.feature.split(",")[0] in parts: word = nodes.surface _node_freq_count(result, word) nodes = nodes.next result = dict(sorted(result.items(), key=lambda x:x[1], reverse=True)) return result aliases['mecab_analyze'] = _mecab_analyze
mecab-configコマンドで辞書のディレクトリを取得し、ユーザー辞書フォルダ名を連結したものを、Tagger初期化時のパラメータに渡しています。 sorted()はタプル入りリストを返すのですが、xonsh関数でタプル入りリストを返却するとエラーになるのがハマりポイントでした。
実行
以下のようなコマンドで実行できます。
mecab_analyze $(cat_all) 名詞