形態素解析器（Janome）を使いこなしたい！

# はじめに
「形態素解析器を使いこなしたい！」、そう思ったのはいったいいつからか...

今回は形態素解析器であるJanomeの公式Documentを自分なりにまとめました！
形態素解析器の使い方がよくわかっていない方の参考になれば幸いです！

# 参考文献
[Janome API reference v0.4](https://mocobeta.github.io/janome/api/janome.html)
[Janome v0.4 documentation (ja)WELCOME TO JANOME'S DOCUMENTATION! (JAPANESE)](https://mocobeta.github.io/janome/)
[Python, Janomeで日本語の形態素解析、分かち書き（単語分割）](https://note.nkmk.me/python-janome-tutorial/)

# 目次
* **Tokenizer**
* **Analyzer**
    * char_filters
    * token_filters

# janome.tokenizer module
**入力した文字列を"Token"に変換**して出力します。

```python:tokenizer
from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()
phrase = "すもももももももものうち"
for token in tokenizer.tokenize(phrase):
  print(token)
```
>【output】
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ

**Tokenの属性**には分割した単語の情報が格納されています。
* **surface**：文章中で使われていた形そのもの
* **part_of_speech**：品詞の詳細
* **infl_type**：活用型（「語形変化」を表すinflectionから来ている？）
* **infl_form**：活用形
* **base_form**：基本形
* **reading**：読み
* **phonetic**：発音


# janome.analyzer module
**形態素解析のための前処理と後処理をまとめたフレームワーク**です。
抽出したい情報の条件をAnalyzerクラスを呼び出す際の引数に入れることで、
条件に該当した単語の情報を抽出することができます。

```python:analyzer
from janome.tokenizer import Tokenizer
from janome.analyzer import Analyzer
from janome.charfilter import *
from janome.tokenfilter import *

phrase = "蛇の目はPure Ｐｙｔｈｏｎな形態素解析器です。"
char_filters = [UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('蛇の目', 'janome')]
tokenizer = Tokenizer()
token_filters = [CompoundNounFilter(), POSStopFilter(['記号','助詞']), LowerCaseFilter()]
analyzer = Analyzer(char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters)
for token in analyzer.analyze(phrase):
  print(token)
```
>【output】
janome	名詞,固有名詞,組織,*,*,*,janome,*,*
pure	名詞,固有名詞,組織,*,*,*,pure,*,*
python	名詞,一般,*,*,*,*,python,*,*
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
形態素解析器	名詞,複合,*,*,*,*,形態素解析器,ケイタイソカイセキキ,ケイタイソカイセキキ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス

また、**文章中に各単語が何回出現したか数える**こともできます。
```python:token_count
phrase = "赤巻紙青巻紙黄巻紙"
analyzer = Analyzer(token_filters=[TokenCountFilter()])
word_count = analyzer.analyze(phrase)
for _ in word_count:
  print(_)
```
>【output】
('赤', 1)
('巻紙', 3)
('青', 1)
('黄', 1)

抽出条件はchar_filters、tokenizer、token_filtersの3つで設定します。

## char_filters
入力テキストに施す内容を設定します。
入力テキストに文字の正規化などの前処理を加えた後、tokenizerに渡します。
* **RegexReplaceCharFilter**
入力内に該当する文字列を別の文字列に変換します。
e.g. RegexReplaceCharFilter('蛇の目', 'janome')とすると、「蛇の目」が「janome」となります。

* **UnicodeNormalizeCharFilter**
Unicode文字列を正規化します。

## token_filters
tokenizerの出力に対して、小文字化，品詞によるトークンのフィルタリングなどを行います。
* **CompoundNounFilter**
tokenizerによって分割されたトークンを複合名詞として扱えるように再結合するクラスです。
e.g. "形態素/解析/器"　⇒　"形態素解析器"

* **ExtractAttirbuteFilter**
Token内から指定した属性の情報を取り出します。
e.g. ExtractAttributeFilter("base_form")ではそのトークンの基本形が抽出されます。

* **LowerCaseFilter**
Tokenのsurfaceとbase_formを小文字に変換します。

* **POSKeepFilter**
引数に入れた品詞に該当するTokenは残し、それ以外のTokenを除外します。
e.g. POSKeepFilter(["動詞"])とすると、‘動詞,自立,＊,＊’や‘動詞,非自立,＊,＊’などが残ります。

* **POSStopFilter**
POSKeepFilterの逆で、引数に入れた品詞に該当するTokenを除外します。

* **TokenCountFilter**
入力テキスト内の単語出現回数を数える。単語と出現回数をペアとして出力します。

# 終わり
以上です。
お読みいただきありがとうございました。

※誤りがありましたら、お手数ですがご指摘いただけますと幸いです。