進化的計算フレームワークDEAP (2) Creating Types

# 最初に
[前回](https://qiita.com/emi-cd/items/44104a8fab60799cf524)はOverviewを見ていったので、さらに詳しいチュートリアルについて見ていきたいと思います。元のドキュメントは[こちら](http://deap.readthedocs.io/en/master/tutorials/basic/part1.html)。
# Creating Types
このチュートリアルでは*creator*を使用した型の作り方、*toolbox*を使用した初期化の仕方について見ていきます。

## Fitness
*Fitness*というクラスは機能する為に*weights*という属性を必要とする抽象クラスです。適応度を最小化する際は負の重みを、最大化する際には正の重みをつけていきます。下の例では、一つの目的関数において、*FitnessMin*と名付けられた適応度を最小化していくようにしています。

```Python
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
```
関数create()は少なくとも2つの引数を必要とします。新しく作成するクラスの名前とその基となるクラスです。後続の引数は、そのクラスの引数になります。*Fitness*のドキュメントで述べられているように、単一目的も多目的の物も同じように扱えるように*weights*はタプルでないといけません。*FitnessMulti*も同じように作れます。

``` Python
creator.create("FitnessMulti", base.Fitness, weights=(-1.0, 1.0))
```
このコードは一つ目の目的関数の値を最小化する事を、二つ目の目的関数は最大化していく事を表しています。また、それぞれの目的関数自体の重みを変えることにも使用できます。これは、*weights*は数字はどのような実数でもよく、符号が最大化か最小化を判断するものだということを表しています。*weights*が役に立つ例としてはNSGA-IIのcrowding distanceソートなどがあります。

## Individual
進化的アルゴリズム（GA、GP、ES、PSO、DE、...）の異なるフレーバーを考えるだけで、極めて多種多様な個体が可能であり、全ての型を開発者が利用できるようにすることはできません。ここでは[creator](http://deap.readthedocs.io/en/master/api/creator.html#module-deap.creator)を使用して個体を作成し、[Toolbox](http://deap.readthedocs.io/en/master/api/base.html#deap.base.Toolbox)で初期化していく方法について見ていきます。
 > **注意!!**
 > もし、[numpy.ndarray](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray)を継承したい場合は、必ず[Inheriting from Numpy](http://deap.readthedocs.io/en/master/tutorials/advanced/numpy.html)のチュートリアルと[One Max Problem: Using Numpy](http://deap.readthedocs.io/en/master/examples/ga_onemax_numpy.html)の例を見るべき。

## List of Floats
最初に作られた個体はシンプルなFloatのリストになります。このような個体を生み出す為に、*creator*を使用して、fitness属性を持ちList型を継承した*Individual*クラスを作成する必要があります。

```Python
import random

from deap import base
from deap import creator
from deap import tools

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

IND_SIZE=10

toolbox = base.Toolbox()
toolbox.register("attr_float", random.random)
toolbox.register("individual", tools.initRepeat, creator.Individual,
                 toolbox.attr_float, n=IND_SIZE)
```
新しく紹介する[register()](http://deap.readthedocs.io/en/master/api/base.html#deap.base.Toolbox.register)メソッドには少なくとも2つの引数、具体的にエイリアスとこのエイリアスに割り当てられる関数が必要です。この2つに続く引数はその関数が呼ばれた時に引き渡されるものになります([functools.partial()](https://docs.python.org/3/library/functools.html#functools.partial)みたいな感じ)。したがって、上記のコードは*toolbox*に*attr_float*と*individual*の二つのエイリアスを作成しています。最初のものは[random.random()](https://docs.python.org/3/library/random.html#random.random)にリダイレクトされます。二つ目のものは[initRepeat()](initRepeat())へのショートカットになります。つまり、*container*引数に*creator.Individual*クラス、その*func*として*toolbox.attr_float()*、さらにその繰り返しの回数として*IND_SIZE*をそれぞれ固定しています。  
今、*toolbox.individual()*を呼ぶと、固定された引数と共に[initRepeat()](http://deap.readthedocs.io/en/master/api/tools.html#deap.tools.initRepeat)が呼ばれ、*IND_SIZE*の単一目的の*fitness*属性を最大化するFloatの値で構成される完全な*creator.Individual*を返します。  
下の例のように[array.array](https://docs.python.org/3/library/array.html#array.array)や[numpy.ndarray](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray)を継承することも可能です。

```python
creator.create("Individual", array.array, typecode="d", fitness=creator.FitnessMax)
creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)
```
arraysを継承する場合は初期化にあたって、元のクラスのように*typecode*を指定してあげる必要があります。

## Permutation  
Permutation表現の個体は、一般的なリスト個体とほぼ同じです。事実、どちらともList型を継承しています。唯一の違いはリストを連続したFloatで埋める代わりに、ランダムな順序を生成し、それを個体にしてあげる必要があります。

```python
import random

from deap import base
from deap import creator
from deap import tools

creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin)

IND_SIZE=10

toolbox = base.Toolbox()
toolbox.register("indices", random.sample, range(IND_SIZE), IND_SIZE)
toolbox.register("individual", tools.initIterate, creator.Individual,
                 toolbox.indices)
```
最初に登録した関数*indices*は[random.sample()](https://docs.python.org/3/library/random.html#random.sample)を与えられた範囲から抽出された*IND_SIZE*の数で固定された引数とともにリダイレクトされます。二つ目に登録された*individual*は引数*container*に*creator.Individual*クラスが、*generator*に*toolbox.indices()*へのエイリアスがセットされた[initIterate()](http://deap.readthedocs.io/en/master/api/tools.html#deap.tools.initIterate)へのリダイレクトが登録されます。  
*toolbox.individual()*を呼び出すと[initIterate()](initIterate())が固定された引数と共に呼び出され、単一目的の*fitness*属性が最小化されるような順列で構成された完全な*creator.Individual*が返されます。

# 最後に
元のドキュメントではまだ続いているのですが、今の所絶対必要ではないかなという気がしたので、このチュートリアルはここまでにして、とりあえず次のチュートリアルを見ていきたいと思います。必要そうだったら足していきます。  

それにしても、まだきちんと全ての日本語の用語を把握している訳ではないのでもっと勉強しないとなぁ、なんて思いました。直訳ごめんなさい。


---
[進化的計算フレームワークDEAP (1) Overview](https://qiita.com/emi-cd/items/44104a8fab60799cf524)
[進化的計算フレームワークDEAP (3) Operators and Algorithms](https://qiita.com/emi-cd/items/bd7d68ea6f9d9aace9e0)
[進化的計算フレームワークDEAP (4) One Max Problem](https://qiita.com/emi-cd/items/72ddc44484752b56156a)