Help us understand the problem. What is going on with this article?

Janomeを使ってPythonで形態素解析

More than 1 year has passed since last update.

TL;DR

  • Pythonで形態素解析をしたい
  • mecab-python3も良いが、MeCabを入れたりするのは避けたい
    • 要は、pipで完結させたい
  • Janomeを使うのがいいのではないだろうか

Janome

Pythonで実装された、形態素解析器だそうです。

Janome

作者様は、Apache Luceneのコミッターをされていらっしゃいますね。

APIリファレンスは、こちら。

Janome API reference

以下の特徴を持つようです。

  • Python 2.7または3.3以上で動作
  • Tokenizerを使った、形態素解析ライブラリ
  • janomeスクリプトを使用したコマンドラインでの実行が可能
  • デフォルトの辞書はmecab-ipadic-2.7.0-20070801
  • ユーザー定義辞書の利用
  • mmapのサポート
  • Graphvizファイルの作成
  • Analyzerフレームワーク(experimental)

などなど。

Q&Aにもありますが、速度自体はMeCabには敵わないようなので、用途に合わないようであればMeCabを使用する方がよいでしょう。

環境

今回の環境は、こちらです。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic


$ python3 -V
Python 3.6.8

この環境に、Janomeをインストールして簡単に形態素解析して遊んでみます。

Janomeのインストール

pipでインストールすれば完了です。

$ pip3 install janome

今回のJanomeのバージョンは、こちら。

$ pip3 freeze
Janome==0.3.9

Tokenizerを使う

では、ドキュメントを見ながら、まずはTokenizerを使ってみましょう。

使い方

サンプルコード。

hello_tokenizer.py

from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()

sentenses = [
    "ギョエェェエーと叫ぶだけの人生だった。",
    "最終兵器は懐にしまいます。",
    "お前は助からない。",
    "ログを読め。",
    "さあご一緒に!「TRUE 1 が TRUE! TRUE 0 が FALSE!」"
]

for sentence in sentenses:
    print("=============================================")
    print(sentence)

    for token in tokenizer.tokenize(sentence):
        print("    " + str(token))

Tokenizerのインスタンスを作成して

tokenizer = Tokenizer()

形態素解析したい文字列をtokenizeメソッドに渡せばOKです。

    for token in tokenizer.tokenize(sentence):

実行結果。

$ python3 hello_tokenizer.py
=============================================
ギョエェェエーと叫ぶだけの人生だった。
    ギョエェェエー   名詞,一般,*,*,*,*,ギョエェェエー,*,*
    と 助詞,格助詞,一般,*,*,*,と,ト,ト
    叫ぶ  動詞,自立,*,*,五段・バ行,基本形,叫ぶ,サケブ,サケブ
    だけ  助詞,副助詞,*,*,*,*,だけ,ダケ,ダケ
    の 助詞,連体化,*,*,*,*,の,ノ,ノ
    人生  名詞,一般,*,*,*,*,人生,ジンセイ,ジンセイ
    だっ  助動詞,*,*,*,特殊・ダ,連用タ接続,だ,ダッ,ダッ
    た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
    。 記号,句点,*,*,*,*,。,。,。
=============================================
最終兵器は懐にしまいます。
    最終  名詞,一般,*,*,*,*,最終,サイシュウ,サイシュー
    兵器  名詞,一般,*,*,*,*,兵器,ヘイキ,ヘイキ
    は 助詞,係助詞,*,*,*,*,は,ハ,ワ
    懐 名詞,一般,*,*,*,*,懐,フトコロ,フトコロ
    に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
    しまい   動詞,自立,*,*,五段・ワ行促音便,連用形,しまう,シマイ,シマイ
    ます  助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
    。 記号,句点,*,*,*,*,。,。,。
=============================================
お前は助からない。
    お前  名詞,代名詞,一般,*,*,*,お前,オマエ,オマエ
    は 助詞,係助詞,*,*,*,*,は,ハ,ワ
    助から   動詞,自立,*,*,五段・ラ行,未然形,助かる,タスカラ,タスカラ
    ない  助動詞,*,*,*,特殊・ナイ,基本形,ない,ナイ,ナイ
    。 記号,句点,*,*,*,*,。,。,。
=============================================
ログを読め。
    ログ  名詞,サ変接続,*,*,*,*,ログ,ログ,ログ
    を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
    読め  動詞,自立,*,*,五段・マ行,命令e,読む,ヨメ,ヨメ
    。 記号,句点,*,*,*,*,。,。,。
=============================================
さあご一緒に!「TRUE 1 が TRUE! TRUE 0 が FALSE!」
    さあ  感動詞,*,*,*,*,*,さあ,サア,サー
    ご 接頭詞,名詞接続,*,*,*,*,ご,ゴ,ゴ
    一緒  名詞,サ変接続,*,*,*,*,一緒,イッショ,イッショ
    に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
    ! 記号,一般,*,*,*,*,!,!,!
    「 記号,括弧開,*,*,*,*,「,「,「
    TRUE    名詞,固有名詞,組織,*,*,*,TRUE,*,*
        記号,空白,*,*,*,*, ,*,*
    1   名詞,数,*,*,*,*,1,*,*
        記号,空白,*,*,*,*, ,*,*
    が 接続詞,*,*,*,*,*,が,ガ,ガ
        記号,空白,*,*,*,*, ,*,*
    TRUE    名詞,固有名詞,組織,*,*,*,TRUE,*,*
    ! 記号,一般,*,*,*,*,!,!,!
        記号,空白,*,*,*,*, ,*,*
    TRUE    名詞,固有名詞,組織,*,*,*,TRUE,*,*
        記号,空白,*,*,*,*, ,*,*
    0   名詞,数,*,*,*,*,0,*,*
        記号,空白,*,*,*,*, ,*,*
    が 接続詞,*,*,*,*,*,が,ガ,ガ
        記号,空白,*,*,*,*, ,*,*
    FALSE   名詞,固有名詞,組織,*,*,*,FALSE,*,*
    ! 記号,一般,*,*,*,*,!,!,!
    」 記号,括弧閉,*,*,*,*,」,」,」

形態素解析の結果は、Tokenとして取得できます。

https://mocobeta.github.io/janome/api/janome.html#janome.tokenizer.Token

Token自体を文字列として出力した時になにが出ているかは、こちらを参照するとよいでしょう。

https://github.com/mocobeta/janome/blob/0.3.9/janome/tokenizer.py#L131-L143

例えば、表層形(surface)と基本形(base_form)を出力してみます。

for sentence in sentenses:
    print("=============================================")
    print(sentence)

    for token in tokenizer.tokenize(sentence):
        print("    " + token.surface + " | " + token.base_form)

こんな感じの結果に。

=============================================
ギョエェェエーと叫ぶだけの人生だった。
    ギョエェェエー | ギョエェェエー
    と | と
    叫ぶ | 叫ぶ
    だけ | だけ
    の | の
    人生 | 人生
    だっ | だ
    た | た
    。 | 。
=============================================
最終兵器は懐にしまいます。
    最終 | 最終
    兵器 | 兵器
    は | は
    懐 | 懐
    に | に
    しまい | しまう
    ます | ます
    。 | 。
=============================================
お前は助からない。
    お前 | お前
    は | は
    助から | 助かる
    ない | ない
    。 | 。
=============================================
ログを読め。
    ログ | ログ
    を | を
    読め | 読む
    。 | 。
=============================================
さあご一緒に!「TRUE 1 が TRUE! TRUE 0 が FALSE!」
    さあ | さあ
    ご | ご
    一緒 | 一緒
    に | に
    ! | !
    「 | 「
    TRUE | TRUE
      |  
    1 | 1
      |  
    が | が
      |  
    TRUE | TRUE
    ! | !
      |  
    TRUE | TRUE
      |  
    0 | 0
      |  
    が | が
      |  
    FALSE | FALSE
    ! | !
    」 | 」

活用形で書かれていた場合に、基本形が確認できたりします。

=============================================
ログを読め。
    ログ | ログ
    を | を
    読め | 読む
    。 | 。

表層形のみがあればよい場合は、分かち書きモードを使用するとよいみたいですよ。

分かち書きモード

janomeスクリプトを使う

コマンドラインからJanomeを使う場合は、janomeスクリプトを使用します。

mecabコマンドのように使えます。

echoなどからパイプで渡してもいいですし

$ echo 'ログを読め。' | janome
ログ  名詞,サ変接続,*,*,*,*,ログ,ログ,ログ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
読め  動詞,自立,*,*,五段・マ行,命令e,読む,ヨメ,ヨメ
。 記号,句点,*,*,*,*,。,。,。

1度コマンドを起動して

$ janome

対話的に入力してもOKです。

私は、東京都に行く。
私 名詞,代名詞,一般,*,*,*,私,ワタシ,ワタシ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
、 記号,読点,*,*,*,*,、,、,、
東京  名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー
都 名詞,接尾,地域,*,*,*,都,ト,ト
に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
行く  動詞,自立,*,*,五段・カ行促音便,基本形,行く,イク,イク
。 記号,句点,*,*,*,*,。,。,。

ヘルプ。

$ janome -h
usage: janome [-h] [-e ENC] [--udic UDIC] [--udic-enc UDIC_ENC]
              [--udic-type UDIC_TYPE] [-m [MMAP]] [-g [GRAPHVIZ]]
              [--gv-out GV_OUT] [--gv-format GV_FORMAT] [--version]

optional arguments:
  -h, --help            show this help message and exit
  -e ENC, --enc ENC     Input encoding. Default is 'utf8'
  --udic UDIC           Path to user dictionary file
  --udic-enc UDIC_ENC   User dictionary encoding. Default is 'utf8'
  --udic-type UDIC_TYPE
                        User dictionary type, 'ipadic' or 'simpledic.' Default
                        is 'ipadic'
  -m [MMAP], --mmap [MMAP]
                        Use mmap mode
  -g [GRAPHVIZ], --graphviz [GRAPHVIZ]
                        Output visualized lattice graph by Graphviz
  --gv-out GV_OUT       Graphviz output file path. This option is used with -g
                        or --graphviz
  --gv-format GV_FORMAT
                        Graphviz output format. default is 'png'. This option
                        is used with -g or --graphviz. See
                        https://graphviz.gitlab.io/_pages/doc/info/output.html
                        for the supported formats.
  --version             show program's version number and exit

Analyzerフレームワーク

Janomeには、Ananlyzerフレームワークというものがあり、文字の正規化などの前処理を行うCharFilter、形態素解析後の後処理を行うTokenFilterCharFilterTokenizerTokenFilterを組み合わせて構成するAnalyzerから成っています。

(experimental) Analyzer フレームワーク

https://mocobeta.github.io/janome/api/janome.html#module-janome.analyzer

https://mocobeta.github.io/janome/api/janome.html#module-janome.charfilter

https://mocobeta.github.io/janome/api/janome.html#module-janome.tokenfilter

今回は、先ほどのサンプルで扱った文をちょっと修正して、遊んでみます。

CharFilterとしてUnicodeNormalizeCharFilterを選んで全角英数字を正規化し(デフォルトでNFKC)、TokenFilterとしてPOSStopFilterを使って特定の品詞を除去、LowerCaseFilterで小文字化を行います。

hello_analyzer.py

from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.charfilter import *
from janome.tokenfilter import *

text = "さあご一緒に! TRUE 1 が TRUE TRUE 0 が FALSE!"

char_filters = [ UnicodeNormalizeCharFilter() ]
tokenizer = Tokenizer()
token_filters = [ POSStopFilter(["記号", "助詞", "接続詞"]), LowerCaseFilter() ]

analyzer = Analyzer(char_filters, tokenizer, token_filters)

for token in analyzer.analyze(text):
    print(token)

結果は、こちら。

$ python3 hello_analyzer.py 
さあ  感動詞,*,*,*,*,*,さあ,サア,サー
ご 接頭詞,名詞接続,*,*,*,*,ご,ゴ,ゴ
一緒  名詞,サ変接続,*,*,*,*,一緒,イッショ,イッショ
!   名詞,サ変接続,*,*,*,*,!,*,*
true    名詞,固有名詞,組織,*,*,*,true,*,*
1   名詞,数,*,*,*,*,1,*,*
true    名詞,固有名詞,組織,*,*,*,true,*,*
true    名詞,固有名詞,組織,*,*,*,true,*,*
0   名詞,数,*,*,*,*,0,*,*
false   名詞,固有名詞,組織,*,*,*,false,*,*
!   名詞,サ変接続,*,*,*,*,!,*,*

簡単に使えて、良さそうですね。

charon
"CROSS THE RUBICON”
https://github.com/charon-r13b
tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away