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

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

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

Ответ 1

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

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

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

Чем больше вход, тем больше значений у вас будут для вас (пара слов), а затем у вас будет "умнее бот", чтобы вы могли "обучать" своего бота, добавляя больше текста (возможно, вход в чат?). Если у вас есть книга в качестве входных данных, вы можете создать несколько хороших случайных предложений. Обратите внимание, что вам не нужно принимать только одно слово, которое следует за парой в качестве значения, вы можете взять 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"]

......

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

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

...

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

"Привет, меня зовут Al, и я могу жить там, пока я хочу"

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

Ответ 2

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

Это не очень реалистично, но я тем самым призываю всех сделать лучше в 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

Вы склонны испытывать странное чувство, когда оно говорит что-то, что кажется частично имеющим смысл.

Ответ 3

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