カスタム適応度関数 DEAP

DEAP

DEAP(Distributed Evolutionary Algorithms in Python)は、遺伝的アルゴリズム(GA)進化戦略(ES)などの進化的計算手法を実装するための強力で柔軟なライブラリです。

以下に、DEAPの高度な使い方を紹介します。

カスタム適応度関数

DEAPではカスタム適応度関数を定義して、特定の問題に対する適応度を評価できます。

ここでは、シンプルな最適化問題を例に説明します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import random
from deap import base, creator, tools, algorithms

# 適応度と個体の定義
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

# 個体生成関数
def create_individual():
return [random.uniform(-10, 10) for _ in range(3)]

# 適応度関数
def evaluate(individual):
return sum(ind ** 2 for ind in individual),

# 登録
toolbox = base.Toolbox()
toolbox.register("individual", tools.initIterate, creator.Individual, create_individual)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("mate", tools.cxBlend, alpha=0.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", evaluate)

# メイン実行ループ
population = toolbox.population(n=300)
NGEN = 40
for gen in range(NGEN):
offspring = toolbox.select(population, len(population))
offspring = list(map(toolbox.clone, offspring))

for child1, child2 in zip(offspring[::2], offspring[1::2]):
if random.random() < 0.5:
toolbox.mate(child1, child2)
del child1.fitness.values
del child2.fitness.values

for mutant in offspring:
if random.random() < 0.2:
toolbox.mutate(mutant)
del mutant.fitness.values

invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
fitnesses = map(toolbox.evaluate, invalid_ind)
for ind, fit in zip(invalid_ind, fitnesses):
ind.fitness.values = fit

population[:] = offspring

best_ind = tools.selBest(population, 1)[0]
print(f"Best individual is {best_ind}, {best_ind.fitness.values}")

[実行結果]

Best individual is [17379.0603611039, 1705192.5401431422, 2.8390485621127146], (2907983630706.9165,)

ソースコード解説

このコードは、DEAPライブラリを使用して遺伝的アルゴリズムを実装しています。

以下に、詳しく説明します。

1. ライブラリのインポート

1
2
import random
from deap import base, creator, tools, algorithms

ここでは、Pythonの標準ライブラリであるrandomと、DEAPライブラリの主要なモジュール(base, creator, tools, algorithms)をインポートしています。
これにより、遺伝的アルゴリズムの構成要素を使用できるようになります。

2. 適応度と個体の定義

1
2
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

このセクションでは、DEAPcreatorモジュールを使用して、遺伝的アルゴリズムの基本的な構成要素である適応度と個体を定義します。

  • FitnessMax: 最大化問題の適応度クラスを定義します。
    weights=(1.0,) は、適応度を最大化することを示しています。
  • Individual: 遺伝的アルゴリズムで操作する個体を定義します。
    個体はリストで表され、その適応度はFitnessMaxです。

3. 個体生成関数

1
2
def create_individual():
return [random.uniform(-10, 10) for _ in range(3)]

この関数は、新しい個体を生成するための関数です。
ここでは、各個体は3つの遺伝子(ランダムな浮動小数点数)を持ちます。
各遺伝子の値は$-10$から$10$の範囲でランダムに生成されます。

4. 適応度関数

1
2
def evaluate(individual):
return sum(ind ** 2 for ind in individual),

適応度関数は、各個体の適応度を評価するための関数です。
この関数は、個体の各遺伝子の二乗和を計算し、その値を返します。
適応度の高い個体は、より良い解を表します。

5. 登録

1
2
3
4
5
6
7
toolbox = base.Toolbox()
toolbox.register("individual", tools.initIterate, creator.Individual, create_individual)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("mate", tools.cxBlend, alpha=0.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", evaluate)

ここでは、DEAPToolboxを使用して、遺伝的アルゴリズムのさまざまな操作を登録しています。

  • individual: 個体生成関数を登録します。
  • population: 個体の集団(ポピュレーション)生成関数を登録します。
  • mate: 交叉オペレーターを登録します。
    ここではブレンド交叉(cxBlend)を使用しています。
  • mutate: 突然変異オペレーターを登録します。
    ここではガウス分布に従う突然変異(mutGaussian)を使用しています。
  • select: 選択オペレーターを登録します。
    ここではトーナメント選択(selTournament)を使用しています。
  • evaluate: 適応度関数を登録します。

6. メイン実行ループ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
population = toolbox.population(n=300)
NGEN = 40
for gen in range(NGEN):
offspring = toolbox.select(population, len(population))
offspring = list(map(toolbox.clone, offspring))

for child1, child2 in zip(offspring[::2], offspring[1::2]):
if random.random() < 0.5:
toolbox.mate(child1, child2)
del child1.fitness.values
del child2.fitness.values

for mutant in offspring:
if random.random() < 0.2:
toolbox.mutate(mutant)
del mutant.fitness.values

invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
fitnesses = map(toolbox.evaluate, invalid_ind)
for ind, fit in zip(invalid_ind, fitnesses):
ind.fitness.values = fit

population[:] = offspring

このセクションでは、遺伝的アルゴリズムのメインループを実行しています。

  1. 初期集団の生成: toolbox.population(n=300) で300個体の初期集団を生成します。
  2. 世代ループ: 40世代(NGEN = 40)のループを実行します。
    • 選択: トーナメント選択を使用して、次世代の親を選択します。
    • 複製: 選択された親を複製して子供を作ります。
    • 交叉: 子供に対して交叉操作を行います。
      50%の確率で交叉します。
    • 突然変異: 子供に対して突然変異操作を行います。
      20%の確率で突然変異します。
    • 適応度の再評価: 交叉や突然変異で適応度が無効になった個体の適応度を再評価します。
    • 集団の更新: 新しい子供集団で現在の集団を置き換えます。

7. 最良個体の表示

1
2
best_ind = tools.selBest(population, 1)[0]
print(f"Best individual is {best_ind}, {best_ind.fitness.values}")

最後に、最良個体を選択し、その個体と適応度を表示します。

  • 最良個体の選択: tools.selBest を使用して、集団の中から最良の個体を選択します。
  • 結果の表示: 最良個体の遺伝子と適応度を表示します。

まとめ

このコードは、DEAPライブラリを使用して遺伝的アルゴリズムを実装する一連のステップを示しています。

具体的には、個体と適応度の定義、個体生成、適応度評価、遺伝的操作(交叉、突然変異、選択)、および最良個体の選択を含みます。

各ステップは、遺伝的アルゴリズムの効率的な実行を支援します。

結果解説

[実行結果]

Best individual is [17379.0603611039, 1705192.5401431422, 2.8390485621127146], (2907983630706.9165,)

この結果は、DEAPを使った遺伝的アルゴリズムの実行の最終結果です。

以下に各部分の詳細な解説を行います。

解説

  1. Best individual is [17379.0603611039, 1705192.5401431422, 2.8390485621127146]

    • Best individual: これは最適化の過程で見つかった最良の個体を示しています。
      個体はリストとして表示され、各要素は個体の遺伝子を表しています。
      ここでは、個体は3つの遺伝子 [17379.0603611039, 1705192.5401431422, 2.8390485621127146] を持っています。
    • 17379.0603611039, 1705192.5401431422, 2.8390485621127146: これらの値は、それぞれの遺伝子の値です。
      これらの遺伝子の組み合わせが、この特定の最適化問題において最良の解を提供したことを示しています。
  2. (2907983630706.9165,)

    • (2907983630706.9165,): これは最良の個体の適応度(fitness)を示しています。
      適応度は個体の「良さ」を表し、通常は評価関数によって計算されます。
      ここでは、適応度が 2907983630706.9165 であることを示しています。
      この値は、評価関数の定義によって大きく変わる可能性があります。

まとめ

この結果から、遺伝的アルゴリズムが非常に大きな値を持つ遺伝子を持つ個体を最適解として見つけたことがわかります。

適応度値評価関数に依存しており、この場合は遺伝子の値の二乗和として計算されています。

結果として表示される適応度は、その個体が他の個体と比べてどれだけ優れているかを示す指標です。

改善のためのヒント

  • 適応度関数の調整: もしこの適応度値が現実的でない場合や、解が望ましい範囲外にある場合は、適応度関数を見直すことを検討してください。
  • パラメータのスケーリング: 遺伝子値の範囲を制限したり、スケーリングを行うことで、最適化の精度を向上させることができます。
  • 他のオペレーターの利用: 異なる交叉や突然変異オペレーターを試すことで、進化の多様性を増やし、より良い解を見つける可能性があります。

DEAPは非常に柔軟なライブラリであり、様々なカスタマイズを行うことで多種多様な最適化問題に対応できます。