皆様のおかげで設立1周年を迎えました。

お手軽最適化パッケージ「vcopt」仕様書

とりあえず実行してみましょう

pip install vcopt
from vcopt import vcopt

#二次関数(評価関数)
def niji_kansu(para):
    y = para**2
    return y

#パラメータ範囲
para_range = [-5, 5] #パラメータが1つだけのときは、[最小値, 最大値]の1次元配列でOK
print(para_range)

#GAで最適化
para, score = vcopt().rcGA(para_range,              #para_range
                           niji_kansu,              #score_func
                           0.00,                    #aim
                           show_pool_func='print')  #show_para_func=None, 'bar', 'print', 'plot'

#結果の表示
print(para)
print(score)

二次関数の最適化ができました。パラメータが0のとき二次関数=0にとなります。

import math
import numpy as np
from vcopt import vcopt

#Rastrigin関数(評価関数)
def rastrigin_score(para):
    y = 0
    for x in para:
        y += 10 + (x*x - 10 * math.cos(2*math.pi*x))
    return y

#パラメータ範囲
para_range = np.ones((15, 2)) * 5.12 #パラメータが複数のときは、[最小値, 最大値]を列挙した2次元配列
para_range[:, 0] *= -1
print(para_range)

#GAで最適化
para, score = vcopt().rcGA(para_range,              #para_range
                           rastrigin_score,         #score_func
                           0.00,                    #aim
                           show_pool_func='print')  #show_para_func=None, 'bar', 'print', 'plot'

#結果の表示
print(para)
print(score)

なんと、これで15次元のRastrigin関数の最適化ができました。15個すべてのパラメータが0のとき、ラストリジン関数=0となりました。

vcoptとは

無料のPythonパッケージで、遺伝的アルゴリズム(Genetic Algorithm, GA)による本格的な最適化がお手軽にできます。読み方は「ぶいしーおぷと」です。

設計理念

GAは「調整が難しい」と言われること多いですが、vcoptではすべてのハイパーパラメータが動的に決定されますので、思考停止で使うことができます。

  • さまざまな最適化問題に対応できる
  • ユーザーがハイパーパラメータを設定する必要がない

できること

<目的><コマンド>
順序(並び替え)の局所最適化vcopt().opt2()
順序(並び替え)の大域最適化(*1)vcopt().tspGA()
離散値の組合せ最適化(*1)vcopt().dcGA()
セットの組合せ最適化(*1) vcopt().setGA()
連続値の組合せ最適化(*1)vcopt().rcGA()

(*1) いずれも大域解を保証するものではありません

実行環境

Python3で使うことができます。

WinPython - Browse /WinPython_3.5/3.5.3.1 at SourceForge.net
Portable Scientific Python 2/3 32/64bit Distribution for Windows
Google Colaboratory

pip

最新バージョンは 1.5.4 です(2019年6月30日時点)

pip install vcopt

import

from vcopt import vcopt

順序の局所最適化|vcopt().opt2()

このコマンドでは順序の局所最適化ができます。2-opt法を独自に高速化したアルゴリズムを用いています。

使い方
#2-opt法で最適化
para, score = vcopt().opt2(para,
                           score_func,
                           aim,
                           show_para_func=None,
                           seed=None,
                           step_max=float('inf'))
para必須list, numpy.ndarray並び替えたい要素の1次元配列です。
要素は int, float, str のいずれでも良いですが、例えば [2, ‘a’] のように混在する場合には [‘2’, ‘a’] のようにすべて str として認識されます。配列は list でも numpy.ndarray でも良いですが、処理開始時に numpy.ndarray に変換されます。
<例1>
[0, 1, 2, 3, 4]
<例2>
[-10, -1, 0, 1, 10]
<例3>
[‘v’, ‘c’, ‘o’, ‘p’, ‘t’]
score_func必須関数評価関数です。para を受け取って評価値(単一の数値)を返す関数を設定してください。
詳細は共通の説明をご覧ください。
aim必須int, float目標評価値です。
<例1>
0.0
<例2>
999999
<例3>
-999999
show_para_func任意関数para を可視化する関数です。並び替え途中の para を受け取って可視化します。
詳細は参考記事をご覧ください。
<受け取る para の例1>
[3, 2, 0, 4, 1]
<受け取る para の例2>
[1, -10, 10, -1, 0]
<受け取る para の例3>
[‘o’, ”c, ‘v’, ‘t’, ‘p’]
seed任意int乱数シードを指定できます。
step_max任意int最大処理ステップ数を指定できます。


具体的な使用例は次の記事を参考にしてください。

順序の大域最適化|vcopt().tspGA()

このコマンドでは順序の大域最適化ができます。親のもつ「辺」を受け継ぐような交叉法を採用し、独自の高速化アルゴリズムを用いています。

ハイパーパラメータ一覧
個体数、親数、子数10n(*2), 2, 2
交叉法親のもつ辺を、2手先までを重み付けして確率的に採用する
突然変異率各辺ともおおむね1/n
選択法エリート選択
終了条件個体群の平均評価値に変化がなくなったら

(*2) nは次元数

使い方
#GAで最適化
para, score = vcopt().tspGA(para_range,
                            score_func,
                            aim,
                            show_pool_func=None,
                            seed=None,
                            pool_num=None,
                            max_gen=None)
para_range必須list, numpy.ndarray並び替えたい要素の1次元配列です。
要素は int, float, str のいずれでも良いですが、例えば [1, ‘a’] のように混在する場合には [‘1’, ‘a’] のようにすべて str として認識されます。配列は list でも numpy.ndarray でも良いですが、処理開始時には numpy.ndarray に変換されます。
<例1>
[0, 1, 2, 3, 4]
<例2>
[-10, -1, 0, 1, 10]
<例3>
[‘v’, ‘c’, ‘o’, ‘p’, ‘t’]
score_func必須関数評価関数です。para を受け取って評価値(単一の数値)を返す関数を設定してください。
詳細は共通の説明をご覧ください。
aim必須int, float目標評価値です。
<例1>
0.0
<例2>
999999
<例3>
-999999
show_pool_func任意関数pool を可視化する関数です。pool を受け取って可視化します。’bar’, ‘print’, ‘plot’から選べ、また独自に定義することもできます。詳細は共通の説明をご覧ください。
seed任意int乱数シードを指定できます。
pool_num任意int個体数を指定できます。必ず2以上の偶数としてください。
max_gen任意int最大世代数を指定できます。一定の世代数(計算時間)で終了したい場合に有効です。


具体的な使用例は次の記事を参考にしてください。

離散値の組合せ最適化|vcopt().dcGA()

このコマンドでは離散値の組合せ最適化ができます。二点交叉と一様交叉を組み合わせた交叉法を採用しています。

ハイパーパラメータ一覧
個体数、親数、子数10n(*2), 2, 4
交叉法二点交叉と一様交叉を組み合わせた方法
突然変異率各遺伝子ともおおむね1/n
選択法エリート選択
終了条件個体群の平均評価値に変化がなくなったら

(*2) nは次元数

使い方
#GAで最適化
para, score = vcopt().dcGA(para_range,
                           score_func,
                           aim,
                           show_pool_func=None,
                           seed=None,
                           pool_num=None,
                           max_gen=None)
para_range必須list, numpy.ndarray取りうる遺伝子の選択肢を列挙した2次元配列です。ただし遺伝子が1つしかない場合は1次元配列でも構いません。
要素は int, float, str のいずれでも良いですが、例えば [[1, ‘a’]] のように混在する場合には [[‘1’, ‘a’]] のようにすべて str として認識されます。配列は list でも numpy.ndarray でも良いですが、処理開始時には numpy.ndarray に変換されます。
<例0>
[0, 1, 2, 3, 4]
<例1>
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]
<例2>
[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[-10, -1, 0, 1, 10]]
<例3>
[[‘私は’, ‘僕は’, ‘俺は’, ‘我輩は’, ‘拙者は’],
[0, 1, 10, 100, 1000],
[‘歳の’, ‘匹の’, ‘戦錬磨の’]
[‘猫でございます’, ‘猫です’, ‘猫だ’, ‘猫だよ’, ‘猫どすえ’]]
score_func必須関数評価関数です。para を受け取って評価値(単一の数値)を返す関数を設定してください。
詳細は共通の説明をご覧ください。
aim必須int, float目標評価値です。
<例1>
0.0
<例2>
999999
<例3>
-999999
show_pool_func任意関数pool を可視化する関数です。pool を受け取って可視化します。’bar’, ‘print’, ‘plot’から選べ、また独自に定義することもできます。詳細は共通の説明をご覧ください。
seed任意int乱数シードを指定できます。
pool_num任意int個体数を指定できます。必ず2以上の偶数としてください。
max_gen任意int最大世代数を指定できます。一定の世代数(計算時間)で終了したい場合に有効です。


具体的な使用例は次の記事を参考にしてください。

セットの組合せ最適化|vcopt().setGA()

このコマンドでは100個の選択肢の中から重複せずに10個を選ぶ、といった組合せ最適化ができます。親の持つ共通集合を引き継ぐ交叉法を採用しています。

ハイパーパラメータ一覧
個体数、親数、子数10n(*2), 2, 4
交叉法親の持つ共通集合を引き継ぐ方法
突然変異率各遺伝子ともおおむね1/n
選択法エリート選択
終了条件個体群の平均評価値に変化がなくなったら

(*2) nは次元数(ここではset_num)

使い方
#GAで最適化
para, score = vcopt().setGA(para_range,
                            set_num,
                            score_func,
                            aim,
                            show_pool_func=None,
                            seed=None,
                            pool_num=None,
                            max_gen=None)
para_range必須list, numpy.ndarray取りうる遺伝子の選択肢を列挙した1次元配列です。
要素は int, float, str のいずれでも良いですが、例えば [1, ‘a’] のように混在する場合には [‘1’, ‘a’] のようにすべて str として認識されます。配列は list でも numpy.ndarray でも良いですが、処理開始時には numpy.ndarray に変換されます。
<例1>
[0, 1, 2, 3, 4]
<例2>
[-10, -1, 0, 1, 10]
<例3>
[‘v’, ‘c’, ‘o’, ‘p’, ‘t’]
set_num必須intpara_rangeから何個選ぶかを指定します。
<例>
3
score_func必須関数評価関数です。para を受け取って評価値(単一の数値)を返す関数を設定してください。paraはソートされた状態で渡されます。
詳細は共通の説明をご覧ください。
aim必須int, float目標評価値です。
<例1>
0.0
<例2>
999999
<例3>
-999999
show_pool_func任意関数pool を可視化する関数です。pool を受け取って可視化します。’bar’, ‘print’, ‘plot’から選べ、また独自に定義することもできます。詳細は共通の説明をご覧ください。
seed任意int乱数シードを指定できます。
pool_num任意int個体数を指定できます。必ず2以上の偶数としてください。
max_gen任意int最大世代数を指定できます。一定の世代数(計算時間)で終了したい場合に有効です。


具体的な使用例は次の記事を参考にしてください。

連続値の組合せ最適化|vcopt().rcGA()

このコマンドでは連続値の組合せ最適化ができます。交叉法には REX (Real-Coded Ensemble Crossover) を採用しています。

ハイパーパラメータ一覧
個体数、親数、子数10n(*2), 2, 4
交叉法REX (Real-Coded Ensemble Crossover)
突然変異率(REXに内包)
選択法エリート選択
終了条件個体群がもつ各遺伝子の分散が十分に小さくなったら

(*2) nは次元数

使い方
#GAで最適化
para, score = vcopt().rcGA(para_range,
                           score_func,
                           aim,
                           show_pool_func=None,
                           seed=None,
                           pool_num=None,
                           max_gen=None)
para_range必須list, numpy.ndarray各遺伝子が取りうる実数値の最小値と最大値を列挙した2次元配列です。ただし遺伝子が1つしかない場合は1次元配列でも構いません。
要素は int, float のいずれかです。配列は list でも numpy.ndarray でも良いですが、処理開始時には numpy.ndarray に変換されます。
<例0>
[-5, 5]
<例1>
[[-5.12, -5.12],
[-5.12, -5.12],
[-5.12, -5.12],
[-5.12, -5.12]]
<例2>
[[0, 1],
[0, 100],
[-10, 0],
[-100, 0]]
score_func必須関数評価関数です。para を受け取って評価値(単一の数値)を返す関数を設定してください。
詳細は共通の説明をご覧ください。
aim必須int, float目標評価値です。
<例1>
0.0
<例2>
999999
<例3>
-999999
show_pool_func任意関数pool を可視化する関数です。pool を受け取って可視化します。’bar’, ‘print’, ‘plot’から選べ、また独自に定義することもできます。詳細は共通の説明をご覧ください。
seed任意int乱数シードを指定できます。
pool_num任意int個体数を指定できます。必ずnの倍数(*2)としてください。
max_gen任意int最大世代数を指定できます。一定の世代数(計算時間)で終了したい場合に有効です。

(*2) nは次元数、すなわち len(para_range) です


具体的な使用例は次の記事を参考にしてください。

評価関数の書き方|score_func()

score_func() は評価値を計算する関数です。GA中に頻繁に呼び出されます。

次のルールに従って書きます。

#評価関数
def score_func(para):

    #スコアの計算
    score = ...
    
    return score

para は次のような1次元配列です(ndarray型)。

<例1>
[4, 2, 1, 5, 3]
<例2>
['t', 'p', 'v', 'o', 'c']

お手軽表示機能|show_pool_func=’bar’, ‘print’, ‘plot’

vcoptには、GAの途中経過を可視化するためのお手軽表示機能が3種類用意されています。

指定なし、もしくはshow_pool_func=Noneの場合

途中経過は一切表示されません。計算はもっとも高速です。

show_pool_func=’bar’

途中経過が進捗バーで表示されます。

左端は目標評価値、|はエリートスコア、<はmean_gapです。<が|に追いつくと終了が近いです。

show_pool_func=’print’

途中経過がprintされます。

show_pool_func=’plot’

途中経過がグラフで表示されます。pool_numが100より大きい場合、100体までのスコアが表示されます。計算は低速で、Noneと比較して3倍程度の時間がかかる場合があります。

可視化関数の書き方|show_pool_func()

お手軽表示機能の他に、可視化関数を独自に定義し、show_pool_func=your_func のように渡すことで、GA中の個体群の様態や、最適値の推移を自由に見ることができます。

次のルールに従って書きます。

#poolの可視化
def show_pool_func(pool, **info):
    
    #GA中の諸情報はinfoという辞書に格納されて渡されます
    #これらを受け取って使用することができます
    gen = info['gen'] #現在の世代
    best_index = info['best_index'] #エリート個体のインデックス
    best_score = info['best_score'] #エリート個体の評価値
    mean_score = info['mean_score'] #個体群の平均評価値
    mean_gap = info['mean_gap'] #目標値と評価値の差の絶対値平均
    time = info['time'] #経過時間(秒)
    
    #可視化
    print(...)

pool は次のような2次元配列です(ndarray型)。

[para,
 para,
 para,
 para]

pool[best_index] によりエリート個体の para が取得できます。

info[‘mean_score’] は目標値に対して片側から近づくタイプの問題で用いると便利です。一方で、info[‘mean_gap’] は目標値に対して両側から近づくタイプの問題で用いると便利です。

info[‘mean_score’] の使用例

個体群の評価値:[2.2, 2.4, 1.8, 1.6, 2.6, 2.0]
目標値:0.0

このような問題においては、mean_score=2.1 が参考になるでしょう。個体群の平均評価値が 2.1 であり、目標値まで 2.1 離れている事がわかります。

info[‘mean_gap’] の使用例

個体群の評価値:[9.2, 10.4, 10.8, 9.7, 9.3, 10.6]
目標値:10.0

このような問題においては、mean_score=10.0 よりも mean_gap=0.8 の方が参考になるでしょう。個体群が目標値まで平均 0.8 離れていることが分かります。

その他のTips

デフォルトでは個体数が10n(nは次元数(=パラメータ数))となっているため、例えば800パラメータの最適化では個体数が8000となり、非常に時間がかかる場合があります。初期個体の評価中に次のようなカウントが表示されます。

この進行があまりにも遅い場合は、pool_num=100といったオプションの使用を検討してください。ただし、個体数を少なくすると大域解の探索力が低下する可能性があります。

更新履歴

1.5.4バグ修正
1.5.3初期個体評価中のカウント機能を実装
1.5.2para_rangeがlist形式の入力に対応
rcGA(), dcGA()が1次元の入力に対応
1.5.1dcGA()の交叉法の変更
rcGA()の高速化
max_genオプションの実装
お手軽表示機能を実装(show_pool_func=’bar’, ‘print’, ‘plot’)
1.5.0setGA()の実装
dcGA()の交叉法の変更
1.4.9バグ修正
1.4.8int, float, strが混在した入力に対応
pool_numオプションの公式実装
mean_gapの実装
変数設計の見直し
1.4.7pool_numオプションの非公式実装
1.4.6バグ修正
1.4.5進化規模均一化によるGAの安定化
1.4.4バグ修正
1.4.3tspGA()の高速化
1.4.2dcGA(), rcGA()の実装
1.4.1opt2(), tspGA()の実装

お問い合わせ

Slack にてお気軽にお問い合わせください。

タイトルとURLをコピーしました