Python ile AI - Genetik Algoritmalar

Bu bölümde AI'nın Genetik Algoritmaları ayrıntılı olarak tartışılmaktadır.

Genetik Algoritmalar nedir?

Genetik Algoritmalar (GA'lar), doğal seleksiyon ve genetik kavramlarına dayanan arama tabanlı algoritmalardır. GA'lar, Evrimsel Hesaplama olarak bilinen çok daha büyük bir hesaplama dalının bir alt kümesidir.

GA'lar, John Holland ve Michigan Üniversitesi'ndeki öğrencileri ve meslektaşları, özellikle de David E. Goldberg tarafından geliştirildi. O zamandan beri çeşitli optimizasyon problemlerinde yüksek derecede başarı ile denenmiştir.

GA'larda, verilen soruna bir olası çözüm havuzumuz var. Bu çözümler daha sonra rekombinasyona ve mutasyona uğrar (doğal genetikte olduğu gibi), yeni çocuklar üretir ve süreç çeşitli nesiller için tekrarlanır. Her bir bireye (veya aday çözüme) bir uygunluk değeri (hedef işlev değerine bağlı olarak) atanır ve uygun kişilere çiftleşme ve verim için daha yüksek bir şans verilir.fitterbireyler. Bu, Darwinist Teori ile uyumludur.Survival of the Fittest.

Böylece tutar evolving durdurma kriterine ulaşana kadar nesiller boyunca daha iyi bireyler veya çözümler.

Genetik Algoritmalar, doğaları gereği yeterince rasgeleleştirilmiştir, ancak tarihsel bilgileri de kullandıkları için rasgele yerel aramadan çok daha iyi performans gösterirler (rasgele çözümler denediğimiz, şimdiye kadarki en iyiyi takip ettiğimiz).

Optimizasyon Sorunları için GA Nasıl Kullanılır?

Optimizasyon, tasarımı, durumu, kaynağı ve sistemi olabildiğince etkili hale getirme eylemidir. Aşağıdaki blok diyagram optimizasyon sürecini göstermektedir -

Optimizasyon süreci için GA mekanizmasının aşamaları

Aşağıda, problemlerin optimizasyonu için kullanıldığında GA mekanizmasının bir dizi adımları verilmiştir.

  • Adım 1 - İlk popülasyonu rastgele oluşturun.

  • Adım 2 - En iyi uygunluk değerlerine sahip ilk çözümü seçin.

  • Adım 3 - Mutasyon ve çaprazlama operatörlerini kullanarak seçilen çözümleri yeniden birleştirin.

  • Adım 4 - Popülasyona bir yavru ekleyin.

  • Adım 5 - Şimdi, durdurma koşulu karşılanırsa, çözümü en iyi uygunluk değeriyle iade edin. Aksi takdirde 2. adıma gidin.

Gerekli Paketleri Kurmak

Python'da Genetik Algoritmalar kullanarak sorunu çözmek için, GA için güçlü bir paket kullanacağız. DEAP. Fikirlerin hızlı prototiplenmesi ve test edilmesi için yeni evrimsel hesaplama çerçevesinin bir kütüphanesidir. Bu paketi, komut isteminde aşağıdaki komutun yardımıyla kurabiliriz -

pip install deap

Eğer kullanıyorsanız anaconda ortam, daha sonra deap yüklemek için aşağıdaki komut kullanılabilir -

conda install -c conda-forge deap

Genetik Algoritmaları Kullanan Çözümleri Uygulama

Bu bölüm size Genetik Algoritmaları kullanan çözümlerin uygulanmasını açıklamaktadır.

Bit desenleri oluşturma

Aşağıdaki örnek, 15 tane içeren bir bit dizesinin nasıl oluşturulacağını gösterir. One Max sorun.

Gerekli paketleri gösterildiği gibi içe aktarın -

import random
from deap import base, creator, tools

Değerlendirme işlevini tanımlayın. Genetik bir algoritma oluşturmanın ilk adımıdır.

def eval_func(individual):
   target_sum = 15
   return len(individual) - abs(sum(individual) - target_sum),

Şimdi, doğru parametrelerle araç kutusunu oluşturun -

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

Araç kutusunu başlatın

toolbox = base.Toolbox()
toolbox.register("attr_bool", random.randint, 0, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual,
   toolbox.attr_bool, num_bits)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

Değerlendirme operatörünü kaydedin -

toolbox.register("evaluate", eval_func)

Şimdi, geçiş operatörünü kaydedin -

toolbox.register("mate", tools.cxTwoPoint)

Bir mutasyon operatörü kaydedin -

toolbox.register("mutate", tools.mutFlipBit, indpb = 0.05)

Yetiştirme için operatörü tanımlayın -

toolbox.register("select", tools.selTournament, tournsize = 3)
return toolbox
if __name__ == "__main__":
   num_bits = 45
   toolbox = create_toolbox(num_bits)
   random.seed(7)
   population = toolbox.population(n = 500)
   probab_crossing, probab_mutating = 0.5, 0.2
   num_generations = 10
   print('\nEvolution process starts')

Tüm popülasyonu değerlendirin -

fitnesses = list(map(toolbox.evaluate, population))
for ind, fit in zip(population, fitnesses):
   ind.fitness.values = fit
print('\nEvaluated', len(population), 'individuals')

Nesiller boyunca oluşturun ve yineleyin -

for g in range(num_generations):
   print("\n- Generation", g)

Yeni nesil bireyleri seçmek -

offspring = toolbox.select(population, len(population))

Şimdi, seçilen kişileri klonlayın -

offspring = list(map(toolbox.clone, offspring))

Yavrulara çaprazlama ve mutasyon uygulayın -

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

Çocuğun fitness değerini silin

del child1.fitness.values
del child2.fitness.values

Şimdi, mutasyonu uygulayın -

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

Uygunluğu geçersiz olan bireyleri değerlendirin -

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
print('Evaluated', len(invalid_ind), 'individuals')

Şimdi, nüfusu yeni nesil bireyle değiştirin -

population[:] = offspring

Mevcut nesiller için istatistikleri yazdırın -

fits = [ind.fitness.values[0] for ind in population]
length = len(population)
mean = sum(fits) / length
sum2 = sum(x*x for x in fits)
std = abs(sum2 / length - mean**2)**0.5
print('Min =', min(fits), ', Max =', max(fits))
print('Average =', round(mean, 2), ', Standard deviation =',
round(std, 2))
print("\n- Evolution ends")

Son çıktıyı yazdırın -

best_ind = tools.selBest(population, 1)[0]
   print('\nBest individual:\n', best_ind)
   print('\nNumber of ones:', sum(best_ind))
Following would be the output:
Evolution process starts
Evaluated 500 individuals
- Generation 0
Evaluated 295 individuals
Min = 32.0 , Max = 45.0
Average = 40.29 , Standard deviation = 2.61
- Generation 1
Evaluated 292 individuals
Min = 34.0 , Max = 45.0
Average = 42.35 , Standard deviation = 1.91
- Generation 2
Evaluated 277 individuals
Min = 37.0 , Max = 45.0
Average = 43.39 , Standard deviation = 1.46
… … … …
- Generation 9
Evaluated 299 individuals
Min = 40.0 , Max = 45.0
Average = 44.12 , Standard deviation = 1.11
- Evolution ends
Best individual:
[0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 
 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0,
 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1]
Number of ones: 15

Sembol Regresyon Problemi

Genetik programlamada bilinen en iyi problemlerden biridir. Tüm sembolik regresyon problemleri rastgele bir veri dağılımı kullanır ve en doğru verileri sembolik bir formülle uydurmaya çalışır. Genellikle, bir bireyin uygunluğunu ölçmek için RMSE (Ortalama Karekök Hata) gibi bir ölçü kullanılır. Bu klasik bir regresör problemidir ve burada denklemi kullanıyoruz5x3-6x2+8x=1. Yukarıdaki örnekte takip edilen tüm adımları izlemeliyiz, ancak asıl kısım ilkel kümeleri oluşturmak olacaktır çünkü bunlar bireyler için yapı taşlarıdır, böylece değerlendirme başlayabilir. Burada klasik ilkelleri kullanacağız.

Aşağıdaki Python kodu bunu ayrıntılı olarak açıklamaktadır -

import operator
import math
import random
import numpy as np
from deap import algorithms, base, creator, tools, gp
def division_operator(numerator, denominator):
   if denominator == 0:
      return 1
   return numerator / denominator
def eval_func(individual, points):
   func = toolbox.compile(expr=individual)
   return math.fsum(mse) / len(points),
def create_toolbox():
   pset = gp.PrimitiveSet("MAIN", 1)
   pset.addPrimitive(operator.add, 2)
   pset.addPrimitive(operator.sub, 2)
   pset.addPrimitive(operator.mul, 2)
   pset.addPrimitive(division_operator, 2)
   pset.addPrimitive(operator.neg, 1)
   pset.addPrimitive(math.cos, 1)
   pset.addPrimitive(math.sin, 1)
   pset.addEphemeralConstant("rand101", lambda: random.randint(-1,1))
   pset.renameArguments(ARG0 = 'x')
   creator.create("FitnessMin", base.Fitness, weights = (-1.0,))
   creator.create("Individual",gp.PrimitiveTree,fitness=creator.FitnessMin)
   toolbox = base.Toolbox()
   toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)
   toolbox.expr)
   toolbox.register("population",tools.initRepeat,list, toolbox.individual)
   toolbox.register("compile", gp.compile, pset = pset)
   toolbox.register("evaluate", eval_func, points = [x/10. for x in range(-10,10)])
   toolbox.register("select", tools.selTournament, tournsize = 3)
   toolbox.register("mate", gp.cxOnePoint)
   toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
   toolbox.register("mutate", gp.mutUniform, expr = toolbox.expr_mut, pset = pset)
   toolbox.decorate("mate", gp.staticLimit(key = operator.attrgetter("height"), max_value = 17))
   toolbox.decorate("mutate", gp.staticLimit(key = operator.attrgetter("height"), max_value = 17))
   return toolbox
if __name__ == "__main__":
   random.seed(7)
   toolbox = create_toolbox()
   population = toolbox.population(n = 450)
   hall_of_fame = tools.HallOfFame(1)
   stats_fit = tools.Statistics(lambda x: x.fitness.values)
   stats_size = tools.Statistics(len)
   mstats = tools.MultiStatistics(fitness=stats_fit, size = stats_size)
   mstats.register("avg", np.mean)
   mstats.register("std", np.std)
   mstats.register("min", np.min)
   mstats.register("max", np.max)
   probab_crossover = 0.4
   probab_mutate = 0.2
   number_gen = 10
   population, log = algorithms.eaSimple(population, toolbox,
      probab_crossover, probab_mutate, number_gen,
      stats = mstats, halloffame = hall_of_fame, verbose = True)

Bit desenleri oluştururken tüm temel adımların aynı olduğuna dikkat edin. Bu program bize çıktıyı 10 nesilden sonra min, maks, std (standart sapma) olarak verecektir.