はじめに
基本的な機械学習の手順:①分類モデルでは、基本的な分類モデルの作成手順を整理しています。
今回は、その中で分類器の学習にフォーカスして、分類器の選択・アンサンブル学習の実現をしていきたいと思います。
これまでの手順
分析環境
Google BigQuery
Google Colaboratory
対象とするデータ
①分類モデルと同様に、下記の様なテーブル構造で購買データが格納されています。
id | result | product1 | product2 | product3 | product4 | product5 |
---|---|---|---|---|---|---|
001 | 1 | 2500 | 1200 | 1890 | 530 | null |
002 | 0 | 750 | 3300 | null | 1250 | 2000 |
0.対象とする分類器
当初は、分類器の性能比較等を行っていこうとしたのですが、これが絶対と決めるのは中々難しい。
それぞれに特徴があったり、その特徴を活かしていくことが大事だろうと考えて、ひとまず次の4つの分類器を学習させています。
- RandomForestClassifier : ランダムフォレスト(軽くて・速くて・ある程度精度がでる)
- LogisticRegression : ロジスティク回帰(ゼロ・イチの分類なのでこれは入れておく)
- KNeighborsClassifier : k近傍法(単純なモデルで分かりやすい)
- LGBMClassifier : LightGBM(最近の流行り。精度高め)
1.各分類器の学習
上記で指定した分類器を準備します。名称・分類器・パラメータの順番でリストを作っています。
Weightは、後で使いますが、アンサンブル学習の重みです。
# 分類器
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from lightgbm import LGBMClassifier
model_names=["RandomForestClassifier", "LogisticRegression", "KNeighborsClassifier", "LGBMClassifier"]
estimators=[RandomForestClassifier(), LogisticRegression(), KNeighborsClassifier(), LGBMClassifier()]
parameters=[
{
'n_estimators': [5, 10, 50, 100, 300],
'max_depth': [5, 10, 20],
},
{
'C': list(np.logspace(0, 4, 10))
},
{
'weights': ['uniform','distance'],
'n_neighbors': [3,5,10,20,30,50],
},
{
'objective': ['binary'],
'learning_rate': [0.01, 0.03, 0.05],
'n_estimators': [100, 150, 200],
'max_depth':[4, 6, 8]
}
]
weights=[1,1,1,1]
上記で定義した、個々のモデルを実行して学習していきます。
ここで、1個ずつシリアルに実施すると延々と時間がかかるので、「scikit-learnのParallelで並列処理」を参考に、パラレルで実行しています。
from sklearn.model_selection import GridSearchCV
from sklearn.externals.joblib import Parallel, delayed
models = []
def tuneParams(n):
estimator = estimators[n]
param = parameters[n]
clf = GridSearchCV(
estimator,
param_grid=param,
cv=5
)
clf = clf.fit(train_features, train_target)
model = clf.best_estimator_
return model
model = Parallel(n_jobs=-1)( delayed(tuneParams)(n) for n in range(len(estimators)) )
models.append(model)
これで、modelsのlistの中に、各分類器の最適なパラメータが入っています。
2.アンサンブル学習
そのパラメータを用いて、複数の分類器を合わせて学習する、アンサンブル学習を「sckit-learnのアンサンブル学習「VotingClassifier」に触ってみる」を参考に実施します。
先ほど#1で作成したmodelsをループしながら、VotingClassifierに投入していく感じです。
アンサンブル学習と、個々の分類器での学習を両方行っていきます。
from collections import defaultdict
from sklearn.ensemble import VotingClassifier
import sklearn.metrics as metrics
def modelingEnsembleLearning(train_features, test_features, train_target, test_target, models):
mss = defaultdict(list)
voting = VotingClassifier(list(zip([n for n in model_names],[m for m in models[0]])), voting='soft', weights=list([w for w in weights]))
voting.fit(train_features,train_target)
# アンサンブルで推計
pred_target = voting.predict(test_features)
ms = metrics.confusion_matrix(test_target.astype(int), pred_target.astype(int))
mss['voting'].append(ms)
# 個々の分類器でも推計
for name, estimator in voting.named_estimators_.items():
pred_target = estimator.predict(test_features)
ms = metrics.confusion_matrix(test_target.astype(int), pred_target.astype(int))
mss[name].append(ms)
return voting, mss
voting, mss = modelingEnsembleLearning(train_features, test_features, train_target, test_target, models)
3.モデルの評価
そして、最後にモデルの評価です。これは、元からプログラムは特に変わっていません。
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
accuracy=accuracy_score(test_target, voting.predict(test_features))
precision=precision_score(test_target.astype(int), voting.predict(test_features).astype(int))
recall=recall_score(test_target.astype(int), voting.predict(test_features).astype(int))
print("Voting")
print("Accuracy : ", accuracy*100, "%")
print("Precision : ", precision*100, "%")
print("Recall : ", recall*100, "%")
アンサンブル学習をすると、単純にAccuracyではLGBMClassifierの方が上、RecallではRandomForestClassifierの方が上。だけど、全体としてバランスがいいのはアンサンブル学習の結果だったということになったりします。
そうなった場合に、アンサンブル学習をモデルとして採用することにしています。
おわりに
基本的な機械学習の手順:①分類モデルから始めて、分類モデルについて私の理解の範囲の中で、手順全体+個別の深堀りについて進めてきました。
ひとまず、分類モデルについてはこれで一段落として、次なるステップに進みたいと思います。