Эта функция:
def weighted_choice(self, dna):
"""
Chooses a random element from tags.
Weight determines the probability
of choosing its respective item.
"""
weight_total = sum((d[1] for d in dna))
n = random.uniform(0, weight_total)
for d, weight in dna:
if n < weight:
return d
n = n - weight
return d
возвращает следующую ошибку:
Traceback (most recent call last):
File "/usr/src/app/project/api/classifiers/metadata/bio/replicate.py", line 39, in brandio_genetics
client_and_product_genes = bio.fitness(place_dna, client_dna)
File "/usr/src/app/project/api/classifiers/metadata/bio/dna.py", line 553, in fitness
# print each offspring
File "/usr/src/app/project/api/classifiers/metadata/bio/dna.py", line 508, in crossover
# genre 2
File "/usr/src/app/project/api/classifiers/metadata/bio/dna.py", line 440, in weighted_choice
UnboundLocalError: local variable 'd' referenced before assignment
структура данных:
dna1 = {'patalanov': {'indie pop': 100, 'indie': 97, 'australian': 90, '80s': 52, 'alternative': 52, 'new wave': 27, 'jangle pop': 26, 'seen live': 25, 'rock': 23, 'indie rock': 23, 'pop': 21, 'australia': 16, 'post-punk': 15, 'alternative rock': 11, 'Brisbane': 10, 'twee': 6, 'college rock': 5, 'singer-songwriter': 5, 'Post punk': 5, 'Aussie': 4, 'The Go-Betweens': 4, 'punk': 3, 'power pop': 3, 'elegant': 3, "80's": 3, 'alternative pop': 3, 'Favourites': 3, 'indie-pop': 3, 'guitar pop': 3, 'All': 3, 'twee pop': 2, 'romantic': 2, '90s': 2, 'Passionate': 2, 'literate': 2, 'melancholy': 2, 'Favorite Artists': 2, 'soft': 2, 'male vocalists': 2, 'oz': 2, 'emusic': 2, 'neo acoustic': 2, '80s indie': 2, 'postcard': 2, 'Grant McLennan': 2, 'Robert Forster': 2, '70s': 2, 'emo': 2, 'folk': 2, 'favorites': 2, 'indiepop': 2, 'americana': 2, 'Reflective': 2, 'genius': 2, 'Alt-country': 2, 'Bittersweet': 2, '00s': 2, 'sophisticated': 2, '1980s': 2, 'wistful': 2, 'jangle': 2, 'c86': 2, 'Left of the Dial': 2, 'Very Good': 2, 'Godlike': 2, 'old favorites': 2, 'wrongly tagged as twee': 2, 'hi fidelity': 2, 'jangle-pop': 2, 'records and tapes': 2}}
dna2 = {'Suplicy': {'electronica ': 288.0, 'art rock ': 290.0, 'chillout ': 288.0, 'genius ': 290.0, 'trip-hop ': 287.0, 'psychedelic ': 288.0, 'indie pop ': 287.0, 'ambient ': 288.0, 'indie rock ': 291.0, 'post-rock ': 287.0, 'alternative rock ': 291.0, 'seen live ': 288.0, 'melancholic ': 290.0, 'Awesome ': 291.0, 'radiohead ': 295.0, 'emo ': 286.0, 'rock ': 292.0, 'indie ': 289.0, '90s ': 5.0, 'pop ': 288.0, 'britpop ': 289.0, 'british ': 293.0, 'classic rock ': 288.0, 'better than radiohead ': 288.0, 'overrated ': 288.0, 'alternative ': 290.0, 'Progressive ': 289.0, 's ': 283.0, 'Favorite ': 288.0, 'electronic ': 289.0, 'Experimental Rock ': 289.0, 'beautiful ': 290.0, 'melancholy ': 290.0, 'idm ': 288.0, 'Progressive rock ': 288.0, 'favorites ': 288.0, 'english ': 288.0, 'male vocalists ': 289.0, 'experimental ': 288.0, 'UK ': 290.0}}
послеtraceback:
def crossover(self, dna1, dna2):
"""
Mixes dna1 and dna2.
"""
global breed
# get alleles for gene 1
A = self.alleles(dna1)[1]
a = self.alleles(dna1)[2]
# get alleles for gene 2
B = self.alleles(dna2)[1]
b = self.alleles(dna2)[2]
# format alleles as dictionaries
AB, Ab, Ba, ab = ({} for i in range(4))
# genre 1
AB[str(self.weighted_choice(A))]='A'
AB[str(self.weighted_choice(B))]='B'
# genre 2
Ab[str(self.weighted_choice(A))]='A'
Ab[str(self.weighted_choice(b))]='b'
# genre 3
Ba[str(self.weighted_choice(B))]='B'
Ba[str(self.weighted_choice(a))]='a'
# genre 4
ab[str(self.weighted_choice(a))]='a'
ab[str(self.weighted_choice(b))]='b'
# pick a random number
x = random.random()
# set percentage
if x < 0.25:
# if low, generate recessive genotypes
genotype = random.choice([ab])
breed = ' '.join([k for k in genotype])
#return genotype
else:
# if low, generate dominant genotypes
genotype = random.choice([AB, Ab, Ba])
breed = ' '.join([k for k in genotype])
return (genotype, breed)
def fitness(self, dna1, dna2, generations=600):
'''
Most adapted phenotype after many generations.
'''
# container for unique breeds
offspring = set()
# fetch million song dataset
pool = self.genome()
# test for many generations
for generation in range(generations):
print ("Generation %s..." % (generation))
# mix phenotype
breed = self.crossover(dna1,dna2)[1]
# print each offspring
print (breed)
# build genotype
offspring.add(breed)
# container for sequences
matches = []
# lookup offspring in genetic pool
for o in sorted(offspring):
for p in pool:
# compare genetic sequences
seq = difflib.SequenceMatcher(None, a=o.lower(), b=p.lower())
print (o, p, round(seq.ratio(), 4))
# sort matches by similarity ratio
matches.append([o, p, round(seq.ratio(), 4)])
# order fittest by descending order
# similarity = sorted(matches, key=lambda x: x[2], reverse=True)
similarity = sorted(matches, key=lambda x: x[2], reverse=True)
# containers for optimized genetic values
fit = []
# add
for m in matches:
# if m[2] == 1.0:
# fit.append(m)
if 0.8880 <= m[2] <= 1.0:
fit.append(m)
return sorted(fit, key=lambda x: x[2], reverse=True)
def alleles(self, dna):
global allele
# each user is one
individual = dna.keys()
# containers for data
total = []
dominant = []
recessive = []
for k, v in dna.items():
# track gene strength # python 3 requires list for indexing
weight = list(v.values())
# add all weights
total.append(weight[0])
# each tag is a 'gene'
gene = v.keys()
# format in allele fashion
allele = zip(gene, weight)
# get the average weight for tags
mean = sum(total)/len(total)
# print allel
for a in allele:
# above avg is a dominant tag
if a[1] > mean:
dominant.append(a)
elif a[1] == 1.0:
dominant.append(a)
recessive.append(a)
# below avg is a recessive tag
else:
recessive.append(a)
return (individual, dominant, recessive)
что не так?