Pythonでの機械学習を支援するツール MALSS（応用）

<Font color="red">Python3に対応しました(2016.01.25)</font>
<Font color="red">MALSSの仕様変更に対応しました(2020.02.08)</font>
<Font color="red">特徴量選択について追記しました(2020.08.22)</font>

Pythonでの機械学習を支援する，MALSS（Machine Learning Support System）というツールを作りました（[PyPI](https://pypi.python.org/pypi/malss/)／[GitHub](https://github.com/canard0328/malss)）．
[導入編](http://qiita.com/canard0328/items/fe1ccd5721d59d76cc77)，[基本編](http://qiita.com/canard0328/items/5da95ff4f2e1611f87e1)と書いてきて，今回は応用編です．

# 準備
前回と同じデータを使います．
普通にfitメソッドを呼んでしまうとモデリングを行うため処理に時間がかかってしまいます．
そこで，algorithm_selection_onlyオプションをTrueにして，アルゴリズム選択のみを行うようにします．

```py:
from malss import MALSS
import pandas as pd
data = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Heart.csv',
                   index_col=0, na_values=[''])
y = data['AHD']
del data['AHD']
cls = MALSS('classification', random_state=0,
            lang='jp')
cls.fit(data, y, algorithm_selection_only=True)
```

# アルゴリズムの変更
慣れてくると，検討するアルゴリズムを変更したいことがあると思います．

MALSSでは[scikit-learnで利用可能なアルゴリズム](http://scikit-learn.org/stable/supervised_learning.html)を簡単に利用することができます．
## アルゴリズム一覧取得
初めに現在検討する予定のアルゴリズム一覧を取得します．

```py:
for name, param in cls.get_algorithms():
    print(name)
```

```console:
Support Vector Machine (RBF Kernel)
Random Forest
Support Vector Machine (Linear Kernel)
Logistic Regression
Decision Tree
k-Nearest Neighbors
```

## アルゴリズムの削除
Random Forestを消すことにします．
削除したいアルゴリズムのインデックスを指定します．無指定の場合最後のアルゴリズムが削除されます．

```py:
cls.remove_algorithm(1)
for name, param in cls.get_algorithms():
    print(name)
```

```console:
Support Vector Machine (RBF Kernel)
Support Vector Machine (Linear Kernel)
Logistic Regression
Decision Tree
k-Nearest Neighbors
```

## アルゴリズムの追加
Extremely Randomized Treesを追加してみます．
*add_algorithm* の引数は，一つ目がestimatorのインスタンス，三つめはアルゴリズムの名前（任意）です．
二つ目が少し分かりにくいのですが，グリッドサーチを行うパラメータとそのレンジです．
辞書（のリスト）の形で，Keyがパラメータ名，Valueがそのレンジになります．パラメータは[scikit-learnのドキュメント](http://scikit-learn.org/stable/supervised_learning.html)などを参照してください．
また，scikit-learnのアルゴリズムでなくても，*fit*，*predict*メソッドを持った独自のestimatorでも構いません．
※アルゴリズムのimportを忘れずに

```py:
from sklearn.ensemble import ExtraTreesClassifier
cls.add_algorithm(ExtraTreesClassifier(n_jobs=3, random_state=0),
                  [{'n_estimators': [10, 30, 50],
                    'max_depth': [3, 5, None],
                    'max_features': [0.3, 0.6, 'auto']}],
                  'Extremely Randomized Trees')
for name, param in cls.get_algorithms():
    print(name)
```

## 分析実行
あとは前回と同様です．

```py:
cls.fit(X, y, 'classification_result')
cls.make_sample_code('classification_sample_code.py')
```

# グリッドサーチパラメータの変更
レポートのグリッドサーチの結果をみて，評価スコアが最大のときのパラメータがレンジの端の値であった場合，レンジを広げる（スライドさせる）必要があります．
が，現在MALSSにはグリッドサーチのパラメータを変更するメソッドがありませんので，
上記アルゴリズムの変更と同じ方法でパラメータの変化幅を変更してください．


# 特徴量選択
目的変数の予測に利用する特徴量（説明変数）はすべてが予測に役立っているとは限りません．予測に寄与しない特徴量がたくさんあると，モデルが過学習（学習に使用したデータだけに過度に適合し，未知のデータを適切に予測できなくなってしまう状態）しやすいという弊害もあります．
このようなケースでは，不要な特徴量を削除する特徴量選択が有効な場合があります．MALSSは特徴量選択をサポートしています．

はじめに検証用のデータを作成します．

```py:
from malss import MALSS
from sklearn.datasets import make_friedman1
X, y = make_friedman1(n_samples=1000, n_features=20, noise=0.0, random_state=0)
```

[make_friedman1](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_friedman1.html)で有効な特徴量は最初の5個（インデックス0～4）なので，あとの15個（n_features=20なので）は予測に寄与しない特徴量です．
まずは普通に分析し，分析レポートを確認します．

```py:
model = MALSS(task='regression', lang='en')
model.fit(X, y, dname='default')
```

分析レポートを確認し，特徴量選択を実行すると判断したら以下のように実施します．

```py:
model.select_features()
```

```console:
  Drop 15
  Drop 6
  Drop 7
  Drop 9
  Drop 19
  Drop 17
  Drop 8
  Drop 14
  Drop 5
```

10, 11, 12, 13, 16, 18番目の特徴量が残ってしまいましたが，9個の特徴量を削除することができました．必要な0～4番目の特徴量は残っています．
最後に特徴量選択した結果を使って，もう一度モデルを学習します．

```py:
model.fit(X, y, dname='feature_selection')
```

# おわりに
導入，基本，応用と３回に渡って，拙作の機械学習支援ツールMALSSを紹介させていただきました．
まだまだ至らない点多いと思いますので，ご意見頂けると嬉しいです．