12
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Python】初めての データ分析・機械学習(Kaggle)

Last updated at Posted at 2020-03-10

#はじめに
就職間近(大学4年の春休み)になって、急遽データサイエンティストになりたいと思い、とりあえずKaggleに取り組み始めました。

今回取り組んだのは、Kaggleのチュートリアルである「Titanic」の問題です。

研究で統計解析の経験はあるが、機械学習は全くわからない状態からなので、めちゃくちゃ優秀な方のコードを参考にして勉強することにしました!

ちなみに、参考にしたのがこちら
✔︎Introduction to Ensembling/Stacking in Python
Notebookで「Most voted」と評されていたコードです。(2020.3.10時点)

あと、上記のコードを参考にしたこちらの記事も参考にしました笑
Pythonでアンサンブル(スタッキング)学習 & 機械学習チュートリアル in Kaggle

#Introduction
今回取り組むタイタニック号のコンペの内容は、年齢、性別、同室者数、部屋のクラス、生死などの乗客に関するデータが与えれます。

そのデータを元に、
データの前処理
→データの可視化
→スタッキングモデル構築
→テストデータ
→評価

といった流れで、最後にはテストデータから構築したモデルを使って乗客の生死の予測をします。この予測がどれくらいあっているかもスコアの基準になります。

かなりボリュームがあるので本記事では**「前処理」・「データの可視化」**に絞ります!

モデル構築以降は次回の記事に載せます!
続編記事はこちら↓↓↓
【Python】初めての データ分析・機械学習(Kaggle)〜Part2〜

では、早速データの前処理に取り掛かります!!

#データの前処理
###ライブラリのインポート
今回使用するライブラリをざっくり

  • 数学的、統計的処理: numpy, pundas
  • 正規表現操作(指定した形の言葉や数値の検索だったり置き換えだったり): re
  • いろんなモデルを持ってるよ~: sklearn
  • 勾配ブースティング決定木のアルゴリズム: XGboost
  • グラフや図: matplotlib, seaborn, plotly
  • 警告の表示/非表示: warnings
  • 5つの基礎モデル
  • これらの5つのモデルライブラリを同時に適応するのがKfold
import_library.py
import pandas as pd
import numpy as np
import re
import sklearn
import xgboost as xgb
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline

import plotly.offline as py
py.init_notebook_mode(connected=True)
import plotly.graph_objs as go
import plotly.tools as tls

import warnings
warnings.filterwarnings('ignore')

# 5つのモデル
from sklearn.ensemble import (RandomForestClassifier, AdaBoostClassifier, 
                              GradientBoostingClassifier, ExtraTreesClassifier)
from sklearn.svm import SVC

#複数の機械学習ライブラリを同時に適応する
from sklearn.cross_validation import KFold

###データの取得

import_data.py
train = pd.read_csv('../input/train.csv')
test = pd.read_csv('../input/test.csv')

#乗客のIDをPassengerIDに保持させる
PassengerId = test['PassengerId']

train.head(3)

出力
スクリーンショット 2020-03-10 16.13.20.png

データの説明

  • PassengerId:乗客のID
  • Survived:生死フラグ(生き残った場合:1, 亡くなった場合:0)
  • Pclass:チケットクラス
  • Name:乗客の名前
  • Sex:性別
  • Age:年齢
  • SibSp:同乗している兄弟/配偶者
  • Parch:同乗している両親/子供
  • fare:料金
  • cabin:客室番号
  • Embarked:乗船した港

###特徴量エンジニアリング
取得したデータを分析しやすいように加工していきます。
機械学習において、この前処理はかなり重要らしいので、長いけど頑張ります!!

基本的には、欠損値(値がない)や文字データを全て数値データに変換します。

FeatureEngineering.py
full_data = [train, test]

#乗客の名前の長さ
train['name_length'] = train['name'].apply(len)
test['name_length'] = test['name'].apply(len)

#客室番号データがあるなら1を、欠損値なら0を
train['Has_Cabin'] = train['Cabin'].apply(lambda x: 0 if type(x) == float else 1)
test['Has_Cabin'] = test['Cabin'].apply(lambda x: 0 if type(x) == float else 1)

#家族の大きさをタイタニックに同乗している"兄弟/配偶者の数"と"親/子供の数"から定義する
for dataset in full_data:
    dataset ['FamilySize'] = dataset['Sibsp'] + dataset['Parch'] +1

#家族がいないなら"IsAlone"が1
for dataset in full_data:
    dataset['IsAlone'] = 0
    dataset.loc[dataset['FamilySize'] == 1, 'IsAlone'] = 1

#出港地の欠損値を一番多い'S'としておく
for dataset in full_data:
    dataset['Embarked'] = dataset['Embarked'].fillna('S')

#料金の欠損値を中央値としておく
#料金を大きく4つのグループに分ける
for dataset in full_data:
    dataset['Fare'] = dataset['Fare'].fillna(train['Fare'].median())
train['CategoricalFare'] = pd.qcut(train['Fare'], 4)

#年齢を5つのグループに分ける
for dataset in full_data:
    age_avg = dataset['Age'].mean()
    age_std = dataset['Age'].std()
    age_null_count = dataset['Age'].isnull().sum()
    #欠損値に入れるランダム値のリスト
    #平均値から偏差分だけ大きいor小さい値を用いる
    age_null_random_list = np.random.randint(age_avg - age_std, age_avg + age_std, size = age_null_count)
    dataset['Age'][np.isnan(dataset['Age'])] = age_null_random_list
    #データをint型に変換
    dataset['Age'] = dataset['Age'].astype(int)

train['CategoricalAge'] = pd.qcut(train['Age'],5)

#名前を取り出す関数get_titleの定義
def get_title(name):
    title_search = re.search('([A-Za-z]+)\.',name)
    #名前があれば取り出して返す
    if title_search:
       return title_search.group(1)
    return ""

#関数get_titleを使う
for dataset in ftll_data:
    dataset['Title'] = dataset['Name'].apply(get_title)

    #名前の記入ミス部分の修正
    dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col','Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Rare')

    dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
    dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')

for dataset in full_data:
    # 女なら0、男なら1
    dataset['Sex'] = dataset['Sex'].map( {'female': 0, 'male': 1} ).astype(int)

    # 名前の5種類にラベル付
    title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
    dataset['Title'] = dataset['Title'].map(title_mapping)
    dataset['Title'] = dataset['Title'].fillna(0)

    # 出港地の3種類にラベル付
    dataset['Embarked'] = dataset['Embarked'].map( {'S': 0, 'C': 1, 'Q': 2} ).astype(int)

    # 料金を4つのグループに分ける
    dataset.loc[ dataset['Fare'] <= 7.91, 'Fare']                               = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare']   = 2
    dataset.loc[ dataset['Fare'] > 31, 'Fare']                                  = 3
    dataset['Fare'] = dataset['Fare'].astype(int)

    # 年齢を5つのグループに分ける
    dataset.loc[ dataset['Age'] <= 16, 'Age']                          = 0
    dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
    dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
    dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
    dataset.loc[ dataset['Age'] > 64, 'Age'] = 4 ;

# 必要ない特徴を削除
drop_elements = ['PassengerId', 'Name', 'Ticket', 'Cabin', 'SibSp']
train = train.drop(drop_elements, axis = 1)
train = train.drop(['CategoricalAge', 'CategoricalFare'], axis = 1)
test  = test.drop(drop_elements, axis = 1)

勉強になったコーディング

  • lambda関数の使い方
  • fillna()
  • pandasのqcut
  • map関数
  • if文を使わず、loc[]の[]内でTrueの場合のみ値を入力
  • axis = 1

#データの可視化
やっと前処理が終わりました!!
ちゃんと全てのデータが数値データになっているか確認してみましょう!

visualize.py
train.head(3)
スクリーンショット 2020-03-10 17.25.59.png

###ピアソン相関ヒートマップ(Peason Correlation Heatmap)
特徴量同士の相関をヒートマップにて確認します。

heatmap.py
colormap = plt.cm.RdBu
plt.figure(figsize = (14,12))
plt.title('Peason Correlation of Features', y = 1.05, size = 15)
sns.heatmap(train.astype(float).corr(), linewidths=0.1, vmax=1.0, square = True, cmap=colormap, linecolor='white', annot=True)
スクリーンショット 2020-03-10 17.32.26.png

このプロットから、そこまで特徴量が互いに強く相関していないことがわかります。

特徴量が互いに独立
→無駄な特徴がない
→学習モデルを構築する上で重要
(ParchとFamilySizeは比較的相関が強いですが、そのまま残しておきます。)

###ペアプロット(PairPlot)
ある特徴から別の特徴へのデータの分布

PairPlot.py
g = sns.pairplot(train[[u'Survived', u'Pclass', u'Sex', u'Age', u'Parch', u'Fare', u'Embarked',
       u'FamilySize', u'Title']], hue='Survived', palette = 'seismic',size=1.2,diag_kind = 'kde',diag_kws=dict(shade=True),plot_kws=dict(s=10) )
g.set(xticklabels=[])
スクリーンショット 2020-03-10 17.40.00.png

#まとめ
本記事では、Kaggleのチュートリアルの「Titanic」に取り組みました。
流れとしては、

  1. ライブラリのインポート
  2. データの取得
  3. データの前処理
    • 欠損値をなくす(平均値に近い値をランダムに挿入等)
    • データの等分
    • カテゴリーデータを数値に変換
  4. データの可視化
    • ピアソン相関ヒートマップ
    • ペアプロット

ここまででも結構大変でしたが、ここからがモデル構築の本番なので引き続き頑張ります!!

12
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?