Kaggle - Titanic: Machine Learning from Disaster
まずは使いそうなライブラリ群をインポート。
import numpy as np import scipy as sp import pandas as pd from pandas import DataFrame as DF
pandasのread_csv()モジュールを使い.csvデータを読み込む。
test_data = pd.read_csv("kaggle/titanic/test.csv") test_data = DF(test_data) train_data = pd.read_csv("kaggle/titanic/train.csv") train_data = DF(train_data) train_y = train_data['Survived']
使えなさそうなデータ列は削除します。
del test_data['Name'] del train_data['Name'] del train_data['PassengerId'] del test_data['PassengerId'] del train_data['Cabin'] del test_data['Cabin'] del train_data['Ticket'] del test_data['Ticket'] del train_data['Survived']
次に、性別を数字に変換します。
maleの場合は1,femaleの場合は0にします。
def toNumSex(data): for i in range(data.shape[0]): if data['Sex'][i] == "male": data['Sex'][i] = 1 elif data['Sex'][i] = "female": data['Sex'][i] = 0 else: print(i) toNumSex(test_data) toNumSex(test_data)
そして、Embarkedを数字にします。
C:1,Q:2、S:3とします。
def toNumEmbarked(data): for i in range(data.shape[0]): if data['Embarked'][i] == "C": data['Embarked'][i] = 1 elif data['Embarked'][i] == "Q": data['Embarked'][i] = 2 elif data['Embarked'][i] == "S": data['Embarked'][i] = 3 else: print(i) toNumEmbarked(test_data) toNumEmbarked(train_data)
ここで、出力に数字が...
>>> 61 >>> 829
どうやら、61行目と829行目はnanらしい。
再頻出な3で埋めておきます。
成形したデータをcsv形式で保存しておきます。
train_data.to_csv("kaggle/titanic/train_data.csv") test_data.to_csv("kaggle/titanic/test_data.csv") train_y.to_csv("kaggle/titanic/train_y.csv")
とりあえず、データの前処理完了です!!
さっそく、chainerでニューラルネットワークを組みましょう。
今回は3層で行きます。
ささっと作ったのでコードは汚いです笑
ニューラルネットワーク
import scipy as sp import pandas as pd import argparse import numpy as np import chainer from chainer import cuda, Function, gradient_check, Variable, optimizers, serializers, utils from chainer import Link, Chain, ChainList, FunctionSet import chainer.functions as F import chainer.links as L import matplotlib.pyplot as plt from pandas import DataFrame as DF from sklearn.cross_validation import train_test_split from sklearn.preprocessing import StandardScaler # GPU設定 parser = argparse.ArgumentParser(description='Chainer example: CIFAR-10') parser.add_argument('--gpu', '-gpu', default=-1, type=int, help='GPU ID (negative value indicates CPU)') # GPUが使えるか確認 args = parser.parse_args() if args.gpu >= 0: cuda.check_cuda_available() xp = cuda.cupy if args.gpu >= 0 else np # データの読み込みと整理 X = pd.read_csv("kaggle/titanic/train_data_1.csv") y = pd.read_csv("kaggle/titanic/train_y.csv", header=None) predict = pd.read_csv("kaggle/titanic/test_data.csv") X = np.array(X) y = np.array(y) predict = np.array(predict) X = X.astype(np.float32) y = y.astype(np.int32) train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=702/891, random_state=0) predict = predict.astype(np.float32) model = chainer.FunctionSet(l1 = L.Linear(6, 256), l2 = L.Linear(256,256), l3 = L.Linear(256, 2)) # GPU使用のときはGPUにモデルを転送 if args.gpu >= 0: cuda.get_device(args.gpu).use() model.to_gpu() # 順伝播 def forward(X_data, y_data): x, t = chainer.Variable(X_data), chainer.Variable(y_data) h = F.tanh(model.l1(x)) h = F.tanh(model.l2(h)) y = F.tanh(model.l3(h)) return F.softmax_cross_entropy(y, t), F.accuracy(y, t) # Setup optimizer optimizer = optimizers.Adam() optimizer.setup(model) # parameter n_epoch = 500 N = train_X.shape[0] N_test = test_X.shape[0] batchsize = 27 l = [] a = [] # Learning loop for epoch in range(1, n_epoch + 1): print('epoch', epoch) # training perm = np.random.permutation(N) sum_accuracy = 0 sum_loss = 0 for i in range(0, N, batchsize): X_batch = xp.asarray(train_X[perm[i:i + batchsize]]) y_batch = xp.asarray(train_y[perm[i:i + batchsize]]) y_batch = y_batch.reshape(y_batch.shape[0], ) # 勾配を初期化 optimizer.zero_grads() # 順伝播させて誤差と精度を計算 loss, acc = forward(X_batch, y_batch) # バックプロパゲーション loss.backward() # 最適化ルーティーンを実行 optimizer.update() sum_loss += float(loss.data) * batchsize sum_accuracy += float(acc.data) * batchsize print('train mean loss={}, accuracy={}'.format(sum_loss / N, sum_accuracy / N)) l.append(sum_loss/N) a.append(sum_accuracy/N) # evaluation sum_accuracy = 0 sum_loss = 0 for i in range(0, N_test, batchsize): X_batch = xp.asarray(test_X[i:i + batchsize]) y_batch = xp.asarray(test_y[i:i + batchsize]) y_batch = y_batch.reshape(y_batch.shape[0], ) # 順伝播させて誤差と精度を計算 loss, acc = forward(X_batch, y_batch) sum_loss += float(loss.data) * batchsize sum_accuracy += float(acc.data) * batchsize print('test mean loss={}, accuracy={}'.format(sum_loss / N_test, sum_accuracy / N_test))
結果
最初は3層で試しましたが、いろいろな試行錯誤をした結果スコアは...
0.78469
もうこれ以上上がる気がしない...
ニューラルネットワークで予想するにはデータ数が少なすぎるのだろう。
うん。
そう信じたい。