Как работают чат-боты сети Markov?


Я думал о создании бота, используя что-то вроде цепей Маркова, но я не совсем уверен, как заставить его работать. Из того, что я понимаю, вы создаете таблицу из данных с заданным словом, а затем слова, которые следуют. Можно ли прикрепить какую-либо вероятность или счетчик во время обучения бота? Это вообще хорошая идея?

вторая часть проблемы связана с ключевыми словами. Предполагая, что я уже могу идентифицировать ключевые слова из пользовательского ввода, как мне создать предложение который использует это ключевое слово? Я не всегда хочу начинать предложение с ключевого слова, так как я могу посеять цепочку Маркова?

3 67

3 ответа:

Я сделал Марковскую цепочку чат-ботов для IRC в Python несколько лет назад и могу пролить свет на то, как я это сделал. Сгенерированный текст не обязательно имеет какой-либо смысл, но это может быть действительно интересно читать. Давайте разберем его по шагам. Предполагая, что у вас есть фиксированный ввод, текстовый файл, (вы можете использовать ввод из текста чата или текстов песен или просто использовать свое воображение)

цикл по тексту и сделать словарь, что означает контейнер ключ - значение. И поставить все пары слов в качестве ключей и слова следующее значение. Например: если у вас есть текст "a b c A b k", вы начинаете с "A b" как ключ и "c" как значение, а затем "b c" и "a" как значение... значение должно быть списком или любой коллекцией, содержащей 0..многие 'вещи', как вы можете иметь более одного значения для данной пары слов. В приведенном выше примере у вас будет "a b" два раза, за которым следует кулак "c", а затем в конце "k". Так что в конце концов у вас будет словарь / хэш, выглядящий так:{'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

теперь у вас есть необходимые структуры для создания вашего фанки текста. Вы можете начать со случайного ключа или фиксированного места! Поэтому, учитывая структуру, мы можем начать с экономии "B" тогда, случайным образом, принимая следующие слова от значения, с или к, Поэтому сначала сохраните в петле, "а б к" (если "к" была случайной величины выбрали) затем вы продолжите перемещение на один шаг вправо, в нашем случае это "Б К" и сохранить случайное число для этой пары, если у вас есть, в нашем случае нет, так что выход из цикла (или вы можете выбрать другие вещи, как начать снова.) Когда цикл закончен, вы печатаете сохраненную текстовую строку.

чем больше вход, тем больше значений у вас будет для вас ключей (пара слов), а затем будет "умный бот", чтобы вы могли "тренировать" своего бота, добавляя больше текста (возможно, вход в чат?). Если у вас есть книга в качестве входных данных, вы можете построить несколько хороших случайных предложений. Обратите внимание, что вы не должны принять только одно слово, которое следует за парой в качестве значения, вы можете взять 2 или 10. Разница в том, что ваш текст будет появляются более точные, если вы используете "более длинные" строительные блоки. Начните с пары в качестве ключа и следующего слова в качестве значения.

таким образом, вы видите, что вы в основном можете иметь два шага, сначала сделать структуру, где вы случайно выбираете ключ для начала, а затем взять этот ключ и распечатать случайное значение этого ключа и продолжить, пока у вас нет значения или какого-либо другого условия. Если вы хотите, вы можете "посеять" пару слов из ввода чата из вашей структуры ключ-значение, чтобы начать. Его до ваше воображение, как начать свою цепь.

пример с реальными слова:

"hi my name is Al and i live in a box that i like very much and i can live in there as long as i want"

"hi my" -> ["name"]

"my name" -> ["is"]

"name is" -> ["Al"]

"is Al" -> ["and"]

........

"and i" -> ["live", "can"]

........

"i can" -> ["live"]

......

теперь построим цикл:

выберите случайный ключ, скажите "Привет мой" и случайным образом выберите значение, только один здесь так его " имя" (сохранение "привет мое имя").
Теперь переместите один шаг вправо, взяв "мое имя" в качестве следующего ключа и выберите случайное значение... "есть" (сохранение "привет Меня зовут").
Теперь двигаемся и берем "имя есть"... "Эл" (сохранение " Привет мой зовут АЛ").
Теперь возьмите "is Al"... "и" (сохранение "привет Меня зовут Ал и").

...

когда вы придете к "и я", вы случайно выберете значение, скажем" может", тогда слово" я могу " будет сделано и т. д... когда вы приходите к своему условию остановки или что у вас нет значений, выведите построенную строку в нашем случае:

"привет, Меня зовут Ал, и я могу жить там столько, сколько захочу"

Если у вас есть более значения вы можете перейти к любой клавиши. Чем больше значений, тем больше комбинаций у вас есть, и тем более случайным и забавным будет текст.

бот выбирает случайное слово из вашего ввода и генерирует ответ, выбирая другое случайное слово, которое считается преемником его удерживаемого слова. Затем он повторяет процесс, находя преемника этого слова в свою очередь и продолжая итеративно, пока он не думает, что это сказано достаточно. Он приходит к этому выводу, останавливаясь на слове, которое было до знака препинания в учебном тексте. Затем он снова возвращается в режим ввода, чтобы вы могли ответить, и так далее.

It это не очень реалистично, но я настоящим призываю всех сделать лучше в 71 строках кода !! Это большой вызов для любого начинающего питониста, и я просто хотел бы открыть вызов для более широкой аудитории, чем небольшое количество посетителей, которых я получаю в этом блоге. Чтобы закодировать бота, который всегда гарантированно будет грамматическим, безусловно, должен быть ближе к нескольким сотням строк, я сильно упростил, просто пытаясь придумать самое простое правило, чтобы дать компьютеру простой удар по тому, чтобы что-то сделать сказать.

его ответы довольно импрессионистичны, чтобы не сказать больше ! Также вы должны поставить то, что вы говорите в одинарных кавычках.

Я использовал War and Peace для моего "корпуса", который занял пару часов для тренировочного прогона, используйте более короткий файл, если вы нетерпеливы...

вот тренер

#lukebot-trainer.py
import pickle
b=open('war&peace.txt')
text=[]
for line in b:
    for word in line.split():
        text.append (word)
b.close()
textset=list(set(text))
follow={}
for l in range(len(textset)):
    working=[]
    check=textset[l]
    for w in range(len(text)-1):
        if check==text[w] and text[w][-1] not in '(),.?!':
            working.append(str(text[w+1]))
    follow[check]=working
a=open('lexicon-luke','wb')
pickle.dump(follow,a,2)
a.close()

вот бот:

#lukebot.py
import pickle,random
a=open('lexicon-luke','rb')
successorlist=pickle.load(a)
a.close()
def nextword(a):
    if a in successorlist:
        return random.choice(successorlist[a])
    else:
        return 'the'
speech=''
while speech!='quit':
    speech=raw_input('>')
    s=random.choice(speech.split())
    response=''
    while True:
        neword=nextword(s)
        response+=' '+neword
        s=neword
        if neword[-1] in ',?!.':
            break
    print response

вы могли бы сделать такой: Заказать 1 генератор Марковской цепи, используя слова, а не буквы. Каждый раз, когда кто-то публикует что-то, то, что он опубликовал, добавляется в базу данных ботов. Также бот сохранит, когда он пошел в чат, и когда парень опубликовал первый пост (в кратных 10 секундам), тогда он сэкономит время, которое этот же парень ждал, чтобы опубликовать снова (в кратных 10 секундам)... Эта вторая часть будет использоваться, чтобы увидеть, когда парень опубликует, поэтому он присоединится к чату и после некоторого количества время, основанное на таблице с "через сколько 10 секунд парень опубликовал после присоединения к чату", затем он будет продолжать публиковать с той же таблицей, думая "как было количество времени, используемое для написания сообщения, которое было опубликовано после сообщения, которое он использовал X секунд, чтобы думать и писать"