Janomeで簡単に品詞登場順の精度を上げる隠し味

Janomeって便利ですよね。でもやはり自然言語処理は難しいものです。

初心者である私が品詞の登場順解析で精度向上した工夫を記します。


#目次
[1.はじめに](#1-はじめに)
[2.前処理編(カウント前)](#2-前処理編(カウント前))
[3.後処理編(カウント時)](#3-後処理編(カウント時))
[4.調理例](#4-調理例)
[5.おわりに](#5-おわりに)




#1. はじめに

```python
a = Analyzer(char_filters=cf,token_filters=tf)#解析器生成
results = a.analyze(text)#解析
```
の過程で、```Analyzer```を使うわけですが、この引数の部分をいじります。
**簡単に**を目指しているので複雑なことはしません。ごめんなさい。

#2. 前処理編(カウント前)

順位を出す前に予め文字を処理します。そこで登場するのがこちらです。

```python
 cf = [UnicodeNormalizeCharFilter()]#前処理フィルタ
```


### Unicodeの正規化

```python
UnicodeNormalizeCharFilter()
```

これを使うと、半角カタカナを全角カタカナにしてくれたり、アルファベットを半角で統一してくれたりする通称Unicodeの正規化と呼ばれるものをしてくれるみたいです。
このコードを追加するだけでいいんです。





#3. 後処理編(カウント時)
ここからは品詞登場順をカウントする際に適応される後処理部分をいじくります。

そこで登場するのがこちらです。

```python
syurui="形容詞"#←ここに順位出したい品詞名を入れる
zyogaiList=["名詞,代名詞","名詞,非自立","名詞,数"]#除外
tf = [CompoundNounFilter(),POSKeepFilter([syurui]),POSStopFilter(zyogaiList),TokenCountFilter(att='base_form')] #後処理フィルタ
```


### 複合名詞でカウント
```python
CompoundNounFilter()
```
これを使うと例えば
**「墾田永年私財法」**だと…

>「墾田」「永年」「私財」「法」4単語

``CompoundNounFilter()``適応後


>「墾田永年私財法」 1単語

のように**複合名詞を1単語としてカウント**してくれます。


### 順位にカウントしない品詞を選ぶ
```python
zyogaiList=["名詞,代名詞","名詞,非自立","名詞,数"]#除外
POSStopFilter(zyogaiList)
```


　```POSStopFilter()```を使うとカウントしない品詞を選べます。

例えば```zyogaiList=["名詞,代名詞","名詞,非自立","名詞,数"]```とすると
「これ」(名詞,代名詞)や、「の」(名詞,非自立)や、数字などを除外できます。
これも名詞の登場順などで、上位を代名詞が占領する状態を防げます。

### 活用形を統一して基本形としてカウント

```python
TokenCountFilter(att='base_form')
```
これを使うと品詞活用をまとめて基本形のみにしてくれます。
形容詞の登場順を出力する場合、あるあるなのが
>「楽しい」「楽しかっ」「楽しく」

が別々にカウントされてしまうことなのですが
これを使うと全部まとめて
>「楽しい」

としてカウントしてくれます。

<hr>

最後に
### 解析したい品詞を入れる

```python
syurui="形容詞"#←ここに順位出したい品詞名を入れる
POSKeepFilter([syurui])
```

を追加すると完成です。

前処理と後処理を用意できたので、後は使うだけです。

```python
a = Analyzer(char_filters=cf,token_filters=tf)#解析器生成
results = a.analyze(text)#解析
```


#4. 調理例





```python 
text="長い文章がここに入る"
syurui="形容詞"
zyogaiList=["名詞,代名詞","名詞,非自立","名詞,数"]#除外
cf = [UnicodeNormalizeCharFilter()]#前処理フィルタ
tf = [CompoundNounFilter(),POSKeepFilter([syurui]),POSStopFilter(zyogaiList),TokenCountFilter(att='base_form')] #後処理フィルタ
a = Analyzer(char_filters=cf,token_filters=tf)#解析器生成
results = a.analyze(text)#解析
print(syurui,"登場順")
s =sorted(results, key=lambda x:x[1],reverse=True)#結果並べ替え
for i,wc in enumerate(s):
    if i >= 50:break
    print((i +1),':',wc))

```

このコードを使うと…………

(```text=```の中には自分の日記を入れた場合の結果)

```
形容詞 登場順
1 : ('ない', 715)
2 : ('いい', 452)
3 : ('すごい', 244)
4 : ('悪い', 170)
5 : ('多い', 148)
6 : ('良い', 122)
7 : ('よい', 116)
8 : ('嬉しい', 110)
9 : ('辛い', 100)
10 : ('楽しい', 85)
11 : ('忙しい', 81)
12 : ('高い', 77)
13 : ('大きい', 77)
14 : ('怖い', 74)
15 : ('うまい', 66)
16 : ('強い', 66)
17 : ('難しい', 65)
18 : ('少ない', 61)
19 : ('弱い', 59)
20 : ('優しい', 58)
21 : ('つらい', 58)
22 : ('早い', 56)
23 : ('痛い', 53)
24 : ('遅い', 51)
25 : ('ほしい', 48)
26 : ('やばい', 43)
27 : ('ものすごい', 43)
28 : ('無い', 40)
29 : ('面白い', 37)
30 : ('低い', 37)
31 : ('凄い', 33)
32 : ('正しい', 32)
33 : ('長い', 27)
34 : ('まずい', 26)
35 : ('かわいい', 25)
36 : ('素晴らしい', 25)
37 : ('深い', 24)
38 : ('眠い', 22)
39 : ('悔しい', 22)
40 : ('厳しい', 21)
41 : ('羨ましい', 21)
42 : ('きつい', 19)
43 : ('新しい', 18)
44 : ('にくい', 18)
45 : ('遠い', 16)
46 : ('美味しい', 16)
47 : ('甘い', 15)
48 : ('可愛い', 14)
49 : ('おかしい', 14)
50 : ('欲しい', 14)
```
みたいな感じで出てきます。


#5. 終わりに

ご清聴いただきありがとうございました。