SIGNATEで登録してから1カ月も経たずにIntermediateに昇格した

# まずSIGNATEで称号「Begginner」を獲得
機械学習について一通り書籍で学んだ後、機械学習のコンペに参加してみようと思い、SIGNATEに登録。その後まず定番の「タイタニックの生存予測」でチュートリアルの通りに投稿し称号<strong>「Begginner」</strong>を獲得。称号「Begginner」は投稿を1回でもすると、獲得できるようです。

# SIGNATEのBegginner限定コンペに参加
チュートリアルを終わったので、次は開催していたコンペ「【第57回_Beginner限定コンペ】採血データを使った心不全予測」というのに参加してみました。このコンペは<strong>参加資格が「Beginner, Registered」</strong>の人のみが参加できるみたいで、気軽にやってみようと思って参加してみました。参加したのが締め切り前でしたので数多く投稿できない状態での参加でした。

# データを読み込んでデータを確認
まずgooglecolabにデータを保存して以下のコードで学習用データと評価用データを読み込み。
```
import pandas as pd
train = pd.read_csv("train.csv") # 学習用データ
test = pd.read_csv("test.csv")   # 評価用データ
```
学習用データの中身を確認
```
train.head()
```
![学習用データ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4064049/7e8bd3db-f142-482a-bde4-9d30cdfa4667.png)

target列は1と0があり、この値を予測するようです。1は心不全になった人、0はなってない人のようです。

そして学習用データと評価用データのサイズを取得
```
train.shape
#(1000, 14)
```
```
test.shape
#(1000, 13)
```
行は両方とも1000行、列は学習用データは14列、評価用データは13列です。評価用データが1列少ないのは’target'列が含まれていないからです。

# 次に欠損値の確認
学習用データの欠損値の確認してみます。
```
train.isnull().sum()
```
![欠損値.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4064049/17e90b41-78d7-4646-af16-55249ece4521.png)
なんと欠損値がないようです。Begginner限定コンペは欠損値の処理をしなくてもいいようになっているのでしょうか？

ここから外れ値の処理や特徴量エンジニアリングをやっても良いのですが、期限がなく急いでいたので、とりあえずモデルを作って1つ投稿して後から精度を上げるためにやろうということで、モデルの作成を先にやりました。

# モデルの選択
使用するモデルを選択するために、学習用データを学習データとバリデーションデータに分割し正解率をモデルごとに比較してみることにします。
まずは学習用データを分割
```
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size = 0.2, random_state = 0)
```
まずは決定木モデルで正解率を出してみました。
```
from sklearn import tree #決定木モデル
treemodel = tree.DecisionTreeClassifier(max_depth = 5, random_state = 0, class_weight = 'balanced')
treemodel.fit(X_train, y_train)

print(treemodel.score(X_train, y_train))
print(treemodel.score(X_val, y_val))

#0.8
#0.715
```
なんと正解率がバリデーションデータですと0.715とめっちゃ低い。これでは勝負になりません。またロジスティック回帰も試してみましたが、あまりよくありません。

そこでランダムフォレストを試してみました。
```
from sklearn.ensemble import RandomForestClassifier

randommodel = RandomForestClassifier(n_estimators = 200, random_state=0)
randommodel.fit(X_train, y_train)

print(randommodel.score(X_train, y_train))
print(randommodel.score(X_val, y_val))

#1.0
#0.85
```
なんとバリデーションデータの正解率が<strong>0.85</strong>と劇的に上昇しました。とりあえず使用するモデルはランダムフォレストに決定！
# ハイパーパラメータのチューニング
次にハイパーパラメータのチューニングをします。ハイパーパラメータのチューニングするためにグリッドサーチをやってみます。グリッドサーチとは指定したハイパーパラメータの全ての組み合わせに対して学習を行い、もっとも高い精度を示したハイパーパラメータを出力する手法です。

そこで[侍テラコヤ](https://terakoya.sejuku.net)さんのコードをお借りしてグリッドサーチをやってみます。
侍テラコヤのコードはそのまま出すと規約に引っかかりそうなので非公開

結果がでるのに数分かかりましたが、<strong>max_depthが8、max_featuresが6、n_estimatorsが140</strong>が一番良いという結果になりました。

# 最後に学習用データをモデルに学習させて、予測値を出し投稿
最後に元の学習用データをモデルに学習させて、評価用データを使って予測値を出して投稿してみます。

```
forestModel = RandomForestClassifier(random_state = 0, n_estimators = 140, max_depth = 8, max_features = 6)
forestModel.fit(X, y)

test_features = test.loc[:,'age':'time']
predict = forestModel.predict(test_features)


submission = pd.DataFrame({'id': test['id'], 'target': predict})
submission.to_csv('submission_heart1.csv', index = False, header = None )
```

提出用データはヘッダー無しでcsv形式で提出するようなので注意しましょう。

# 何と一発でIntermediateに昇格した
結果は何と暫定評価で<strong>0.8500000</strong>で「今回運営の設定するTier変更の閾値はAccuracy=0.843」だったらしく一発で称号「Intermediate」に昇格しました。こんな簡単に「Intermediate」昇格してもいいのでしょうか？ランキングを見てみると半分以上の方が「Intermediate」に昇格したように見えますがどうでしょうか？

# Beginner限定コンペにはもう参加できない
ランクが「Intermediate」に昇格してしまったのでもうBeginner限定コンペには参加できなくなってしまいました。私としてはもう少しBeginner限定コンペに参加してみたかったのですがしょうがありません。これからは練習問題をやり、それからSOTAコンペに参加しようと思います。