#python #nltk #genetic-algorithm #context-free-grammar
#python #nltk #генетический алгоритм #контекстно-свободная грамматика
Вопрос:
Учитывая грамматику NLTK, как я могу представить предложение, используя массив целых чисел?
Я использую NLTK для генерации некоторых предложений из определенной грамматики. Я хотел бы сгенерировать массив целых чисел для представления генома для сгенерированного предложения (фенотипа).
С таким представлением целых чисел я бы эволюционировал геном в генетическом алгоритме, выполнив некоторые мутации, чтобы получить лучшие предложения.
Например,
from nltk import CFG
from nltk.parse.generate import generate, demo_grammar
g = CFG.fromstring(demo_grammar)
sentence = next(generate(g, n=1))
print(sentence) # ex: ['the', 'man', 'saw', 'the', 'park']
convert_to_genotype(sentence) # returns [253, 69, 221, 97, 190, 254, 67, 137, 95, 72, 54, 232, 11, 136] for example.
Как я могу создать convert_to_genotype
функцию?
Спасибо
Ответ №1:
После некоторых исследований я создал реализацию, которая создает фенотип для данного генома. Это было то, что я искал, чтобы развивать своих людей, созданных с использованием правил грамматики.
import nltk
from nltk import CFG
GRAMMAR = CFG.fromstring("""
string -> letter | letter string
letter -> vowel | consonant | char
char -> ' '|'!'|'?'|','|'.'
vowel -> lower_vowel | upper_vowel
lower_vowel -> 'a'|'e'|'o'|'i'|'u'
upper_vowel -> 'A'|'E'|'I'|'O'|'U'
consonant -> lower_consonant | upper_consonant
lower_consonant -> 'b'|'c'|'d'|'f'|'g'|'h'|'j'|'k'|'l'|'m'|'n'|'p'|'q'|'r'|'s'|'t'|'v'|'w'|'x'|'y'|'z'
upper_consonant -> 'B'|'C'|'D'|'F'|'G'|'H'|'J'|'K'|'L'|'M'|'N'|'P'|'Q'|'R'|'S'|'T'|'V'|'W'|'X'|'Y'|'Z'
""")
def genome_to_grammar(array):
sb = []
stack = [GRAMMAR.start()]
index = 0
wraps = 0
while stack:
symbol = stack.pop()
if isinstance(symbol, str):
sb.append(symbol)
else:
rules = [i for i in GRAMMAR.productions() if i.lhs().symbol() == symbol.symbol()]
rule_index = 0
if len(rules) > 1:
rule_index = array[index] % len(rules)
index = 1
if index >= len(array):
index = 0
wraps = 1
if wraps > 10:
return None
rule = rules[rule_index]
for production in reversed(rule.rhs()):
stack.append(production)
return ''.join(sb)
genome = [253, 69, 221, 97, 190, 254, 67, 137, 95, 72, 54, 232, 11, 136]
print(genome_to_grammar(genome))