【前編】KaggleのKarnel上でtitanic問題を解いてみた ~データの特徴をつかむ~

#はじめに
　Kagglerの登竜門的な課題である、titanicコンペに改めて挑戦してみました。自身がこれまで勉強してきたことの再整理も含めて、課題に取り組んでおります。また本記事は【前編】【後編】に分けて、【前編】では、扱うデータの特徴をつかむこと、【後編】で予測モデルの構築に重きを置いて記載します。

#動作環境
・Kaggle kernel上


#コード

##ライブラリのインポート

```py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import plotly.offline as py
import plotly.graph_objs as go
import cufflinks as cf

py.init_notebook_mode(connected=True)
# デフォルトでPlotlyがオンラインモードになっているので、オフラインモードへと変更

#cf.go_offline()# 恒久的にデフォルトをオフラインモードに
```

##データセットの読み込み
```py
train=pd.read_csv("../input/train.csv")
test=pd.read_csv("../input/test.csv")
data=[train,test]
```

##データの中身を確認

```py
train.info()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/6d067500-31da-8af4-84a8-0756c66f1a4f.png)


```py
test.info() 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/bea89583-e448-af7d-5f31-c7eac7e162c3.png)


```py
train.head() #trainの先頭の5行を表示する
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/9014fed9-9254-37b2-11aa-f5533faf24c2.png)

各カラムの説明としては以下を参照

・PassengerId – 乗客識別ユニークID
・Survived – 生存フラグ（0=死亡、1=生存）
・Pclass – チケットクラス
・Name – 乗客の名前
・Sex – 性別（male=男性、female＝女性）
・Age – 年齢
・SibSp – タイタニックに同乗している兄弟/配偶者の数
・parch – タイタニックに同乗している親/子供の数
・ticket – チケット番号
・fare – 料金
・cabin – 客室番号
・Embarked – 出港地（タイタニックへ乗った港）


```py
train.tail() #同様にtrainの末尾の5行を表示しよう。
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/43e20165-6d0a-4963-0ffb-3b2444450ba3.png)


##データ欠損の確認

```py
train.isnull()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/43d66462-995c-7aaa-e561-eda901161b58.png)


```py
train.isnull().sum() #各列の欠損値を数える
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/176a7bb7-b3af-4316-3cb3-aaed5a653641.png)

```py
train.notnull().sum() #逆に、欠損値でないところを数える
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/42629f2e-cbf0-eee5-376e-70d1055ccf2b.png)


#相関関係の確認

```py
train.corr().style.background_gradient(cmap="autumn_r")

#Styler機能を用いて、色調を"autumn_r"として一覧表にして表示してみる
#train.corr()はデータの各要素（各列）同士の相関係数を表形式で視覚化する
#文字列データは自動的に外してくれる
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/d88f82b4-3474-872c-0566-13f96cf8a34d.png)


##生存率
###全体の生存率

　この事故で生き残った人はどれほどで、亡くなった人はどれほどいたのだろうか？
　生き残った人と亡くなった人の割合を円グラフにし、それぞれの人数を棒グラフにして、左右に並べて表示


```py
fig,ax=plt.subplots(1,2,figsize=(8,4))
ax[0].pie(train["Survived"].value_counts(),labels=["Deceased","Survived"] , autopct='%.1f%%' )
ax[0].set_title("Ratio of the Survived/Deceased")

sns.countplot(train["Survived"],ax=ax[1])
*棒グラフはseaborn使った方が楽
ax[1].set_title("The number of Survived/Deceased people")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/a1f80b87-d63f-af18-f131-f83ab375e889.png)


```py
print(train.Survived.mean())
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/877e1cbe-7194-5459-9583-9b7e783a1205.png)

###生存率 vs sex(性別)

```py
train.groupby(["Sex"]).sum()["Survived"] 
#男女でそれぞれ何名の方が生存したかを表示
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/fc8f96b5-a4c7-98f5-d535-0b545d3c9133.png)

```py
train.groupby(["Sex"]).sum()["Survived"].plot.bar() 
#男女でそれぞれ何名生き残ったかを、pandasのビルトイン描画機能を用いてグラフ化
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/65011444-2f51-17cc-f870-f8f10562e2c5.png)


###生存率 vs Pclass(チケットクラス)

```py
train.groupby(["Pclass"]).mean()["Survived"].plot.bar()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/12885527-1f84-2862-240e-de5fd46526c5.png)

```py
train.groupby(["Pclass"]).mean()["Survived"]
#train.groupby(["Pclass"])["Survived"].mean()　#でもOK
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/c158491c-98dd-3618-3093-f30647d86226.png)


###生存率 vs sex & P-class

上の方法では、生き残った人数しかわからないため、亡くなった人数も同時に調べたい。
女性で亡くなった人数、生き残った人数
男性で亡くなった人数、生き残った人数
を取得する

```py
train.groupby(["Sex","Survived"])["Survived"].count()
# train.groupby(["Sex","Survived"]).count()["Survived"]だと、動作しない
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/7827dd9a-7c9e-8587-6e40-655e9b692f1b.png)

これもpandasのビルトインの描画機能で棒グラフを作成

```py
train.groupby(["Sex","Survived"])["Survived"].count().plot.bar()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/24f3d903-ca41-1084-4770-f3444a5cfecf.png)

練習のため、seabornで同じ意味合いの棒グラフをプロット
棒グラフの横軸（カテゴリ）は"Survived"とし、縦軸はその人数とする。
ただし、棒グラフは性別でわけ、男性についてのグラフと女性についてのグラフが隣り合わせでプロットされるようにする

```py
#seaborn使って、性別ごとに２本のバーをまとめる
sns.countplot(x="Survived",hue="Sex",data=train)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/acfa03ea-8dcb-a7d5-c165-dd0c2d48565b.png)

性別ごとに生存率を求めてみよう

```py
#生存率を求める
train.groupby(["Sex"]).mean()["Survived"]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/a7835d5e-18eb-221e-71bb-cc1287da76f4.png)

```py
train.groupby(["Sex"]).mean()["Survived"].plot.bar()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/c598327d-2086-70f5-2dff-fd877938ef94.png)

"Sex"(2値),"Pclass"(3値)を元に6つにセグメントを分割し、それぞれについて生き残った人数を調べ、
表形式で表示し、これに"autumn_r"の色調で色をつける

```py
pd.crosstab([train["Sex"],train["Pclass"]],train["Survived"],margins=True).style.background_gradient(cmap='autumn_r')
#crosstabを使うとgroupbyと似たようなまとめかたができるが、groupbyと違って、抽出した集合にたいしてmeanやmaxなどの演算ができない
#人数だけ見てるとよくわからない
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/bcc53df2-a260-590a-7955-b0a0fff5c609.png)

Pclass,Sexによって出費額がどのように分布するかを図示してみよう。
violinplotを用いる

###violinplot

```py
sns.violinplot("Pclass","Fare",data=train,hue="Sex",split=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/c4e87e7a-0bff-2e72-25db-f9a9771b3621.png)

1等級のチケットは値段のばらつきが相当大きいようである。
そして、少数ではあるものの２等・３等より安い値段で１等に乗っていた
乗客もいたという点で、単純に１等が一番高いとは言えないことがわかった。
人によってここまで値段がばらついているあたり、大人の事情が垣間見える。

ところで、グラフをよくみると、縦軸が負の部分にプロットが食い込んでいることがわかる。
もしかして、"Fare"には負の数が含まれているのだろうか。
お金をもらって乗船している人がいるということだろうか。
min()関数を使って"Fare"列の最小値を見てみよう。

```py
train.Fare.min()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/5743beb8-693b-4093-69b6-9d6a73f2ade4.png)

さすがに最小値は負の数ではなかった。
violinplotの両側はカーネル密度推定の曲線であり、一つ一つのデータが正規分布による広がりを持っているため、
負の数が要素に含まれていなくても分布のプロットが負の領域にさしかかることが起こりうる。

Fareには負の数は含まれていなかったものの、無賃で乗船できた方はいたことがわかった。
無賃で乗った人は何人いて、そのうちの何割が生き残ったのだろうか。
調べてみよう。

train["Fare"]の値が0である行のうち、Survivedが１であるデータ数、０であるデータ数を数える。

```py

train.loc[train.Fare==0,"Survived"].value_counts()
```

残念ながら、無賃で乗船した方は一人を除いて全員(train分に限るが)亡くなったようである。
次に、生き残った人・亡くなった人をhueで区別して、それぞれについての乗車賃の分布をカーネル密度推定のグラフで示そう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/1b748066-6a77-8fe7-f098-a5b4d7d6b94b.png)

残念ながら、無賃で乗船した方は一人を除いて全員(train分に限るが)亡くなったようである。

###カーネル密度推定グラフ
次に、生き残った人・亡くなった人をhueで区別して、それぞれについての乗車賃の分布をカーネル密度推定のグラフで示す

```py
facet = sns.FacetGrid(train, hue="Survived",aspect=4)
facet.map(sns.kdeplot,'Fare',shade= True)
# facet.set(xlim=(0, 100))
facet.add_legend()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/ae97f428-8034-dd8e-e958-f11ad5861846.png)


どの港から乗ってきたかによってどれだけ生存率が異なるだろうか。
３つの港ごとの生存者数・志望者数を調べる

```py
train.groupby("Embarked").Survived.value_counts()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/1c9e07fd-6c0d-55f3-7518-4d934ad514da.png)

港ごとの生存率を、性別で区別して、factorplot(pointplotの形式)で描画

```py
sns.factorplot("Embarked","Survived",data=train,hue="Sex")
# sns.factorplot("Embarked","Survived",data=train)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/98b7de47-f49e-3c44-f9b6-b33ce03d9dea.png)

次は、横軸：各港、縦軸：生存率　を性別で区別したグラフを、Pclassごとに3つに分けて描画し、3つのグラフを並べる。

```py
sns.factorplot("Embarked","Survived",data=train , hue="Sex", col="Pclass")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/97553707-5353-88cc-899e-e1d18891a9ad.png)

```py
temp=pd.DataFrame()
```

```py
temp["FamilySize"]=train["SibSp"]+train["Parch"]
temp["Pclass"]=train["Pclass"]
temp["Sex"]=train["Sex"]
temp["Fare"]=train["Fare"]
```

```py
sns.factorplot("FamilySize","Fare",data=temp,hue="Sex",col="Pclass")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374781/852ab692-0455-14e1-0f33-b4af1c084d43.png)