Kaggle奮闘録(Titanic編1) -ロジスティック回帰による分類-

# 1. はじめに

今回がQiita初投稿です．これから積極的にKaggleに挑戦していくので，その中で身につけた知識等を備忘録として書いていきます．

普段は研究でディープラーニング等を使って時系列分類，予後予測等に従事しているので，ある程度の基礎はあるつもりですが，もし間違いがあったらすみません．間違いに気づかれた方，もしくはアドバイス等がある方はコメントいただけると大変嬉しいです．

さて，早速ですが，今回はKaggleの初心者向けCompetition "Titanic - Machine Learning from Disaster"に挑戦していきたいと思います．
とりあえずは正答率が8割を超えるまではこのCompetitionに挑戦し続けようと思います．
ではKaggleに初めてSubmitしたコードを掲載し，意識した点を軽く記述しておきます．ちなみにデータの概要などには今回触れません．


# 2. 方法
では早速ですが，提出したコードをバンバン貼っていきます．

### Titanic Tutorialに載っていたデータインストールのために必要なコード(コピペ)
[Titanic Tutorial](https://www.kaggle.com/code/alexisbcook/titanic-tutorial)

```python
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
```

## パッケージインストール
```python
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.linear_model import LogisticRegression
```

## データのインストール
```python
train = pd.read_csv("/kaggle/input/titanic/train.csv")
test = pd.read_csv("/kaggle/input/titanic/test.csv")
```

## 欠損値の補間
```python
# for train
print(train.isnull().sum())   # Visualize the number of missing values
# fill Age column base on the sex and pclass of row
train['Age']= train.groupby(['Sex','Pclass'])['Age'].apply(lambda row : row.fillna(row.median()))

# for test
print(test.isnull().sum())
test['Age']= test.groupby(['Sex','Pclass'])['Age'].apply(lambda row : row.fillna(row.median()))
test['Fare']= test.groupby(['Sex','Pclass'])['Fare'].apply(lambda row : row.fillna(row.median()))
```
タイタニックのデータでは主に年齢(Age)の欠損が多かったので、性別(Sex)、チケットクラス(Pclass)が同じ集団の中から中央値の算出を行い，それを代入することで補間しました．平均値では外れ値などにより値が引っ張られてしまうのが怖かったので，今回は中央値で補間しました．この辺の欠損値の扱いも自分はまだ不慣れなので，後々勉強していきたいと思います．
またテストデータのみ運賃(Fare)の欠損(1件のみ)があったので，同様の補間方法により対処しています．

## 特徴量の選択
```python
names = ['Pclass','Sex','Age','SibSp','Parch','Fare']
X_train = train[names]
X_test = test[names]
y_train = train['Survived']
X_train.head()
```
本当は赤池情報量基準(AIC)などを使ってしっかり変数選択を行うべきかもしれませんが，今回は特にそういったことはせず適当に選びました．Kaggleに慣れてきたらそういった点も今後しっかり吟味していこうと思います．

## カテゴリー変数の変換
```python
# Label encoding
sex_le = LabelEncoder()
X_train['Sex'] = sex_le.fit_transform(X_train['Sex'])
X_test['Sex'] = sex_le.fit_transform(X_test['Sex'])
X_train.head()
```
pandas.get_dummies()を使ってもできるそうです．

## 標準化
```python
# Normalization (Mean=0, Standard division=1)
standard = StandardScaler()

standard.fit(X_train)
X_train = standard.transform(X_train)
X_test = standard.transform(X_test)
```
基本的に機械学習は特徴量を標準化しないと予測能が悪くなることが多いです．
標準化は$x = (x - \mu) / \sigma$ ($\mu:x$の平均，$\sigma:x$の標準偏差)でも計算することができますが，sklearnのStandardScaler()を使う方が楽なことが個人的には多いです．

## モデルの学習と予測
```python
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
```
sklearnのLogisticRegression()にはデフォルトでもL2正則化，つまりRedge回帰による正則化が入っているので，ある程度多重共線性による予測能の低下を軽減することができます．
今はデフォルトのパラメータを使用していますが，こちらについても今後しっかり検討したいです．

## 予測結果をCSVファイルに変換
```python
output = pd.DataFrame({'PassengerId': test.PassengerId, 'Survived': y_pred})
output.to_csv('submission.csv', index=False)
print("Your submission was successfully saved!")
```

# 3. 結果
以上のモデルによる予測結果を提出したところ，正答率は75.837%でした．
これから色々工夫をしてみて，なんとか正答率80%越えを達成したいと思います．


# 4. おわりに
今回はタイタニックデータにおける生存者・死亡者の2値分類をテーマに，アンサンブル学習などは一切行わず，ロジスティック回帰単体での精度をみてみました．今回の工夫点は大きなものはないですが，強いていうなら説明変数の標準化と，Redge回帰によるモデルの正則化を行ったことです．
正答率80%越えを目指して引き続き頑張りたいと思います．