Cieľom je merať odchýlku a rozpätie selekčných vzorkovacích metód. Ide o to, že:
Je daná skupina jedincov, pričom každý z nich má pridelenú inú hodnotu vhodnosti. Na základe tejto vhodnosti a použitej vzorkovacej metódy je možné pre každého jedinca určiť očakávanú pravdepodobnosť vzorkovania a očakávaný počet výberov.
Realizuje sa selekčný proces (keďže sa jedná o stochastický proces, tak sa viackrát opakuje pre získanie spoľahlivejšej vzorky dát). Pre každého jedinca sa zaznamená, koľkokrát bol počas jednotlivých opakovaní selekcie vyberaný za rodiča. Z týchto dát je možné pre každého jedinca určiť skutočné rozpätie výberov pripadajúcich na daného jedinca.
Pre prípravu experimentu je potrebné doplniť (nahradiť) kód v bunke venovanej selekčnej metóde.
%matplotlib inline
from random import shuffle, randrange
from functools import reduce
import matplotlib.pyplot as plt
# Generovanie populácie
μ = 100 # veľkosť populácie
populacia = [i for i in range(μ)]
shuffle(populacia)
# Určenie vhodnosti jedincov
MIN = 0.0 # vhodnosť najhoršieho jedinca
MAX = 2.0 # vhodnosť najlepšieho jedinca
def Φ(jedinec):
return MIN + (MAX - MIN) / (μ - 1) * jedinec
populacia = [(i, Φ(i)) for i in populacia]
# Selekčná metóda - vyberá sa toľko rodičov, koľko je jedincov v populácii
def vyber_rodica(jedince):
return randrange(0,μ)
def selekcia(jedince):
rodicia = []
for _ in jedince:
rodicia.append(vyber_rodica(jedince))
return rodicia
# Experiment - opakované selekcie
OPAKOVANIA = 1000
vyber_poc = [0] * μ # kumulovanie počty vyberov jedincov
vyber_min = [None] * μ # sledovanie minimálneho počtu výberov jedincov
vyber_max = [None] * μ # sledovanie maximálneho počtu výberov jedincov
for _ in range(OPAKOVANIA):
vybery = [0] * μ
for rodic in selekcia(populacia):
vybery[rodic] += 1
for jedinec, vyber in enumerate(vybery):
vyber_poc[jedinec] += vyber
if vyber_min[jedinec] is None or vyber_min[jedinec] > vyber:
vyber_min[jedinec] = vyber
if vyber_max[jedinec] is None or vyber_max[jedinec] < vyber:
vyber_max[jedinec] = vyber
# Odchýlka
# teoretická pravdepodobnosť selekcie
Φsum = reduce(lambda x, y: x + y[1], populacia, 0)
ps_ocak = [(i, Φi / Φsum) for (i, Φi) in populacia] # očakávaná ps pri proporcionálnej selekcii
ps_ocak = list(map(lambda x: x[1], sorted(ps_ocak, key=lambda x: x[0])))
# skutocná pravdepodobnosť selekcie
ps_skut = [(i, vyber_poc[i] / (OPAKOVANIA * μ)) for (i, _) in populacia]
ps_skut = list(map(lambda x: x[1], sorted(ps_skut, key=lambda x: x[0])))
fig, (sub1, sub2) = plt.subplots(nrows=1, ncols=2, figsize=(15,5), sharex=True)
fig.suptitle("Vyhodnotenie odchýlky", fontsize=16)
sub1.set_title("Očakávaná a realizovaná pravdepodobnosť selekcie")
sub1.plot(ps_ocak,"b-", label="očakávaná")
sub1.plot(ps_skut,"r-", label="realizovaná")
sub1.legend(loc="upper left")
sub1.set(xlabel="jedince", ylabel="pravdepodobnosť")
sub2.set_title("Rozdiel teoretickej a realizovanej pravdepodobnosti selekcie")
sub2.plot(list(map(lambda x, y: x - y, ps_ocak, ps_skut)),"b-", label="očakávaná - realizovaná")
sub2.legend(loc="upper left")
sub2.set(xlabel="jedince", ylabel="pravdepodobnosť")
plt.show()
# Rozpätie
plt.suptitle("Rozpätie")
plt.xlabel("jedinec")
plt.ylabel("rozpätie")
plt.plot([i for i in range(μ)], vyber_min, label="min")
plt.plot([i for i in range(μ)], vyber_max, label="max")
plt.plot([i for i in range(μ)], [μ * i for i in ps_ocak], label="očakávané")
plt.legend(loc="upper left")
plt.gcf().set_size_inches(7, 5)
plt.show()