马尔可夫链聊天机器人如何运作?

Jor*_*dan 70 artificial-intelligence probability markov-chains chatbot

我正在考虑使用马尔可夫链等创建一个聊天机器人,但我不完全确定如何让它工作.根据我的理解,您可以根据具有给定单词的数据创建表格,然后根据后面的单词创建表格.在训练机器人时是否可以附加任何类型的概率或计数器?这是一个好主意吗?

问题的第二部分是关键字.假设我已经可以从用户输入中识别关键字,如何生成使用该关键字的句子?我并不总是想用关键字开始这个句子,那么如何为马尔可夫链种子?

小智 137

几年前我在Python中为IRC创建了一个马尔可夫链聊天机器人,并且可以解释我是如何做到这一点的.生成的文本不一定有意义,但阅读起来真的很有趣.让我们逐步分解.假设你有一个固定的输入,一个文本文件,(你可以使用聊天文本或歌词中的输入或只是使用你的想象力)

循环遍历文本并创建一个Dictionary,意思是键值容器.并将所有单词作为键,然后将单词作为值.例如:如果你有一个文本"abcab k"你开始用"ab"作为键,"c"作为值,然后"bc"和"a"作为值...值应该是一个列表或任何集合持有0..many'itements',因为对于给定的单词对,您可以有多个值.在上面的示例中,您将有两次"a b",然后是"c",最后是"k".所以最后你会有一个字典/哈希看起来像这样:{'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

现在,您拥有了构建时髦文本所需的结构.您可以选择以随机密钥或固定位置开头!所以给定我们的结构,我们可以先保存"ab",然后随机从值c或k中取一个跟随的单词,这样第一次保存在循环中,"ab k"(如果"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"]

......
Run Code Online (Sandbox Code Playgroud)

现在构造一个循环:

选择一个随机密钥,说"我好"并随机选择一个值,这里只有一个,所以它的"名称" (保存"我的名字").
现在向右移动一步,将"我的名字"作为下一个键并选择一个随机值..."是" (保存"我的名字是").
现在移动并取"名字是"......"Al" (保存"我的名字是AL").
现在拿"是Al"......"和" (保存"我的名字是Al和").

...

当你来到"和我"你将随机选择一个值,让我们说"可以",然后单词"我可以"等等...当你到达你的停止条件或你没有值打印构造我们的案例中的字符串

"我的名字是Al,我可以住在那里,只要我想要"

如果您有更多值,您可以跳转到任何键.值越多,您拥有的组合越多,文本的随机性和趣味性就越大.

  • 我认为这里缺少一个部分,因为马尔可夫链根据概率做出决策,所以当涉及到“和我”时,系统应该能够重新评估整个字符串(而不仅仅是最后一个密钥对),直到在那里确定下一个单词。系统应该告诉你“live”应该是下一个,但不是偶然的。 (2认同)

use*_*316 7

机器人从您的输入中选择一个随机单词,并通过选择另一个被视为其持有单词的后继单词的随机单词来生成响应.然后通过依次找到该单词的后继者并反复进行直到它认为已经说得足够重复该过程.通过停止在训练文本中的标点符号之前的单词来达到该结论.然后它再次返回到输入模式以让您响应,依此类推.

这不是很现实,但我在此挑战任何人在71行代码中做得更好!! 对于任何崭露头角的Python主义者来说,这是一个巨大的挑战,我希望我能够向更广泛的受众开放挑战,而不是我访问此博客的少数访问者.编码一个总是保证语法的机器人肯定会接近几百行,我只是试图想出最简单的规则来简化计算机只是为了让计算机只需要说些什么.

至少可以说它的反应相当印象派!你也必须把你说的用单引号括起来.

我使用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()
Run Code Online (Sandbox Code Playgroud)

这是机器人:

#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
Run Code Online (Sandbox Code Playgroud)

当它说出一些似乎有意义的东西时,你往往会有一种不可思议的感觉.