自然言語処理の前処理とMeCab(形態素解析エンジン)について

# はじめに
この記事は機械学習を行うための準備段階のお話です。
今回は自然言語処理における前処理と形態素解析についてまとめました。
[前回](https://qiita.com/you_gin/items/e982ed443c71771ee9b6)の記事では、PythonでWebスクレイピングを行いました。今回はスクレイピングで取得したテキストデータの前処理と形態素解析の予行演習をまとめました。

機械学習の一連の流れは以下になります。
1.機械学習のデータを集めるためにWebからデータをスクレイピング
1.5.テキストデータの前処理　**<font color="Red">←今ここ！</font>**
2.スクレイピングしたデータの整形（特徴量）
3.学習モデルの作成、検証

なお、テキストデータ前処理、形態素解析はPythonで実装しています。

# 自然言語処理の前処理について
機械学習を行う上で構造化された膨大な量のテキストデータが必要な場合もあります。構造化されていないテキストデータ（生のデータ）は人間から見たらある程度理解できると思いますが、機械学習ではテキストデータが持つ単語や、その意味を人間のように理解できるわけではありません。そのため、機械学習でもテキストデータを理解できるように構造化（例.単語のベクトル表現）する必要があります。

テキストデータの構造化を行う上で、不要な単語などの削除を行うことでテキストデータが持つ意味をより正確に把握することが可能です。
テキストデータの構造化（前処理）にも様々な手法があります。その中でも今回は**クリーニング処理**と**単語の正規化**を実施しています。

## クリーニング処理
クリーニング処理ではテキスト内に存在するノイズを削除します。ノイズとしては以下のようなものが挙げられます。

 - URL
 - 絵文字（こんなの→✨😀）
 - 記号（顔文字含む）

### 絵文字の削除
どのようなテキストデータを使用するかで絵文字の有無は変わる気がします。今回は食べログの口コミをテキストデータとして使用しているので、よく絵文字が出てきます😅
今回はPythonのパッケージである[emoji](https://pypi.org/project/emoji/)を使用しました。

```python
import emoji

# 絵文字の削除
result = ''.join(c for c in pre_result if c not in emoji.UNICODE_EMOJI)
```
参考にしたサイト→[pythonで絵文字を駆逐する](https://qiita.com/yoshimo123/items/85331d881aed9ad41020)

### URLの削除
URLの削除に関しては中々苦労してました。
URL部分と日本語部分の境目がなく、正規表現も色々試しました。
たどり着いた正規表現は以下のようなかんじになりました。

```python
import re

# URLの削除
result = re.sub('https?://[\da-zA-Z!\?/\+\-_~=;\.,\*&@#\$%\(\)\'\[\]]+', '', result)
```

### 記号の削除
記号の削除に関してはゴリ押しです。
引っかかりそうな記号（顔文字）から選出しています。

```python
import re

# 記号の削除
code_regex = re.compile('[\t\s!"#$%&\'\\\\()*+,-./:;；：<=>?@[\\]^_`{|}~○｢｣「」〔〕“”〈〉'\
    '『』【】＆＊（）＄＃＠？！｀＋￥¥％♪…◇→←↓↑｡･ω･｡ﾟ´∀｀ΣДｘ⑥◎©︎♡★☆▽※ゞノ〆εσ＞＜┌┘]')
result = code_regex.sub('', result)
```

## 単語の正規化
今回の単語の正規化については以下の処理を実施しています。

 - 文字種の統一
 - 数字の置き換え

他にも単語の正規化として、単語の統一がありますが、中々難しい部分もあり実装していません。

### 全角・半角の変換
文字種の統一として全角半角変換、およびアルファベットを全て小文字に変換しています。
以下2つの変換を行なっています。

 - 全角英数字から半角英数字の変換
 - 半角カナから全角カナの変換

このように文字種の統一を行うことで単語の表記揺れを少なくすることが目的です。
今回は全角半角変換に[mojimoji](https://pypi.org/project/mojimoji/)を使用しています。

```python
# 全角から半角に変換（カナは除く）
result = mojimoji.zen_to_han(text, kana=False)

# 半角カナから全角カナに変換
result = mojimoji.han_to_zen(result, ascii=False)

# 全ての文字を小文字に変換
result = result.lower()
```

### 数字の削除
自然言語処理において数字の表現はあまり重要でない場合があります。そのため、数字は別の記号に置き換えることが多いです。自分が扱うテキストデータにおいても数字はあまり意味を成さない可能性があるため、数字の置換を実装します。

```python
# 数字の削除
num_regex = re.compile('\d+,?\d*')
# 数字は全て0に置換する
result = num_regex.sub('0', result)
```

# 形態素解析について
自分たちが普段使っている言葉の中で、意味のある最小の要素を形態素と言います。話す言葉、書く言葉がどのような構成（名詞、動詞など）で成り立っているか調べる処理を**形態素解析**と呼びます。形態素解析を用いた単語の分割はテキストデータをベクトル表現するにあたり、必要不可欠な処理となります。
形態素解析について詳しく知りたい方は[こちら](https://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90)をご覧ください。

## MeCabについて
[Mecab](https://taku910.github.io/mecab/)はオープンソースの形態素解析エンジンになります。
他にも様々な形態素解析エンジンがあり、Pythonで有名どころとして[Janome](https://mocobeta.github.io/janome/)があります。

MeCabを選んだ理由としては[mecab-ipadic-NEologd](https://github.com/neologd/mecab-ipadic-neologd/blob/master/README.ja.md)というシステム辞書が存在するからです。
>mecab-ipadic-NEologd は、多数のWeb上の言語資源から得た新語を追加することでカスタマイズした MeCab 用のシステム辞書です。
>Web上の文書の解析をする際には、この辞書と標準のシステム辞書(ipadic)を併用することをオススメします。

このように記載されているため、使わない手はないと考えました。
MeCabやmecab-ipadic-NEologdのインストール、設定方法は以下のサイト参考にさせていただきました。

 - [MecabをPythonで使うまで](https://qiita.com/Sak1361/items/47e9ec464ccc770cd65c)
 - [新し目の辞書を使ってMeCabをPythonから利用する](https://qiita.com/yuichy/items/5c8178e5cc3711386b77)
 - [Pythonから呼び出すMeCabのデフォルト辞書を変更する](https://qiita.com/shimajiroxyz/items/3b475da3b6cd850d2c22)

## MeCabを使ってみる
さっそくインストールしたMeCabを使って形態素解析を試してみたいと思います。

最初にデフォルト辞書を使用したMeCabを試します。
![mecab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671222/665da280-89c8-d407-4746-eabd61591d72.png)
デフォルト辞書のMeCabでは「エモい」や「インスタ映え」などの新しい言葉に対して期待する形態素解析が行えていません。
一方、mecab-ipadic-NEologdを使用したMeCabで再度、形態素解析を行います。
![mecab_neologd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671222/8536c9a1-7102-f7cb-252d-29c77e343c5c.png)
mecab-ipadic-NEologdを使用したMeCabでは「エモい」や「インスタ映え」が正しく認識されています。

# まとめ
今回は自然言語処理において精度向上のために必要な前処理についてまとめてみました。
これらの前処理を経て、今後は自分のやりたいことが実現できる機械学習モデルを作成するため、単語のベクトル表現を模索していきます。

# 参考サイト
[自然言語処理における前処理の種類とその威力](https://qiita.com/Hironsan/items/2466fe0f344115aff177)
[自然言語（前）処理](https://qiita.com/dcm_sawayama/items/406408e8bda0840a8106)
[Python3×日本語：自然言語処理の前処理まとめ](https://qiita.com/chamao/items/7edaba62b120a660657e)
[基本的な正規表現一覧](https://murashun.jp/blog/20190215-01.html)