日立の社内ハッカソン参加者とPyCaretで競ってみた（後編）

# はじめに

こんにちは。(株) 日立製作所の [Lumada Data Science Lab.](https://www.hitachi.co.jp/New/cnews/month/2020/03/0330d.html) の清水目拓馬です。

前編の著者の小幡と、今回、PyCaretでのモデリングに取り組みました。[日立のハッカソンデータを使ってPyCaretでモデリングしてみた（前編）](https://qiita.com/t-obata/items/1efaff233f7384233f7b)の記事では、日立社内で実施したハッカソンで使用したデータを基にPyCaretで予測モデルを作成しました。後編となる今回は、複数の予測モデルを組み合わせたアンサンブル学習でどのぐらい分析精度が上がるかを検証します。

# アンサンブル学習

##### ◆バギング

前編で検討したモデルの比較で最も精度の良かったExtra Trees Regressorを用いて、バギングを実施しました。バギングとは、全体の学習データからデータ・説明変数を一部抽出して弱学習器を複数作成し、それらの予測値の平均を最終的な結果とする手法です。つまり、このバギングによって最終的に構築される予測モデルに多様性を持たせることが出来ます。

バギングの結果、`RMSE 217.61`となり、前編の`RMSE 223.43`より精度が向上しました。Extra Trees Regressorは内部でバギング処理を⾏っており、二重にバギング処理を実施していることになりますので、元の予測モデルにチューニングの余地があったかもしれません。

```python
# Bagging
bagged_dt = ensemble_model(et, method='Bagging')

# テストデータで評価
pred_data = predict_model(bagged_dt, data=test_data)
# 評価指標はRMSE
print('RMSE', check_metric(pred_data['目的変数'], pred_data.Label, 'RMSE'))
```
```python
RMSE 217.6096
```
##### ◆ブースティング

ここでもExtra Trees Regressorを用いて、ブースティングを実施しました。ブースティングは、バギングと同様に弱学習器を用いますが、独立に作るのではなく、1つずつ順番に作成していき、直前の予測誤差を小さくするように（弱点を補うように）学習していきます。

ブースティングの結果、`RMSE 214.57`となり、前編より精度が向上しました。バギングを⾏うExtra Trees Regressorにブースティングを重ねて実施しても精度が向上したのは面白い結果だと思います。

```python
# Boosting
boosted_dt = ensemble_model(et, method='Boosting')

# テストデータで評価
pred_data = predict_model(boosted_dt, data=test_data)
# 評価指標はRMSE
print('RMSE', check_metric(pred_data['目的変数'], pred_data.Label, 'RMSE'))
```
```python
RMSE 214.5677
```
##### ◆ブレンディング

ブレンディングは、複数の予測モデルの平均値を最終的な予測値とします。前編で検討したモデルの比較で精度の良かった上位3つのモデル Extra Trees Regressor, Random Forest, Gradient Boosting Regressorを組み合わせて予測値を決定します。

ブレンディングの結果、`RMSE 215.91`となり、前編の結果よりも精度が向上しました。

```python
# 上位3つのモデルをブレンディング
blender = blend_models(estimator_list=[et, rf, gbr])

# テストデータで評価
pred_data = predict_model(blender, data=test_data)
# 評価指標はRMSE
print('RMSE', check_metric(pred_data['目的変数'], pred_data.Label, 'RMSE'))
```

```python
 RMSE 215.9084
```

##### アンサンブル学習をした結果、分析精度が向上しました！

今回、アンサンブル学習を実施した中で、最も精度が良かったのは**ブースティング**でした。

**Tips：**前編では「初心者」レベルだったのが、「中級者」レベルまでランクアップしました。
<div align="center">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698650/b1af6b36-3bce-023d-820b-c5eb5957c124.png" /></div>
# ハッカソン上位者のノウハウ

今回のPyCaretの結果では中級者レベルにとどまりましたが、ハッカソンの上位者は下記のような点を考慮して精度向上につなげたようです。

1. **データクレンジングの実施**
   - 連続変数、離散変数またはカテゴリ変数のどちらで扱うかを見極める
   - 異常値を確認、補間、または削除する
   - 情報量を削減して、過学習を抑制する
2. **新規変数の作成**
   - 交互作用変数を作成する（不快指数など）
   - タイムスタンプを変数として扱う
   - 時系列を意識した変数を作成する　　　　　

# 結論

PyCaretだけでも、そこそこのデータ分析ができることがわかりました。
そこにデータサイエンティストのノウハウを加えることで、精度の向上が期待できると思います。

# おわりに

最後に、今回PyCaretを使用して、使いやすかった点と難しかった点をまとめます。

#### ◆使いやすかった点
- **複数モデルの構築や精度検証ができ、工数を軽減できる**<br>
  少ないコード量で多くのモデルを比較でき、データ分析作業の工数を軽減できると考えられます。
- **分析結果を可視化しやすい**<br>
  今回の記事では紹介しませんでしたが、説明変数の重要度、ROC曲線、学習曲線、混同行列など、様々なプロットが可能です。

#### ◆難しかった点
- **使用可能なAPIが多くて何を使ってよいのかわからない**<br>
  様々な処理ができることはメリットですが、最初に使った感覚としては、使用可能なAPIの多さに戸惑いました。
- **予期せぬエラーのデバッグがしづらい**<br>
  PyCaretの内部がブラックボックスのため、自分で実装しない分、エラーが発生したときのデバッグがしづらい面があります。
- **学習前にデータの確認が必要**<br>
  数値変数の中に文字が含まれていた場合には数値変数がカテゴリ変数として扱われるため、何も考えずにデータを`setup`関数に与えると、説明変数が膨大に増えてしまいます。その結果、計算時間がとんでもないことに！
- **時系列分析は苦手？**<br>
  時系列モデル（状態空間モデルなど）は現時点では実装されていません。