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

时间:2011-03-15 02:05:34

标签: artificial-intelligence probability chatbot markov-chains

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

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

3 个答案:

答案 0 :(得分:135)

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

遍历文本并创建一个Dictionary,意思是键值容器。并将所有单词作为键,然后将单词作为值。 例如:如果你有一个文本“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"]

......

现在构建一个循环:

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

...

当你来到“和我”时,你会随机选择一个值,让我们说“可以”,然后单词“我可以”等等......当你达到停止条件或没有价值时在我们的例子中打印构造的字符串:

“我的名字是Al,只要我愿意,我就可以住在那里”

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

答案 1 :(得分: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()

这是机器人:

#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

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

答案 2 :(得分:0)

你可以这样做: 使用单词而不是字母创建订单1马尔可夫链生成器。 每当有人发布某些内容时,他发布的内容都会添加到bot数据库中。 当他去聊天时,机器人会保存,当一个人发布第一个帖子(10秒的倍数)时,他会节省同一个人等待再次发布的时间(10秒的倍数)...... 第二部分将用于查看该人发布的时间,因此他加入聊天并在一段时间后根据一张桌子加入聊天,并且在加入聊天后一个人发布了多少10秒钟后#34; ,然后他会继续用相同的表格发表思考"在用过X秒思考和写作的帖子之后发布的帖子用了多长时间?"