データ解析の流れを最速で俯瞰する【Kaggleタイタニック】

データ解析の流れを最速で俯瞰する【Kaggleタイタニック】

はじめに

この記事はあくあたん工房 Advent Calendar 2019,12日目の記事です.Advent Calendarにはなんでもありな面白い記事が載ってるのでぜひ下のリンクから

https://adventar.org/calendars/3951

この記事では統計やデータ解析を趣味としている僕と一緒に、Kaggleを通してさらっと高速でデータ解析の流れを俯瞰してみるというのを一緒にやっていけたらと思います。最速なんていっちゃってーという感じですが、内容をしっかりしつつどこまで楽に早く知ってもらえるのか僕の挑戦です、よろしくお願いします笑



今回用いる題材はデータ解析のコンペ「Kaggle」でのチュートリアル「タイタニック」です。内容は、

「タイタニック号の沈没事故を題材に、乗客の情報(性別、年齢、どこから乗船したか、客室のクラスなど)から生存者を予測する」

というのものです。




なお、今回の記事はKaggleのカーネル(ソースコードを公開できるるところ)を利用して、LD Freemanさんの記事の翻訳、超大雑把な要約がメインでそれに自分のアレンジを加えたものになります。その点だけご了承お願いします。


使用元リンク「A Data Science Framework: To Achieve 99% Accuracy




今回最も重要視するのはタイトルにもある通り「最速」と「俯瞰」です。つまり「さらっと流して理解する」のでコードの詳細や手法の詳細は説明しません。というかもうコードは載せません。ビジュアルとテキストと通してデータサイエンスをさらっていきましょう!!(ちなみに自分はプロでもなんでもなく趣味でやっているだけなので間違いとかも普通にあると思われます。そのあたりあれば教えてください。)




ちなみに、上のリンク見てもらえばわかりますが凄い量です笑 中々読んでいられないと思うので本当にさらっとやります。気になる!と思った方は、ぜひ実際に手を動かしてやってみてください!



(ちなみにタイムリーなので書きますと、僭越ながら先日データ解析の予測精度を競う大会で2位で準優勝しました。データ解析系のイベントの賞金は、他の普通のハッカソンとかと比にならないぐらいでやすい傾向がある気がするので結構挑戦し甲斐もあるかもしれません)



それではやっていきましょう!



※Kaggleとは何ぞ? → データ解析のコンペティションサイトです

※実際に手を動かしてやってみたい → Kaggleに登録するところから始めてください。ググれば大量にヒットしますので大丈夫です、誰でもすぐに始められます! 



実行環境だけ確認

データセット(csvファイル)はKaggleから取得できますのでそれを用います。

コードは基本載せないですが、元記事のソースコードは以下の自分の環境でも動いたので、載せておきます。実行にはjupyter notebookを利用します。

import sys #access to system parameters https://docs.python.org/3/library/sys.html
print("Python version: {}". format(sys.version))

import pandas as pd #collection of functions for data processing and analysis modeled after R dataframes with SQL like features
print("pandas version: {}". format(pd.__version__))

import matplotlib #collection of functions for scientific and publication-ready visualization
print("matplotlib version: {}". format(matplotlib.__version__))

import numpy as np #foundational package for scientific computing
print("NumPy version: {}". format(np.__version__))

import scipy as sp #collection of functions for scientific computing and advance mathematics
print("SciPy version: {}". format(sp.__version__))

import IPython
from IPython import display #pretty printing of dataframes in Jupyter notebook
print("IPython version: {}". format(IPython.__version__))

import sklearn #collection of machine learning algorithms
print("scikit-learn version: {}". format(sklearn.__version__))

#misc libraries
import random
import time


#ignore warnings
import warnings
warnings.filterwarnings('ignore')
print('-'*25)
Python version: 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 14:00:49) [MSC v.1915 64 bit (AMD64)]
pandas version: 0.25.3
matplotlib version: 3.1.1
NumPy version: 1.17.4
SciPy version: 1.3.1
IPython version: 7.9.0
scikit-learn version: 0.21.3
-------------------------

データサイエンスフレームワーク

データサイエンスの流れは基本的に以下のようになります。なおこれはFreemanさんが行っているものであり、全員がこの通りやっているわけではないことに注意してください。あくまで方法の一つとしてみてみてください。

⓵課題設定

・今回は先に軽く述べたように「タイタニック号沈没時の乗客の生存結果を予測するアルゴリズムの開発」になります。

⓶データ収集

・すでにKaggle側が用意してくれているので次から自分たちが取り組む内容になります。

 ⓷前処理

前処理と聞くと色んな方法がありますが、大まかには以下4つに大別されます。

Freemanさんは以下のように記しています。

「The 4 C’s of Data Cleaning: Correcting, Completing, Creating, and Converting」

つまり

Correcting:  異常値と外れ値の対策

Completing: 欠損値の補間

Creating: 分析のための新しい特徴量の作成

Converting: 機械学習への入力とするための変数の数値化

ですね。生データは外れ値や欠損値など大量にあったりしますから、データの整形が必要ということ、文字列などはそのままでは扱えないので数値化しましょうということです!

④統計による探索的分析の実行

前処理によってすべてが数値化されたのでグラフや統計手法を用いてデータ間の繋がり、特徴を見ていきます。これで課題解決のためにキーとなる特徴量や関係性を見つけることになります。ここからまた⓷の特徴量選択に戻る事も多々あります。

ちなみに探索的データ分析という言葉も良く用いられ、英語では基本EDA(Explanatory Data Analysis)という略語が使われています!

⑤データモデリング

EDAまでできたので次は機械学習モデルを作ります。

元記事では「データサイエンスとは、数学とコンピュータサイエンスとビジネスマネジメント間の学問領域にわたる分野である」と言っています。つまり機械学習やるには数学とコンピュータサイエンスの力がある程度は求められるし、問題を捉えるにはビジネス的な洞察力も欠かせないということを言っています。

そして機械学習を行うにあたっては、

最良のアルゴリズムを事前に推し量ることができないという「No Free Lunch Theorem」が存在、万能なスーパーアルゴリズムなんてない、と言っています。

初心者が良く言う質問に

“what is the best machine learning algorithm?”

がありますが、

ということです。

じゃあどうするのかというと、

・複数の機械学習手法を試して、精度比較するのが良い

と述べています。要するにトライ&エラーってことです。

⑥モデルの性能を評価

⑤までで得た予測精度の値(評価指数の値)からどうしていくかを決めます。限られた時間の中で精度を上げることにどれだけリソースを割くのか、どこを着地点とするのかなど、ビジネス的な観点が述べられていますが、一旦ビジネス的な話は置いておきましょう。

自分たちはここからさらにパラメータチューニングや特徴量の改善などが考えられますね。

さて、さらっと流れを抑えましたが、実際にこの通りに行うかと言われれば、モデリングしたあとに特徴量作り直すとか普通にありますし、分析して新しく特徴量作ってみることもあるので⓷④⑤は行ったり来たりします。ですが今回はこの流れに習ってやってみましょう!

前処理

データを読み込み、どんな変数(特徴量)があるのかまずは確認です。

今回のデータセットの中身は以下の通りです。学習データを見てみましょう。

※画面が小さく見にくい場合はクリックして拡大してみてください。

目的は生存者の予測なので「Survived」が1か0かを予測することになります

簡単にカテゴリの説明をすると

PassengerId 乗客に割り当てられた番号
Pclass チケットのクラス(客室のグレード)
Name 人の名前
Sex 性別
Age 年齢
SibSp タイタニックに同乗している兄弟/配偶者の数
Parch タイタニックに同乗している親/子供の数
ticket チケット番号
fare 料金
cabin 客室番号

Emberked:タイタニックへ乗船した場所

(テーブルの数が足りずに漏れてしまいました)

という感じになっています。ではデータサイエンスフレームワークの手順通り前処理をしていきましょう!



まず最初に、

「Correcting:異常値と外れ値の対策」

ですが、今回のデータセットには外れ値はなかったので飛ばします。

「Completing:欠損値の補完」

から行っていきます!

まずは欠損値がいくつあるか確認してみると….

言い忘れていました、学習用データセットが891件、テスト用データセットが418件です。なので、Cabinはあまりにも欠損値の割合が多すぎますね。このような特徴量は使えないのでデータから落とします(後程)。あとはAgeとEmberkedですが、そんなに件数は多くないので欠損値を埋めましょう。

埋め方としては一般的に「平均値」「中央値」「最頻値」などがありますが、ここでは以下のように埋めることとしておきます。

・Ageの欠損を中央値で補完

・Emberkedの欠損を最頻値で補完

・Fareの欠損を中央値で補完

次に生存を予測するにあたって全く因果として関係性のないものを、先ほどのCabinと一緒に落としてデータから落としてしまいましょう。

・PassengerId

・Ticket

・Cabin

を落とすと以下のようになりました。

特徴が少なければ良いという訳でもありません。

次にFreemanさんは精度向上に向けて、新しい特徴を生成しています。

3つめの「Creating: 分析のための新しい特徴量の作成」です。

上のデータから作れるもので、

・FamilySize : 家族の構成人数 

・isAlone: 一人かどうか

・Title: Mr. Ms.など

を新しく作成しています。

一人かどうか、家族構成というのは「家族なら一緒に行動していることが多いので、生存か死亡かは似た性質を持ちそう」という予測からきていると考えられます。Titleははっきりとは分かりませんが関係性があるのでしょうか。(詳しくない)

そこからさらに

FareBin : 料金を4分割にしたもの

AgeBin: 年齢を4分割したもの

を特徴量として作成しています。

連続値ではなく分割してグループ化している感じですね!こういう分割するという手法は良く使われます。連続値のまま使うよりも上手く効くことがあります。4という数字はおそらく手探り、あるいはざっとデータを眺めて良い感じに分割できそうとかって感じでしょうか。はっきりとは分かりません。

そんな感じで次のように特徴量ができました。

次に4C最後の「Convert: カテゴリ変数を数値に変換」します!

良く使われるのに手法には

LabelEncoding 男、女を1,2にするみたいな感じです。
OneHotEncoding 男、女を男カラムを作って男なら1, 女なら0とする,  女カラムも作って女なら1,男なら0にするという感じで特徴量の次元が増えます。
TargetEncoding

何かの特徴量と、目的の特徴量(ここではSurvive)を元にして新しく特徴量を作り出す方法ですが色々あるのでここでは説明しません。

などがあります。

それぞれもちろんメリットデメリットがあります。例えばLabelEncodingは数値の大小が生まれてしまうので回帰モデルには向かないだとか、OneHotEncodingはカテゴリの数が多い場合には次元が高くなりすぎてしまうなどですが、一旦細かい話は抜きにしてエンコーディングをみていきましょう!

カテゴリデータは

・Sex

・Emberked

・Title

・AgeBin

・FareBin

があるので今回はこれらをOneHotEncodingしてみると、こんな感じで0, 1の数値に変換することができました!

統計による探索的分析の実行

数値で見てもよいのですが、グラフ化した方が見やすいのでグラフで見ていきましょう。知りたいのはSurvivedなのでこれと各特徴量との関係を見ていきます。

・Fare(運賃)

・Age(年齢)

・FamilySize (家族の数)

と生き残ったかどうかの関係性をまずは可視化しています。

死亡者の方が多いことを除けば、分布としては差異はあまり見られないように思いますね。

次に

・Embarked (どこから乗船したか)

・Pclass (チケットのランク、グレード)

・isAlone (タイタニック号に一人で乗ったかどうか)

と生存の割合を可視化しています。

ちょっと傾向が見られますね。チケットのグレードが良い方が生き残っている割合が高いとかありますね。

次に一気に各特徴量間の相関を見てみることにします。

赤いくなるほど相関が1です、青くなるほど相関が-1です。


Survivedと直接大きく関わる特徴量はなさそうですね。本来はこういう作業を通してまた新たに特徴量を考えたりしていきますが、チュートリアルなのでこの辺にしておきましょう。

データモデリング

さて、特徴量選択を行い、機械学習への適用を行う準備ができました。

とりあえずモデルの選定は行わず、色々なモデルで行ってみましょう。

学習データで交差検証を行ってみます。評価指標はaccuracyで行います。今回はハイパーパラメータはデフォルト値で行っています。

結果はこちら

MLAName:モデルの名前

MLA Parameters:ハイパーパラメータの設定

MLA Train Accuracy Mean: 学習データの正答率

MLA Test Accuracy Mean: 検証データでの正答率

…という感じです。

一位はLGBMClassifierという勾配ブースティング木のモデルという結果でした。

これをもう少し見やすいよう可視化してみましょう。

大きな精度差はそれほどなくどれも似通っていますね。

さて、検証によって82~3%の精度で生存率を予測できることがわかりました。Kaggleではテストデータに対して予測を行ったものを提出すれば、テストデータに対するスコアをサイト上で見ることができます。ちなみにですが、テストデータではこれよりも若干低いスコアになりました。

モデル性能を評価する

さて一度精度が出てからは改善、改良です。Freemanさんはビジネス的な話をされていましたが自分たちは今は考えなく良いとして、これから精度向上に向けて考えられるのは以下のような事になると思います。

・特徴量選択をもう一度考え直す

・ハイパーパラメータのチューニングを行う

・複数のアルゴリズムを組み合わせるアンサンブル学習を用いる

などで、手法は多岐にわたります。

どれも仮説を立てたり、あるいは全探索したり、経験に基づく感覚でやってみたりと様々になると思います。。精度が出たから終わりではなく、そこからどう高めていくか、ここが最も大事な部分かもしれません。



おわりに

以上、データ解析の流れを急ぎ足でさらってみました。

急いで書いたこともあり乱雑な文や、不正確な文がある事かと思いますが、後程読み返したら気づくと思うのでその際にでも修正します笑

Kaggleやデータ解析って面白そうと思ってくださればいいなと思います。そして一緒にやっていけたらいいなとも思います。

ありがとうございました。


明日以降もAdvent Calendarは続いていくのでよければ見ていってください。