Created
April 26, 2021 13:24
-
-
Save Blucknote/a518f1208a6b4a8bc5080af3b40c1efa to your computer and use it in GitHub Desktop.
markov chain?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
class Dictogram(dict): | |
def __init__(self, iterable=None): | |
# Инициализируем наше распределение как новый объект класса, | |
# добавляем имеющиеся элементы | |
super(Dictogram, self).__init__() | |
self.types = 0 # число уникальных ключей в распределении | |
self.tokens = 0 # общее количество всех слов в распределении | |
if iterable: | |
self.update(iterable) | |
def update(self, iterable): | |
# Обновляем распределение элементами из имеющегося | |
# итерируемого набора данных | |
for item in iterable: | |
if item in self: | |
self[item] += 1 | |
self.tokens += 1 | |
else: | |
self[item] = 1 | |
self.types += 1 | |
self.tokens += 1 | |
def count(self, item): | |
# Возвращаем значение счетчика элемента, или 0 | |
if item in self: | |
return self[item] | |
return 0 | |
def return_random_word(self): | |
random_key = random.sample(self, 1) | |
# Другой способ: | |
# random.choice(histogram.keys()) | |
return random_key[0] | |
def return_weighted_random_word(self): | |
# Сгенерировать псевдослучайное число между 0 и (n-1), | |
# где n - общее число слов | |
random_int = random.randint(0, self.tokens - 1) | |
index = 0 | |
list_of_keys = [*self.keys()] | |
# вывести 'случайный индекс:', random_int | |
for i in range(0, self.types): | |
index += self[list_of_keys[i]] | |
# вывести индекс | |
if (index > random_int): | |
# вывести list_of_keys[i] | |
return list_of_keys[i] | |
def make_markov_model(data): | |
markov_model = dict() | |
for i in range(0, len(data) - 1): | |
if data[i] in markov_model: | |
# Просто присоединяем к уже существующему распределению | |
markov_model[data[i]].update([data[i + 1]]) | |
else: | |
markov_model[data[i]] = Dictogram([data[i + 1]]) | |
return markov_model | |
def make_higher_order_markov_model(order, data): | |
markov_model = dict() | |
for i in range(0, len(data) - order): | |
# Создаем окно | |
window = tuple(data[i: i + order]) | |
# Добавляем в словарь | |
if window in markov_model: | |
# Присоединяем к уже существующему распределению | |
markov_model[window].update([data[i + order]]) | |
else: | |
markov_model[window] = Dictogram([data[i + order]]) | |
return markov_model | |
def generate_random_start(model): | |
# Чтобы сгенерировать любое начальное слово, раскомментируйте строку: | |
# return random.choice(model.keys()) | |
# Чтобы сгенерировать "правильное" начальное слово, используйте код ниже: | |
# Правильные начальные слова - это те, что являлись началом предложений в корпусе | |
if 'END' in model: | |
seed_word = 'END' | |
while seed_word == 'END': | |
seed_word = model['END'].return_weighted_random_word() | |
return seed_word | |
return random.choice([*model.keys()]) | |
def generate_random_sentence(length, markov_model): | |
current_word = generate_random_start(markov_model) | |
sentence = [current_word] | |
for i in range(0, length): | |
current_dictogram = markov_model[current_word] | |
random_weighted_word = current_dictogram.return_weighted_random_word() | |
current_word = random_weighted_word | |
sentence.append(current_word) | |
sentence[0] = sentence[0].capitalize() | |
return ' '.join(sentence) + '.' | |
text = """ | |
Попробуйте придумать, где вы сами можете использовать генератор текста на основе марковских цепей. | |
Только не забывайте, что самое главное — это то, как вы парсите модель и какие особые ограничения устанавливаете на генерацию. | |
Автор этой статьи, например, при создании генератора твитов использовал большое окно, | |
ограничил генерируемый контент до 140 символов и использовал для начала предложений только «правильные» слова, | |
то есть те, которые являлись началом предложений в корпусе. END | |
""" | |
m = make_markov_model(text) | |
print(generate_random_sentence(10,m)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment