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

我在考虑用马尔可夫链之类的东西创建一个聊天机器人,但我不完全确定如何让它工作。根据我的理解,您从数据中创建一个表,其中包含一个给定的单词,然后包含下面的单词。在训练机器人时,是否可以附加任何形式的概率或计数器?这是个好主意吗?

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

56375 次浏览

几年前,我用 Python 为 IRC 做了一个 Markov 链式聊天机器人,可以告诉你我是怎么做到的。生成的文本不一定有任何意义,但它可以是真正有趣的阅读。我们一步一步来。假设您有一个固定的输入,一个文本文件(您可以使用聊天文本或歌词的输入,或者仅仅使用您的想象力)

循环遍历文本并创建一个 Dictionary,即键-值容器。并将所有成对的单词作为键,将单词 follow 作为值。 例如: 如果你有一个文本“ 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']}

现在您已经有了构建时髦文本所需的结构。您可以选择从一个随机的键或固定的位置开始!所以给定我们的结构,我们可以从保存“ a b”开始,然后从值 c 或 k 中随机抽取一个下面的单词,所以在循环中的第一个保存,“ a b k”(如果“ k”是随机选择的值) ,然后继续向右移动一步,在我们的例子中是“ b k”,如果你有一个随机值,在我们的例子中没有,所以你打破循环(或者你可以决定其他东西,如重新开始)。循环完成后,打印保存的文本字符串。

输入越大,键值(一对单词)就越多,然后就会有一个“智能机器人”,这样你就可以通过添加更多的文本(也许是聊天输入)来“训练”你的机器人.如果你有一本书作为输入,你可以构造一些漂亮的随机句子。请注意,您不必只取一对后面的一个单词作为值,您可以取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” (保存“嗨我的名字”)
现在向右移动一步,选择“ my name”作为下一个键,然后选择一个随机值... “ is” (保存“嗨,我的名字是”)
现在移动,并采取“名字是”... “艾尔” (保存“嗨,我的名字是 AL”)
现在看“是艾尔”... “和” (保存“嗨,我的名字是艾尔和”)

...

当你说到“ and i”的时候,你会随机选择一个值,比如说“ can”,然后就是“ i can”这个词,等等。.当您到达您的停止条件或您没有值时,在我们的例子中打印构造的字符串:

“嗨,我叫 Al 我想住多久就住多久”

如果您有更多的值,您可以跳转到任何键。值越多,你有更多的组合和更随机和乐趣的文本将。

你可以这样做: 制作一个命令1马尔可夫链生成器,使用单词而不是字母。 每次有人发布东西,他发布的东西都会被添加到机器人数据库。 还有,聊天的时候,如果有人发布了第一个帖子(10秒的倍数) ,那么聊天机器人就会节省这个人等待再次发布的时间(10秒的倍数) ... ..。 第二部分是用来看看这个家伙什么时候发帖,所以他加入了聊天,然后根据一个表格“这个家伙在加入聊天后发了多长时间”,过了一段时间之后,他会继续用同一个表格发帖,思考“他用了 X 秒钟思考和写作后发布的帖子用了多长时间来写”

Bot 从您的输入中选择一个随机单词,并通过选择另一个已被视为其所持单词的继承者的随机单词来生成响应。然后重复这个过程,依次找到这个词的继承者,并不断重复,直到它认为已经说得够多了。它通过停在训练文本中标点符号之前的一个单词得出这个结论。然后它再次返回到输入模式,让您响应,以此类推。

这是不是很现实,但我在此挑战任何人做得更好的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

当它说的一些事情似乎部分有道理时,你往往会有一种不可思议的感觉。