AI與Python人工智能遺傳算法
本章詳細(xì)討論了人工智能的遺傳算法。
什么是遺傳算法?
遺傳算法(GA)是基于自然選擇和遺傳概念的基于搜索的算法。GA是更大的計算分支的子集,稱為進(jìn)化計算。
GA由John Holland及其密歇根大學(xué)的學(xué)生和同事開發(fā),最著名的是David E. Goldberg。從那以后,已經(jīng)嘗試了各種優(yōu)化問題并取得了很大的成功。
在GA中,我們有一組可能的解決方案來解決給定的問題。然后這些溶液經(jīng)歷重組和突變(如在天然遺傳學(xué)中),產(chǎn)生新的兒童,并且該過程重復(fù)多代。為每個個體(或候選解決方案)分配適合度值(基于其目標(biāo)函數(shù)值),并且使得更健康的個體具有更高的交配和產(chǎn)生更健康的個體的機(jī)會。這符合達(dá)爾文適者生存理論。
因此,它不斷發(fā)展更好的個人或解決方案,直到它達(dá)到停止標(biāo)準(zhǔn)。
遺傳算法在本質(zhì)上具有足夠的隨機(jī)性,但它們比隨機(jī)局部搜索(我們只是嘗試隨機(jī)解決方案,跟蹤迄今為止的最佳解決方案)表現(xiàn)得更好,因?yàn)樗鼈円怖昧藲v史信息。
如何使用GA進(jìn)行優(yōu)化問題?
優(yōu)化是使設(shè)計,情境,資源和系統(tǒng)盡可能有效的行動。以下框圖顯示了優(yōu)化過程 -
GA機(jī)制優(yōu)化過程的階段
以下是用于優(yōu)化問題的GA機(jī)制的一系列步驟。
- 第1步 - 隨機(jī)生成初始種群。
- 第2步 - 選擇具有最佳適合度值的初始解決方案。
- 步驟3 - 使用突變和交叉算子重新組合所選解決方案。
- 第4步 - 將后代插入人口。
- 步驟5 - 現(xiàn)在,如果滿足停止條件,則返回具有最佳適合度值的解決方案。否則轉(zhuǎn)到第2步。
安裝必要的軟件包
為了通過Python中的遺傳算法解決問題,我們將使用一個名為DEAP的功能強(qiáng)大的GA包。它是一個新的進(jìn)化計算框架庫,用于快速原型設(shè)計和思想測試。我們可以在命令提示符下使用以下命令安裝此軟件包 -
pip install deap
如果您使用的是anaconda環(huán)境,則可以使用以下命令安裝deap -
conda install -c conda-forge deap
使用遺傳算法實(shí)現(xiàn)解決方案
本節(jié)將介紹使用遺傳算法實(shí)現(xiàn)解決方案的過程。
生成位模式
以下示例顯示如何根據(jù)One Max問題生成包含15個字符串的位字符串。
如圖所示導(dǎo)入必要的包 -
import random from deap import base, creator, tools
定義評估功能。這是創(chuàng)建遺傳算法的第一步。
def eval_func(individual): target_sum = 15 return len(individual) - abs(sum(individual) - target_sum),
現(xiàn)在,使用正確的參數(shù)創(chuàng)建工具箱 -
def create_toolbox(num_bits): creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", list, fitness=creator.FitnessMax)
初始化工具箱
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)
注冊評估運(yùn)營商 -
toolbox.register("evaluate", eval_func)
現(xiàn)在,注冊交叉運(yùn)算符 -
toolbox.register("mate", tools.cxTwoPoint)
注冊變異算子 -
toolbox.register("mutate", tools.mutFlipBit, indpb = 0.05)
定義繁殖的運(yù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')
評估整個人口 -
fitnesses = list(map(toolbox.evaluate, population)) for ind, fit in zip(population, fitnesses): ind.fitness.values = fit print('\nEvaluated', len(population), 'individuals')
創(chuàng)造和迭代幾代人 -
for g in range(num_generations): print("\n- Generation", g)
選擇下一代個人 -
offspring = toolbox.select(population, len(population))
現(xiàn)在,克隆選定的個人 -
offspring = list(map(toolbox.clone, offspring))
在后代上應(yīng)用交叉和變異 -
for child1, child2 in zip(offspring[::2], offspring[1::2]): if random.random() < probab_crossing: toolbox.mate(child1, child2)
刪除孩子的健身價值
del child1.fitness.values del child2.fitness.values
現(xiàn)在,應(yīng)用變異 -
for mutant in offspring: if random.random() < probab_mutating: 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 print('Evaluated', len(invalid_ind), 'individuals')
現(xiàn)在,用下一代個人取代人口 -
population[:] = offspring
打印當(dāng)前世代的統(tǒng)計數(shù)據(jù) -
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")
打印最終輸出 -
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
符號回歸問題
這是遺傳編程中最著名的問題之一。所有符號回歸問題都使用任意數(shù)據(jù)分布,并嘗試使用符號公式擬合最準(zhǔn)確的數(shù)據(jù)。通常,像RMSE(均方根誤差)這樣的度量用于衡量個體的適應(yīng)度。這是一個經(jīng)典的回歸問題,在這里我們使用等式5x 3 -6x 2 + 8x = 1。我們需要遵循上面示例中的所有步驟,但主要部分是創(chuàng)建原始集,因?yàn)樗鼈兪莻€人的構(gòu)建塊,因此評估可以開始。在這里,我們將使用經(jīng)典的基元集。
以下Python代碼詳細(xì)解釋了這一點(diǎn) -
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)
請注意,所有基本步驟與生成位模式時使用的步驟相同。該程序?qū)⒃?0代之后給出輸出為min,max,std(標(biāo)準(zhǔn)偏差)。
以上就是AI與Python人工智能遺傳算法的詳細(xì)內(nèi)容,更多關(guān)于AI Python遺傳算法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
matplotlib之Font family [‘sans-serif‘] not&nbs
本文主要介紹了matplotlib之Font family [‘sans-serif‘] not found的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Pandas中常用的七個時間戳處理函數(shù)使用總結(jié)
在零售、經(jīng)濟(jì)和金融等行業(yè),數(shù)據(jù)總是由于貨幣和銷售而不斷變化,生成的所有數(shù)據(jù)都高度依賴于時間。如果這些數(shù)據(jù)沒有時間戳或標(biāo)記,實(shí)際上很難管理所有收集的數(shù)據(jù)。本文為大家準(zhǔn)備了Pandas中常用的七個時間戳處理函數(shù),需要的可以參考一下2022-04-04Python緩存技術(shù)實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Python緩存技術(shù)實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09Django框架基礎(chǔ)模板標(biāo)簽與filter使用方法詳解
這篇文章主要介紹了Django框架基礎(chǔ)模板標(biāo)簽與filter使用方法,簡單分析了Django模板基本語法、函數(shù)與自定義filter相關(guān)使用技巧,需要的朋友可以參考下2019-07-07python3實(shí)現(xiàn)將json對象存入Redis以及數(shù)據(jù)的導(dǎo)入導(dǎo)出
這篇文章主要介紹了python3實(shí)現(xiàn)將json對象存入Redis以及數(shù)據(jù)的導(dǎo)入導(dǎo)出,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python入門教程(十八)Python的For循環(huán)
這篇文章主要介紹了Python入門教程(十八)Python的For循環(huán),Python是一門非常強(qiáng)大好用的語言,也有著易上手的特性,本文為入門教程,需要的朋友可以參考下2023-04-04