yProcessingClub

すみません、許してください

kaggleでタイタニックに挑戦

自分語り

最近ディープラーニングが熱いらしい.
大学の輪講とかでちょくちょく見聞きしてきたが,概要を知っている程度*1で中身はほとんど分からず.

弊社でついに「AIを使ってなんかしようぜ」って話が出てきたため,本格的に勉強することにした.


勉強方針だが,統計学とか線形代数みたいなガチガチの数学から入ると挫折すること間違いなしなので,とりあえずは動かしてみて簡単な実装を出来るようになろうと思う.
そのためにkaggleを利用することにした.
www.kaggle.com
kaggleとは機械学習のコンペプラットフォームで,用意されたデータセットを使って学習を行い,その性能で順位を競うというものである.
実際のデータセットが使えるので実践的で良さそう~.


とりあえずkaggle入門書を購入.

私が大学にいた頃(2015年)はようやく機械学習プロフェッショナルシリーズの1巻目が出たという感じで日本語で学べる環境が基本的に無かったが,今は無限に教材があるので良いことである.


最も入門的なタイタニックデータセットを使用し,コードは他の方が公開されているものをコピーした.
python-kaggle-start-book-ch02_01

pythonもほぼ触ったことが無いため,文法も覚えつつやっていく.

勉強内容

データのインポート
# パッケージをimportする
import numpy as np
import pandas as pd

# pandasを使ってcsvを読み込む
# data frame
train = pd.read_csv('../input/titanic/train.csv')
test = pd.read_csv('../input/titanic/test.csv')
gender_submission = pd.read_csv('../input/titanic/gender_submission.csv')

# trainデータ内の乗客の生存率を表示
print(train['Survived'].sum()/len(train['Survived'])*100)

# 先頭を表示
# 引数が空なら5行を出力
gender_submission.head()
#gender_submission.head(10)
gender_submission.tail()

# pandas.DataFrame, Seriesを連結する
data = pd.concat([train, test], sort=False)

# isnull : null 1, other 0
# sum count null
data.isnull().sum()
特徴量エンジニアリング
# このように書くと,値のみが返ってくるっぽい
#replaced_data_sex = data['Sex'].replace(['male', 'female'], [0, 1])
#print(replaced_data_sex.head())
#0    0
#1    1
#2    1
#3    1
#4    0

# 'Sex'列の'male'を0に置き換える
# デフォルトでは要素を置換した新たなDataFrameが返されるが,引数inplace=Trueとすると元のDataFrameが変更される.
data['Sex'].replace(['male', 'female'], [0, 1], inplace=True)


# Embarked : 乗り出した(どこの港で乗ったか)
# NAを'S'で埋める
data['Embarked'].fillna(('S'), inplace=True)
# 置き換え
data['Embarked'] = data['Embarked'].map({'S': 0, 'C': 1, 'Q': 2}).astype(int)

print(data['Fare'])
np.mean(data['Fare'])
data['Fare'].fillna(np.mean(data['Fare']), inplace=True)


age_avg = data['Age'].mean()
# age_avg = 29.881137667304014
age_std = data['Age'].std()
# age_std = 14.413493211271334
# 欠損値にσ = 1の範囲内でランダム値を入れる
data['Age'].fillna(np.random.randint(age_avg - age_std, age_avg + age_std), inplace=True)

# dataからこれらの列を取り除く
# 学習にはあまり関係の無いデータだと思われるため
delete_columns = ['Name', 'PassengerId', 'SibSp', 'Parch', 'Ticket', 'Cabin']
data.drop(delete_columns, axis=1, inplace=True)


# スライス操作
# 0 ~ len(train)-1のデータを取り出す
# x[0:N]と入れると,x[0]~x[N-1]の配列を取り出す
# 普段使っているmatlabと比べて面白いと思ったのがここ.
# matlabだとx(1:N)とするとx(1)~x(N)までのベクトルを返してくれたので,思想がちょっと違うっぽい.
train = data[:len(train)]
test = data[len(train):]


# trainデータから正解を抜き出す
# 機械学習でこの値になるように学習する
y_train = train['Survived']
# trainから'Survived'の列を取り除く
# axis=1にしているのは縦に取り除く(列方向)
X_train = train.drop('Survived', axis=1)
X_test = test.drop('Survived', axis=1)
機械学習アルゴリズム
# ロジスティック回帰
from sklearn.linear_model import LogisticRegression

# モデルのインスタンスを作成
# clfはclassifier(分類器)の略と思われる
# 引数はハイパーパラメータか
clf = LogisticRegression(penalty='l2', solver='sag', random_state=0)

# 学習を行う
clf.fit(X_train, y_train)

# テストデータで推論を行う
y_pred = clf.predict(X_test)
提出
sub = pd.read_csv('../input/titanic/gender_submission.csv')
sub['Survived'] = list(map(int, y_pred))
sub.to_csv('submission.csv', index=False)

Scoreは0.66267となった.
f:id:Yuri-Processing-Club:20210904201836p:plain

人様のコードをforkしてきただけだが,
とりあえず実行して推論した結果を提出まで行えることは確認できた.

感想

おおよその流れとして,

データの読み込み

データの前処理(missingや外れ値をいい感じにする)

特徴量作成(結果に無関係なデータ列を削除など)

データの前処理2(訓練データを入力層と出力層に分ける, x_train, y_train)

学習

推論

という感じかな.

機械学習に必要なライブラリが用意されているため,機械学習アルゴリズム自体の実装はしなくても良いというのが楽である.
試しに,モデルを別のものに変えてみる.

機械学習アルゴリズム(その2)
# ロジスティック回帰
# from sklearn.linear_model import LogisticRegression
# Linear SVCを用いる
from sklearn.svm import LinearSVC
# モデルのインスタンスを作成
#clf = LogisticRegression(penalty='l2', solver='sag', random_state=0)
clf = LinearSVC()

# 以降は変わらず
# 学習を行う
clf.fit(X_train, y_train)

# テストデータで推論を行う
y_pred = clf.predict(X_test)

f:id:Yuri-Processing-Club:20210904202856p:plain
Scoreは0.75837となり,ロジスティック回帰よりも良いスコアが得られた.





*1:機械学習は人間の脳を模倣していて凄い,程度の知識