“look and give up in miracles”
“仰望奇迹,放弃幻想”
但其实上面这些鸡汤句子全都是电脑生成的,而且其生成鸡汤文所用的程序还不到 20 行 Python 代码。
一提到自然语言生成,人们通常会觉得这一定是很先进的 AI 系统,使用了很高级的数学知识。但是,事实并非如此。在本文我(作者 Ramtin Alami——译者注)会用马尔科夫链(Markov chains)和一个很小的鸡汤文数据集生成新的鸡汤文。
更多Python视频、源码、资料加群725638078免费获取
马尔科夫链
马尔科夫链是一种随机模型,能根据先前的事件单独预测一个事件。举个简单的例子,就用我家喵主子的生活状态转换解释一下吧。我家喵主子总是要么吃、要么睡、要么玩玩具。她大部分时间都是在睡觉,但是偶尔会睡醒起来用膳。通常,用膳过后她会倍儿精神,开始玩玩具,玩够了就回去睡,然后再睡醒去吃。
用马尔科夫链就能很容易地模拟出我家喵主人的生活状态,因为她会根据之前的状态决定下一步去干嘛。她一般不会醒来后直接去玩玩具,但是吃完东西后,有很大概率去玩一会。这些生活状态转换也可以用图表的形式表现出来:
每个椭圆代表一种生活状态,箭头所指的是下一个生活状态,箭头旁边的数字是指她从一种状态转到另一种状态的概率。我们可以看到,状态转换的概率基本上只根据上一种生活状态。
使用马尔科夫链生成文本
使用马尔科夫链生成文本也是采用了相同的理念,努力找到一个词出现在另一个词后面的概率。为了确认这些转换的可能性,我们用一些例句训练模型。
例如,我们使用下面这些句子训练模型:
我喜欢吃苹果(I like to eat apples)。 你吃橘子(You eat oranges)。
从上面这两个训练句子,我们可以总结出“I”(我),“like”(喜欢)和“eat”(吃)总是以相同的顺序出现,而“you”(你)和“eat”(吃)一直连在一起。但是“orange”(橘子)和“apples”(苹果)出现在词汇“eat”(吃)后面的几率是相等的。下面这个转换图表能更好地显示我上面讲的这一堆:
这两个训练句子能够生成两个新的句子,但是情况不总是这样。我用下面这四个句子训练了另一个模型,结果大不相同:
我朋友做出的树莓派在镇上最好(my friend makes the best raspberry pies in town)。 我觉得苹果派最好(i think apple pies are the best pies)。 史蒂夫觉得苹果做出的电脑在世界上最好(steve thinks apple makes the best computers in the world)。 我有两台电脑,它们不是苹果电脑,因为我既不是史蒂夫也不是大款(I own two computers and they’re not apple because I am not steve or rich)。
用这四个句子训练的模型的转换图表会大得多。
虽然图表和典型的马尔科夫链转换图表看起来大不一样,但两者背后的主要理念是一样的。
从起始节点开始的路径会随机选取接下来的词,一直到终端节点。词语之间相连路径的宽度表示词汇被选取的概率。
虽然只用四个句子训练,上面的模型却能够生成几百个不同的句子。
代码
上面这个文本生成器的代码非常简单,除了Python的随机模块,不需要任何额外的模块或程序库。代码包含两部分,一个用来训练,另一个用来生成。
训练
训练代码构造了我们稍后会用来生成鸡汤句的模型。我用了一个词典作为模型,其包含一些词汇作为关键点,还有一列可能跟随词作为对应值。例如,用上面“我喜欢吃苹果”(‘I like to eat apples’)和“你吃橘子”(You eat oranges)这两个句子训练的模型的词典会是这样:
{'START': ['i', 'you'], 'i': ['like'], 'like': ['to'], 'to': ['eat'], 'you': ['eat'], 'eat': ['apples
我们不需要计算跟随词出现的概率,因为如果它们出现的概率较高,那么它们会在可能跟随词列表中多次出现。例如,如果我们想另外添加训练句子“我们吃苹果”(‘we eat apples’),词汇“苹果”(‘apples’)已经在两个句子中出现在词汇“吃”(eat)后面,那么它出现的概率就会很高。在该模型的词典中,如果在“吃”(eat)列表中出现两次就属于出现概率较高。
{'START': ['i', 'we', 'you'], 'i': ['like'], 'like': ['to'], 'to': ['eat'], 'you': ['eat'], 'we'
另外,在上面的模型词典中还有两个术语:“起始”(START)和“结束”(END),它们表示一个生成的句子的起始词和结束词。
for line in dataset_file:
line = line.lower().split()
for i, word in enumerate(line):
if i == len(line)-1:
model['END'] = model.get('END', []) + [word]
else:
if i == 0:
model['START'] = model.get('START', []) + [word]
model[word] = model.get(word, []) + [line[i+1]]
生成鸡汤句
生成器部分包含一个循环。它首先会选取一个随机的起始词并将其添加至一个列表,然后会在词典中所搜包含潜在跟随词的列表,并随机选取一个列表,将新的选取的词添加至该列表。生成器会一直选择随机的潜在跟随词直到找到结束词,然后会停止循环,输出生成的句子或所谓的“名言”。
(1)Python所有方向的学习路线(新版)
这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
最近我才对这些路线做了一下新的更新,知识体系更全面了。
(2)Python学习视频
包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。
(3)100多个练手项目
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!