【データサイエンス】Titanicサンプルで行うデータ前処理

##はじめに
こんにちは、皆さん！[@Raphael_de_murl](https://twitter.com/Raphael_de_murl)です。今回はデータ分析の定番であるKaggleで提供されてるTitanicデータを利用してデータの前処理を行いたいと思います。

##開発環境
OS: macOS Mojava 10.14.3
Memory: 16GB
開発ツール: Jupyter Notebook

##データ前処理とは
簡単に定義すると以下のようです。
>機械学習で行いたい作業に対してデータの読み込みやクリーニング、変形、整形といった作業のこと

##なぜ前処理が重要なのか
機械学習のプロジェクトにおいて一番時間がかかる作業が前処理だと言われでます。作業全体を10にするとデータ前処理が8割以上になるほど重要な作業であります。そもそも何でこんなに時間がかかるのかをみると扱いたいデータがファイルやデータベースに保存されていても分析者が必要なデータの形式で保存されてない事があるためです。そのような場合に多くの分析者は、汎用的なプログラミング言語を用いて、データを別の形式に変換するためのアドホックな処理を行うという対応をとります。

##欠損値の取り扱い
今回はこちらの[Titanic: Machine Learning from Disaster](https://www.kaggle.com/c/titanic)サイトからデータを用意しました。では実際コートを見ながら説明して行きます。

```python
import pandas as pd
from pandas import DataFrame

titanic_df = pd.read_csv('titanic.csv')
#0~9行までのデータを表示
titanic_df.head(10)
```
これでtitanic.csvの生データを確認する事が出来ます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/6817f291-3d79-0a25-a49c-86b5e28eccaa.png)
画像をよく見るとAge、Cabin列に<b>NaN</b>っていう文字がある事が分かります。Pandasのライブラリは、欠損値の表現として浮動小数値NaN(非数値、Not a Numberの意味)を使います。この値のことを、簡単に欠損値を見つけるための標識と読んでいます。ここで欠損値を列ごとに取りたいということであればPandasのisnull()メソッドを使うことで取ることが出来ます。

```python
#列ごとの欠損値をカウント
titanic_df.isnull().sum()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/1e6b64cf-ba4e-b6d8-5724-9fe4b6fbad45.png)
isnull()メソッドを使うことで一目で欠損値の把握ができることが分かります。

##欠損値を削除する
欠損値を削除する方法はいくつかあります。Pandas.isnull()と真偽値の配列を用いて手動で削除するという方法も常に選択の1つではありますが、Pandas.dropna()を使う方法が便利です。このdropna()を使うことで欠損値を含んでいる全ての行を削除することが出来ます。

```python
titanic_df.dropna()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/70c3bcb4-4f9f-347c-38af-1c27c3914978.png)

```python
#全てのデータがNaNである行のみを削除
titanic_df.dropna(how='all')
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/928998cb-9fe5-c5d5-5571-06f4d7e85a72.png)

```python
#欠測値を含む列を削除
titanic_df.dropna(axis=1)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/bc170987-663c-d1a4-aed1-d1c60cd522bb.png)

```python
#全ての列がNaNの行のみの列を削除
titanicdf.dropna(axis=1, how='all')
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/fc6c6c63-1004-3b45-5e95-ebf58ff99c0a.png)

##欠損値を穴埋めする
Pandas.dropna()で欠損値を簡単に削除することができますが、削除しすぎると後のデータ分析で役に立つ有効なデータも削除される場合もありますので、欠損値という【穴】を何らかの方法で埋めたい場合もあります。その役目を果たしてくれるのがfillnaメソッドです。簡単に言うと欠損値をある値で置き換えるということです。

```python
titanic_df.fillna(0)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/17bcdfb6-0ad5-bdc9-0fca-8032ec436ab9.png)

```python
#列ごとに異なる値を埋める
titanic_df.fillna({'Age':0, 'Cabin':'C01'})
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/f3c7ce7c-5bae-3118-5f9a-03469b80fb50.png)
Pandas.fillna()を使うことで指定した値で埋めることができることが分かります。

```python
#fillnaメソッドはデフォルトでは新しいオブジェクトを戻しますが、既存のオブジェクトを直接変更することも可能
titanic_df.fillna(0, inplace=True)
```
##データ分析を行う
上でデータ前処理を行うことで欠損値を削除又は値を置き換えました。実際簡単な分析をやってみましょう。Pandas.dropna（）を使って欠損値を扱います。

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from pandas import DataFrame
%matplotlib inline
#cabin列の欠損値がある行を削除
drop_titanic_df = titanic_df['Cabin'].drop()

levels = []
for level in drop_titanic_df:
    levels.append(level[0])

cabin_df = DataFrame(levels)
cabin_df.columns = ['Cabin']
```
ここまでは欠損値を除いたCabin列をdrop_titanic_df変数に入れて新しいオブジェクトに生成しました。これを用いてカウントをしてみます。
```python
sns.countplot('Cabin', data=cabin_df, palette='cool',order=sorted(set(levels)))
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/309361/667e8807-8d06-6ace-a51d-537cd3a8ef51.png)

##まとめに
サンプルとしてカウントしかやってないんですけれどもデータ前処理は生データによって前処理の手法が違うのでどの手法を選ぶべきなのかから始まるんだと思います。皆さんも手軽にやりながら勉強ができればと思います。この記事が少しでも気に入ったらいいねとフォロワー宜しくお願い致します。