言語処理100本ノック-36(pandas使用):単語の出現頻度

[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)[「第4章: 形態素解析」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch4)の[36本目「単語の出現頻度」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec36)記録です。
今回は出現回数カウントとソートというpandasが得意とする内容なので、超簡単です。

# 参考リンク

|リンク|備考|
|:--|:--|
|[036.単語の出現頻度.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/04.%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90/036.%E5%8D%98%E8%AA%9E%E3%81%AE%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6.ipynb)|回答プログラムのGitHubリンク|
|[素人の言語処理100本ノック:36](http://qiita.com/segavvy/items/932c1413e2552f208dfc)|多くのソース部分のコピペ元|
|[MeCab公式](https://taku910.github.io/mecab/)|最初に見ておくMeCabのページ|

# 環境

|種類|バージョン|内容|
|:--|:--|:--|
|OS|Ubuntu18.04.01 LTS|仮想で動かしています|
|pyenv|1.2.16|複数Python環境を使うことがあるのでpyenv使っています|
|Python|3.8.1|pyenv上でpython3.8.1を使っています<br>パッケージはvenvを使って管理しています|
|Mecab|0.996-5|apt-getでインストール|

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

|種類|バージョン|
|:--|:--|
|pandas|1.0.1|

# [第4章: 形態素解析](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch4)
## 学習内容
> 夏目漱石の小説『吾輩は猫である』に形態素解析器MeCabを適用し，小説中の単語の統計を求めます．
>> 形態素解析, MeCab, 品詞, 出現頻度, Zipfの法則, [matplotlib](http://matplotlib.org/), [Gnuplot](http://www.gnuplot.info/)

## ノック内容
> 夏目漱石の小説『吾輩は猫である』の文章（[neko.txt](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/neko.txt)）をMeCabを使って形態素解析し，その結果をneko.txt.mecabというファイルに保存せよ．このファイルを用いて，以下の問に対応するプログラムを実装せよ．

なお，問題37, 38, 39は[matplotlib](http://matplotlib.org/)もしくは[Gnuplot](http://www.gnuplot.info/)を用いるとよい．

### [36. 単語の出現頻度](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec36)
> 文章中に出現する単語とその出現頻度を求め，出現頻度の高い順に並べよ．

# 回答
## 回答プログラム [036.単語の出現頻度.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/04.%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90/036.%E5%8D%98%E8%AA%9E%E3%81%AE%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6.ipynb)

```python
import pandas as pd

def read_text():
    # 0:表層形(surface)
    # 1:品詞(pos)
    # 2:品詞細分類1(pos1)
    # 7:基本形(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')
    return df[(df['pos'] != '空白') & (df['surface'] != 'EOS') & (df['pos'] != '記号')]

df = read_text()

df['surface'].value_counts()[:30]

# 助詞と助動詞を除外
df[~df['pos'].str.startswith('助')]['surface'].value_counts()[:30]
```

## 回答解説
### 出現頻度カウントとソート
[ノック19本目「各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる」](https://qiita.com/FukuharaYohei/items/87f0413b87c6109e8ca4#019%E5%90%84%E8%A1%8C%E3%81%AE1%E3%82%B3%E3%83%A9%E3%83%A0%E7%9B%AE%E3%81%AE%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6%E3%82%92%E6%B1%82%E3%82%81%E5%87%BA%E7%8F%BE%E9%A0%BB%E5%BA%A6%E3%81%AE%E9%AB%98%E3%81%84%E9%A0%86%E3%81%AB%E4%B8%A6%E3%81%B9%E3%82%8Bipynb)で使った`value_counts`で重複削除とソートをします。デフォルトで降順ソートをしてくれるのが便利ですね。

```python:
df['surface'].value_counts()[:30]
```

助詞と助動詞を除外は、条件を加えているだけです。「助」から始まる品詞は助詞と助動詞くらいだろう、ということで`str.startswith`の否定条件にしました。

```python:
# 助詞と助動詞を除外
df[~df['pos'].str.startswith('助')]['surface'].value_counts()[:30]
```

### 出力結果(実行結果)
プログラム実行すると以下の結果が出力されます。
全対象の上位30件です。当然ではありますが、助詞と助動詞ばっかりで内容の類推ができないです。

```bash:出力結果(全対象)
の     9109
て     6697
は     6384
に     6147
を     6068
と     5476
が     5259
た     3916
で     3774
も     2433
だ     2272
し     2264
ない    2254
から    2001
ある    1705
な     1579
か     1446
ん     1416
いる    1249
事     1177
へ     1033
する     986
です     974
もの     971
君      955
云う     937
主人     928
う      922
よう     687
ね      673
Name: surface, dtype: int64
```

助詞と助動詞を出力対象外にしました。すべてを対象にするより、だいぶ「吾輩は猫である」の類推がしやすいです。

```bash:出力結果(助詞と助動詞を除外)
し     2201
の     1597
いる    1249
事     1177
する     986
もの     971
君      955
云う     937
主人     928
ある     723
ない     708
よう     687
ん      667
この     635
御      598
その     560
何      518
吾輩     477
人      449
そう     448
い      443
なる     410
なっ     403
これ     397
それ     370
来      367
見      349
迷亭     343
れ      327
時      316
Name: surface, dtype: int64
```