【Beginner】【AI】【機械学習】Light GBM: Titanic: Machine Learning from Disaster

本ブログは、超初心者でも機械学習を利用した予測モデルが構築できるようになる内容となってます
教材としては、Kaggle_GettingStartedのTitanic: Machine Learning from Disasterを利用し、その予測過程を解説します。

本ブログは下記の順番で展開します

1. データクレンジング(データ前処理)
2. Light GBM(予測モデリング手法)の適用

「誰でも」 (精度は置いておいて)Light GBMという先端的な予測モデリング手法を利用して、二値分類予測モデルが解けることを目的としているので、中級者が読むとしょうもないことも、途中で記載しております

また本ブログは 下記2点を前提として進めております

- kaggleを知っている
- jupyter(データ分析プラットフォーム)を利用している

kaggleを初めてやるという方はこちらのQiitaブログからkaggleの開始方法をご確認下さい

jupyterをダウンロードしていないという方は、こちらをご参照下さい
*windowsの人はanaconda入れれば面倒な開発環境設定がいりませんので、anacondaインストールを推奨しております

分析かじっていて色々用語は知ってるんだけど、一回も実装したことが無い。。という方には特におすすめです
それ以外の方でも「読んでやるよ」という方は下記にてお進みください

1.データクレンジング(データ前処理)

今回、Light GBMというモデリング手法を使用します。kaggleの上位ランカーがかなり利用しており、実装は簡単ですが非常に精度の高い機械学習ライブラリとして注目されている手法です

そのLight GBMに必要なデータを与えると、予測結果を返してくれるという単純な仕組みなのですが、
与えるデータにざっくり下記の3つの条件が有ります

1. 教師データと予測データのカテゴリ(列数と種類)が揃っていること(説明変数の設定)
2. 欠損値(データ上の空白)が無いこと(欠損値の補完)
3. 取り込まれるデータは全て「数値データ」であること(ダミー化)

数値データってintですか!?floatですか!?とかいろいろツッコミ来そうですが、最初はこれで十分です

なのでこれらの条件を満たすためにデータを綺麗にする、「データクレンジング」という処理を行います

ちょっと地味な作業になりますがお付き合いください

まず、教師データ(train)と予測データ(test)を読み込みます
厳密には予測データ(test)では無いと言われそうですが、最初はこちらの方が理解しやすいのでこのように記載します

import pandas as pd
test = pd.read_csv("test.csv" , encoding="CP932")
train = pd.read_csv("train.csv", encoding = "CP932")

*Tipsですが、windowsの人はencoding="CP932"をつけると日本語読み込む際に文字化けが消えます(今回は意味ないです)
*test.csvとtrain.csvはkaggleのCompetition内のTitanic:Machine Learning from Disaster(こちら)からダウンロードできます

次に教師データ(train)を教師データ説明変数(train_x)と教師データ目的変数(train_y)に分け読み込み、予測データ(test)はそのまま予測データ説明変数(test_x)として読み込みます
説明変数と目的変数って?という方もググったらすぐ分かりますが、
こちらが分かりやすいです。

train_x = train.drop("Survived",axis=1)
train_y = train["Survived"]
test_x = test 

躓きポイント

この後、「欠損値の補完」→「ダミー化」と進んでいくのですが、「ダミー化」の際に、train_xとtest_xのcolumns数(列数)が揃っておく必要が有ります今の状態でダミー化してしまうと、列数が500列程数がズレてしまいLight GBMに与えるデータとして使えないので、ここからさらに説明変数に使用するカテゴリを絞ります
ここは最初実装するときに、割と躓きやすいポイントだと思います

よくモデルを作成する際にその精度を向上させるために行う「チューニング」という作業が有りますが、
この説明変数の設定もチューニングの一つです

*ダミー化が分からない方はこちらをご参照下さい
「ダミー化」とは簡単に言うと、文字列データを数値化するよといったニュアンスです。詳細はリンクで

上記の躓きポイントを解消するために説明変数を絞り込みます
今回は"Name"(乗客の名前) "Ticket"(チケット番号) "Cabin"(部屋番号)は、"Survived"(生存結果1:生存,0:死亡)に寄与しないという仮説を立て、この3カテゴリを省いたものを説明変数とします

train_x = train_x.drop("Name",axis =1)
train_x = train_x.drop("Ticket",axis =1)
train_x = train_x.drop("Cabin",axis =1)
test_x = test_x.drop("Name",axis =1)
test_x = test_x.drop("Ticket",axis =1)
test_x = test_x.drop("Cabin",axis =1)

以上のコードで 1.説明変数の設定が完了致しました
次に、2.欠損値の補完 を行います

最初に、すぐに欠損値の補完を行うのでは無く、どのカテゴリにどの程度欠損値があるかを把握します
確認するコードは下記です。(最初に教師データ説明変数(train_x)で確認しております)

train_x.isnull().sum()


結果は下記です
PassengerId 0
Pclass 0
Sex 0
Age 177
SibSp 0
Parch 0
Fare 0
Embarked 2

Ageの欠損が目立ちますね
Embarked(出港した港)も欠損値が2つ見られます
同様に、予測データ説明変数(test_x)でも確認します

test_x.isnull().sum()

PassengerId 0
Pclass 0
Sex 0
Age 86
SibSp 0
Parch 0
Fare 1
Embarked 0

こちらも同様にAgeの欠損が目立ち、Fare(乗船料金)にも一つ欠損が見られます
以上より"Age""Fare""Embarked"に対して欠損値補完の方針を検討し、実行します

今回の欠損値補完方針は下記で行います

- Age = 全体の乗船者年齢の中央値(median)
- Fare = 全体の乗船料金の中央値(median)
- Embarked = "S"(Sの港を利用した人が最も多いので)

中央値じゃなくて、平均値じゃダメなんですか!とも言われそうですが 結論OKです
ここも チューニングポイントの一つなので、この値をどう設定するかも後の予測結果に影響してきます
ただ、この中では深く議論しません。欠損値を埋めるという目的をただ遂行します

ちなみにEmbarkedで"S"が一番多いのを判定したプログラムは下記です

train_x["Embarked"].value_counts()

これにより下記の通り出力が有ります
S 270
C 102
Q 46
上記結果をtest_xにも適用して、Sが最も多いと判定し、欠損値の補完要素の1つとして採用致しました
value_counts()は、選択した列に含まれる文字のユニーク数をカウントしてくれるコードなので割と頻出で良く使えます

話を戻して、決定した方針を元に、実際に欠損値を補完します
コードは下記です

train_x["Age"] = train_x["Age"].fillna(train_x["Age"].median())
train_x["Fare"] = train_x["Fare"].fillna(train_x["Fare"].median())
train_x["Embarked"] = train_x["Embarked"].fillna("S")
test_x["Age"] = test_x["Age"].fillna(test_x["Age"].median())
test_x["Fare"] = test_x["Fare"].fillna(test_x["Fare"].median())
test_x["Embarked"] = test_x["Embarked"].fillna("S")

fillna("補完値")でデータが空白(Nan)の値を指定した"補完値"で補完出来ます
ちなみにmedian()というのが中央値を算出するコードです

以上で 2.欠損値の補完が完了致しました
最後に、3.データをすべて数値化(ダミー化)を行います

ダミー化については再掲ですがこちらをご覧ください。

ここから先は

2,123字 / 1画像

¥ 100