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


73

我当时在考虑使用markov链创建聊天机器人,但我不确定如何使它工作。据我了解,您是根据数据创建一个表的,其中包含给定的单词,然后是给定的单词。训练机器人时是否可以附加任何可能性或计数器?那是个好主意吗?

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


1
表格2D数据对于人工智能并不是真正有用,图形将更加有益。为了得到后续的支持,贝叶斯网络是最好的解决方案。要构成句子,必须进行语言处理,而您不能使用基本逻辑(例如马氏链)来完成它
AbiusX 2011年

2
用马尔可夫链条你做不到吗?存在一些使用马尔可夫链的机器人,尽管它实际上只是将句子组合在一起,但我认为它们并不总是有意义。
约旦

您可以,但不能进行语言处理。只是弄清楚最可能的句子。
AbiusX 2011年

@AbiusX:您什么意思是“找出最可能的句子”?贝叶斯网络会给我什么,而马尔可夫链不会呢?我将如何处理?马尔可夫链不像贝叶斯网络吗?我的意思是,您仍在处理概率以及诸如有向图之类的东西,它只是存储在表中。在每个单词上,您仍在选择下一个单词以给定的概率跟随,不是吗?有什么不同?我可以从马尔可夫链开始,并添加其他逻辑吗?有什么建议?谢谢!
约旦

1
@乔丹:人工智能是一个广泛的话题。我曾经与Bayesian Nets,Semantic Webs和一些创新想法进行过聊天机器人,听起来不错。如果您不太了解AI,请坚持创意。贝叶斯网络会让您的机器人说出“您是秘鲁人吗?”之类的话。这不是一个正确的句子,但是会让您觉得它很聪明!(将Bayesian Nets应用于单词中的字母选择以生成新单词,这就是CAPTCHA算法的作用,因为您已经在CAPTCHA图像中看到了毫无意义但又不错的单词)
AbiusX 2011年

Answers:


139

几年前,我用Python为IRC制作了一个Markov链聊天机器人,可以说明我的工作方式。生成的文本不一定有意义,但是阅读起来确实很有趣。让我们分步分解它。假设您有一个固定的输入文本文件(您可以使用聊天文本或歌词中的输入,也可以只是想像力)

循环遍历文本并创建一个Dictionary,意思是键-值容器。并将所有单词对作为键,并将其后的单词作为值。例如:如果文本为“ abcab k”,则以“ ab”为键,以“ c”为值,然后以“ bc”和“ a”为值...该值应为列表或任何保存的集合0 ..许多“项目”,因为给定的单词对可以有多个值。在上面的示例中,您将有两次“ 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"]

......

现在构造一个循环:

选择一个随机密钥,说“ hi my”,然后随机选择一个值,这里只选一个,以便其为“ name” (保存“ hi my name”)
现在,以“我的名字”作为下一个键,向右移动一步,并选择一个随机值...“是” (保存“我的名字是”)
现在移动并取“ name is” ...“ Al” (保存“ hi my name is AL”)
现在取“是Al” ...“和” (保存“嗨,我叫Al和”)

...

当您来到“和我”时,您将随机选择一个值,让我们说“可以”,然后用单词“我可以”等。本例中的字符串:

“嗨,我叫Al,只要我愿意,我就可以住在那里”

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


1
如果使用聊天文本作为输入,则必须使机器人变得“聪明”,当有人提到该机器人名称时,就会触发响应。我把整个字符串写好,首先检查是谁写的,然后以这个名字开始回答,例如“ Jordan:bla bla”,然后我从该字符串中选择了一对单词并从那里开始。我还可以用第二个以“ and(随机词)”开头的句子组成两个句子,我还随机选择了我的回答有多长时间,也许是5-50个单词。我还有一个以上的“大脑”,可以玩更多的结构。大脑基本上只是一个文本文件。
诺克,

1
忘了说,如果您使用聊天输入,由于人们容易犯很多拼写错误和捷径,这可能会很困难,那么您的漫游器将像这样。如果有时间,您还可以研究自然语言处理,这是Python链接中的内容
Nocker

如果您仍然有任何来源,请将其放在github上。
user1943442 2015年

我做了类似的事情,在程序上扫描了Oliver Twist,并提取了每个4字块组合以及每个组合的频率。花了很长时间才生成频率图,并且只输出接近无意义的文本的垃圾字符串。我希望我能重新了解这种方法!
Carcigenicate 2015年

1
我认为这里有一个遗漏的部分,因为马尔可夫链根据概率进行决策,因此当涉及到“和我”时,系统应该能够重新评估整个字符串(而不仅仅是最后一个密钥对),直到在那里确定下一个单词。系统应该告诉您“下一个”应该是下一个,而不是偶然。
胡安·萨莫拉

9

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

这不是很现实,但我特此挑战任何人,使其在71行代码中做得更好!对于任何刚起步的Python工作者来说,这都是一个巨大的挑战,我只希望我可以向比这个博客访问者少的访问者开放更多的受众。要编写始终保证语法合理的机器人程序,必须肯定要接近几百行,我通过尝试考虑最简单的规则来简化计算机,让计算机仅需说些什么就大大简化了程序。

至少可以说,它的回应是印象派的!同样,您必须将您所说的内容放在单引号中。

我为我的“语料库”使用了“战争与和平”,这花了几个小时进行训练,如果您急躁,请使用较短的文件…

这是教练

#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

当您说出某些似乎有道理的话时,您往往会感到一种古怪的感觉。


0

您可以这样:用单词而不是字母制作1阶markov链生成器。每当有人发布内容时,他发布的内容都会添加到bot数据库中。当他去聊天和一个人发布第一条帖子时,bot也会节省(以10秒的倍数),然后他会节省同一个人再次等待发布的时间(以10秒的倍数)...第二部分将用于查看该人何时发布信息,因此他加入了聊天,并在基于“有一个人在加入聊天后发布了10秒后”的表格之后经过了一段时间。用同一张桌子发帖,思考“写一篇帖子后花了多长时间,他花了X秒钟思考和写一篇帖子”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.