mecabを使って国内作家と海外作家の作品で一人称の割合を調べる

## はじめに

筆者は昨年の6月頃から機械学習の学習をはじめました。
半年間でpython基礎から機械学習でよく使用するライブラリ、基本的なモデルの扱い方など網羅的に学びましたので、いくつかアウトプットを行いたいと思い本記事に至ります。
普段はBtoC向けのWEBサイトの構築（静的～wordpress）を仕事としています。
キャリアチェンジとして学習をはじめ初投稿になりますので、ご指摘などありましたらコメントなどで教えていただけますと幸いです。

githubのリポジトリは下記になります。
[https://github.com/koichini/mecab-aozora-analyze](https://github.com/koichini/mecab-aozora-analyze)

## MeCabを使って日本人作家と海外作家の解析

形態素解析としてMeCabを使用し、青空文庫にある作品を解析します。
文化の違いがあるので、そのあたりの差を解析で出せればいいなと思います。
具体的には日本人作家は集団主義的、海外作家は個人主義的な差が生まれるのではないかと予想します。
解析の着地点としては一人称（わたし、自分など）に注目し
<dl>
<dt>日本人作家 : 集団主義的</dt>
<dd>一人称の割合が少なめ</dd>
<dt>海外作家 : 個人主義的</dt>
<dd>一人称の割合が多め</dd>
</dl>
としまして、文学作品にも一般的に言われているようなことが納得できるような結果が出るのか解析を行います。

## 開発環境

- Windows 
- Python 3.7.9  
- Pandas 1.2.0
- Anaconda 
- jupyter 1.0.0

## インストール
形態素解析をMeCabにて行いますので、自身の環境に合わせMeCabのインストール。日本語の対応まで行います。
参考記事はいくつかあると思いますが、私は下記を参考にさせていただきました。
[Windows環境のPython3でMeCabを使ってみよう - GIS奮闘記](https://www.gis-py.com/entry/mecab)

## 解析実装
それでは実際に実装していきます。

### データ読み込み
```python:baseBookAnalysis.ipynb
import re
import pandas as pd
import glob
import MeCab
from collections import Counter


title_list = []
author_list = []
text_list = []
text_count = []

columns = ["author", "title", "text", "count"]
values = [title_list, author_list, text_list, text_count]

# ファイルの読み込み
files = glob.glob("./books/*")
for file in files:

    with open(file) as h:
        lines = h.readlines()
        # タイトルの抽出
        title = lines[0]
        title = re.sub('\n', '', title)
        # 作家の抽出
        author = lines[1]
        author = re.sub('\n', '', author)
        author = re.sub('\u3000', '', author)
        title_list.append(title)
        author_list.append(author)

    with open(file) as f:
        # 本文と文字数の抽出
        text = f.read()
        # ヘッダーの除去
        text = re.split('\-{5,}', text)[2]
        # フッタの除去
        text = re.split('底本：', text)[0]
        # 最初の一の除去
        text = re.sub('一', '', text, 1)
        # ふりがなの削除
        text = re.sub('《.+?》', '', text)
        # 入力注の削除
        text = re.sub('［＃.+?］', '', text)
        # 空行の削除
        text = re.sub('\n\n', '\n', text)
        text = re.sub('\u3000', '\n', text)
        text_list.append(text)
        text_count.append(len(text))

```
こちらで[青空文庫](https://www.aozora.gr.jp/)より適当な作品をDLしてデータを作成する前準備を行います。
PandasのDataFrame形式に「作家 : `author`」「タイトル : `title`」「本文 : `text`」「文字数 : `count`」を構成することを想定。
`book`ディレクトリに格納されている作品データの各項目を抽出して、リスト形式で格納する一連の流れをループ処理しています。
形態素解析において正規表現は頻出しそうですが、その辺りは慣れが必要そうです。

### DataFrameの作成
```python:baseBookAnalysis.ipynb
df = pd.DataFrame()

for i, column in enumerate(columns):
    for value in values:
        df[column] = values[i]

df
```
![aozora01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144532/0d9f9b0c-7dd0-18ba-429f-4e17947a5013.png)
先ほど準備した各項目を使用してDataFrameを作成。
こちらで形態素解析を行う準備ができました。

### MeCabを使用した形態素解析
```python:baseBookAnalysis.ipynb
# MeCabで形態素解析
tagger = MeCab.Tagger("-Ochasen")

word_top = []

for text in list(df["text"]):

    result_words = []
    words = []

    result = tagger.parse(text)
    result_lines = result.split('\n')


    for result_line in result_lines:
        result_words.append(re.split('[\t,]', result_line))

    for result_word in result_words:
        if (result_word[0] not in ('EOS', '') and result_word[3] == '名詞-一般'):
            words.append(result_word[0])

    # 頻出単語TOP10を抽出
    counter = Counter(words)
    text_group = []
    for word, count in counter.most_common(10):
        add_word = '%s : %s' % (word, count)
        text_group.append(add_word)

    word_top.append(text_group)

df["word_ranking"] = word_top
df
```
![aozora02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144532/b6b33cda-8480-3582-1b05-942c3c5fc0a8.png)

こちらでいよいよ形態素解析を行います。
具体的には`MeCab`で本文を形態素(単語が意味を持つ最小の単位)に分解し、そこから名詞のみを抽出。
さらに名詞の頻出単語をTOP10までに絞込み`DataFrame'に格納しています。

### データの可視化
```python:baseBookAnalysis.ipynb
import warnings
warnings.filterwarnings('ignore')

import matplotlib.pyplot as plt
import japanize_matplotlib


for i, count_data in enumerate(df["word_ranking"]):
    list = []

    for j in count_data:
        # 整形
        count_list = j.split(" : ")
        list.append(count_list)

    book_title = df["title"][i] + ":" + df["author"][i]
    data = []
    labels = []

    for a in list:
        labels.append(a[0])
        data.append(a[1])

    fig = plt.figure()
    fig.patch.set_facecolor('white')
    plt.pie(data, labels=labels, autopct="%1.1f%%")
    plt.title(book_title, y=-0.15)

    plt.axis("equal")
    plt.show()
```
![fig01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144532/8c9aec3c-8999-2f85-7fce-7c97cb3adbb1.png)
![fig02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144532/b0ac5738-8293-eb6e-6c07-c1620d74214e.png)
![fig03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144532/7d538cdb-75a3-13a2-444f-147f97af3420.png)

可視化ができました！
作業前の予想ですが、見ての通り完全に合致しているとは言い切れませんがおおよそは満たしている結果になりました。
作風などにも左右されると思いますし、サンプル量も少ないですが今回の投稿では
<strong>データ読み込み -> データ整形 -> 形態素解析 -> 解析結果の可視化</strong>
の流れの実装に重きを置いているため、サンプル量を増やしたり分析を発展させるような部分はまた別の機会にします。

## さいごに
形態素解析を用いて、解析のはじめの一歩のような内容になりました。
MeCabさえ入れられれば割と手軽に長文を形態素分解できるので、アイデアや分析を繰り返すことで新たな発見生まれそうな可能性を感じ、とても楽しそうです。
今後も少しずつ昨年学んだ内容をアウトプットする形で、何回か投稿やリライトしていこうと思います。

【主な参考】
[Python で MeCab を使ってテキストの内容を形態素解析してみる ～小説内の頻出単語の抽出～ - GIS奮闘記](https://www.gis-py.com/entry/mecab-text)
感謝です。