Hyperoptを使った、関数の最適化
皆さんこんにちは
お元気ですか。私は元気です。
本日はhyperoptと呼ばれるライブラリを紹介したいと思います。
KaggleのForamで時々あがっていたので、気になっていました。
Hyperoptについて
What is Hyperopt?
hyperoptはTree-structured Parzen Estimator Approach(TPE)やRandomSearchを使って、最適化を行うライブラリです。
しかし、掲載論文を読む時間がないので、最適化の方法はともかく、
このライブラリは最小化するパラメータの推定を行ってくれます。
(他のもできるかもしれませんが、今回は調べていません。)
Hyperoptについて、Scipy2013で発表をしているようです。興味が有る人は以下のビデオもどうぞ。
Install
sudo pip install hyperopt
何に使えるのか
機械学習のパラメータチューニングに使っている人は多いようです。
時々、Kaggleで見ることがあります。
サンプルを書いてみた
簡単なサンプルを参考にしながら書いてみました。
以下のコードの意味ですが、簡単に言いますと、function内部の
関数を最小にするように動作しています。
#coding:utf-8 from hyperopt import fmin, tpe, hp, rand def function(args): x,y = args return x ** 2 + y ** 2 space = [hp.uniform('x',0,1), hp.normal('y', 0, 1)] best = fmin(function,space,algo=rand.suggest,max_evals=100) print best best = fmin(function,space,algo=tpe.suggest,max_evals=100) print best
第一引数に関数の最小化、パラメータ、TPEアルゴリズムで提案、反復回数となっています。
まだまだよくわからない箇所があるので、これを使って実際に
機械学習の最適化を行ってみたいと思います。
Scikit-learnで学ぶ機械学習のパラメータ最適化
機械学習でPythonといえば、scikit-learnが最も有名でしょう。
早速やってみた。
#coding:utf-8 from hyperopt import fmin, tpe, hp, rand import numpy as np from sklearn.metrics import accuracy_score from sklearn import svm parameter_space_svc = { 'C':hp.loguniform("C", np.log(1), np.log(100)), 'kernel':hp.choice('kernel',['rbf','poly']), 'gamma': hp.loguniform("gamma", np.log(0.001), np.log(0.1)), } from sklearn import datasets iris = datasets.load_digits() train_data = iris.data[0:1300] train_target = iris.target[0:1300] test_data = iris.data[1300:-1] test_target = iris.target[1300:-1] count = 0 def function(args): print args clf = svm.SVC(**args) clf.fit(train_data,train_target) prediction = clf.predict(test_data) global count count = count + 1 score = accuracy_score(test_target,prediction) print "%s回目の推測" % str(count),score return -accuracy_score(test_target,prediction) best = fmin(function,parameter_space_svc,algo=tpe.suggest,max_evals=100) print "best estimate parameters",best clf = svm.SVC(**best) print clf
ポイントは、2点
①辞書型にして渡るように辞書を構築し、中でhpを使い、パラメータの範囲や出方を決定していること。
②最大値への最適化はできないので、最小値への最適化に問題を変換(-をつける)
し、パラメータチューニングの問題を解いていること。
上記の式を応用すると、他の機械学習ライブラリに対しても
Hyperoptを適用することができます。
以下、ログです。パラメータを推定しながら、動いていることがわかります。
(長いログになったので省略しています。興味のある人はやってみてください。)
{'kernel': 'rbf', 'C': 7.193526575307785, 'gamma': 0.026663099972129244} 1回目の推測 0.197580645161 {'kernel': 'rbf', 'C': 95.55790927197563, 'gamma': 0.024863130263766336} 2回目の推測 0.219758064516 {'kernel': 'poly', 'C': 2.4628795490270203, 'gamma': 0.09203400263813753} 3回目の推測 0.959677419355 (略) {'kernel': 'rbf', 'C': 10.928134685112381, 'gamma': 0.009527462400869574} 97回目の推測 0.711693548387 {'kernel': 'rbf', 'C': 15.893094144901005, 'gamma': 0.0017010025860481686} 98回目の推測 0.967741935484 {'kernel': 'poly', 'C': 1.1348590065991755, 'gamma': 0.08212341793223293} 99回目の推測 0.959677419355 {'kernel': 'rbf', 'C': 15.822412405153285, 'gamma': 0.005563271969641763} 100回目の推測 0.887096774194 best estimate parameters {'kernel': 0, 'C': 1.0905097294517248, 'gamma': 0.0010874401961848724} SVC(C=1.09050972945, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.00108744019618, kernel=0, max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False)