我正在考虑使用诸如马尔可夫链之类的东西创建一个聊天机器人,但我不完全确定如何让它工作。据我了解,您从数据中创建一个表格,其中包含给定的单词,然后是后面的单词。在训练机器人时是否可以附加任何类型的概率或计数器?这甚至是个好主意吗?
问题的第二部分是关键字。假设我已经可以从用户输入中识别关键字,我如何生成一个使用该关键字的句子?我并不总是想用关键字开始句子,那么我如何播种马尔可夫链呢?
我正在考虑使用诸如马尔可夫链之类的东西创建一个聊天机器人,但我不完全确定如何让它工作。据我了解,您从数据中创建一个表格,其中包含给定的单词,然后是后面的单词。在训练机器人时是否可以附加任何类型的概率或计数器?这甚至是个好主意吗?
问题的第二部分是关键字。假设我已经可以从用户输入中识别关键字,我如何生成一个使用该关键字的句子?我并不总是想用关键字开始句子,那么我如何播种马尔可夫链呢?
几年前,我用 Python 为 IRC 制作了一个马尔可夫链聊天机器人,并且可以阐明我是如何做到的。生成的文本不一定有任何意义,但阅读起来确实很有趣。让我们逐步分解它。假设你有一个固定的输入,一个文本文件,(你可以使用聊天文本或歌词的输入,或者只是发挥你的想象力)
循环遍历文本并制作字典,即键值容器。并将所有单词对作为键,将后面的单词作为值。例如:如果你有一个文本“abcab k”,你以“a b”作为键,“c”作为值,然后“b c”和“a”作为值......值应该是一个列表或任何集合持有0..many 'items' 因为对于给定的一对单词,您可以有多个值。在上面的示例中,您将有两次“a b”,然后是“c”,最后是“k”。所以最后你会得到一个像这样的字典/哈希:{'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}
现在你有了构建时髦文本所需的结构。您可以选择从随机密钥或固定位置开始!所以给定我们的结构,我们可以从保存“a b”开始,然后从值 c 或 k 中随机取下一个单词,所以循环中的第一个保存,“ab 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”并随机选择一个值,这里只有一个值,所以它的“name”
(SAVING “hi my name”)。
现在向右移动一步,将“我的名字”作为下一个键并选择一个随机值......“是”
(SAVING “hi my name is”)。
现在移动并取 "name is" ... "Al"
(SAVING "hi my name is AL")。
现在采取 "is Al" ... "and"
(SAVING "hi my name is Al and")。
...
当你来到“and i”时,你会随机选择一个值,比如说“can”,然后出现“i can”这个词等等......当你到达停止条件或者你没有值时打印构造的在我们的例子中是字符串:
“嗨,我的名字是 Al,我想住多久就住多久”
如果你有更多的值,你可以跳转到任何键。值越多,您拥有的组合就越多,文本就越随机和有趣。
机器人从您的输入中选择一个随机词,并通过选择另一个随机词来生成响应,该随机词已被视为其持有的词的后继词。然后它通过依次找到该词的后继词并迭代地继续执行该过程,直到它认为它已经说得足够多,从而重复该过程。它通过停在训练文本中标点符号之前的一个词来得出这个结论。然后它再次返回输入模式以让您响应,依此类推。
这不是很现实,但我在此挑战任何人在 71 行代码中做得更好!对于任何初露头角的 Python 爱好者来说,这都是一个巨大的挑战,我只希望我能向更广泛的受众开放挑战,而不是我访问这个博客的少数访问者。为了编写一个始终保证语法正确的机器人,它肯定接近几百行,我通过尝试考虑最简单的规则来极大地简化计算机,让计算机仅仅尝试有话要说。
它的反应至少可以说是相当印象派的!此外,您必须将您所说的内容放在单引号中。
我使用战争与和平作为我的“语料库”,训练运行需要几个小时,如果您不耐烦,请使用较短的文件……</p>
这是教练
#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
You tend to get an uncanny feeling when it says something that seems partially to make sense.
你可以这样做:使用单词而不是字母创建一个 order 1 马尔可夫链生成器。每次有人发布内容时,他发布的内容都会添加到机器人数据库中。当他去聊天和一个人发布第一个帖子(以 10 秒的倍数)时,机器人也会保存,然后他会节省同一个人等待再次发帖的时间(以 10 秒的倍数)......这第二部分将用于查看该人何时发布,因此他加入聊天并在基于“一个人在加入聊天后多少 10 秒后发布”的表格的一段时间后,然后他将继续在同一张桌子上发帖,思考“在他用 X 秒思考和撰写的帖子之后发布的帖子花费了多少时间”