你是否考虑过让电脑依照既定规则自主构建语句?今天,我将为大家详细讲解如何构建一个句子生成系统。
设定语法规则
simple_grammar = """
sentence => noun_phrase verb_phrase
noun_phrase => Article Adj* noun
Adj* => null | Adj Adj*
verb_phrase => verb noun_phrase
Article => 一个 | 这个
noun => 女人 | 篮球 | 桌子 | 小猫
verb => 看着 | 坐在 | 听着 | 看见
Adj => 蓝色的 | 好看的 | 小小的
"""
在开始生成句子之前,必须先向机器说明生成规则。例如,我们可以制定一个简单的语法规则,并将其表示为语法树。这里有一些基本的规则设定,比如“=>”符号表示由多个部分构成;“Adj => 蓝色的 | 好看的 | 小小的”说明Adj有三种可能的选择。这些规则构成了后续生成句子的基础。只有设定好这些规则,计算机才能理解如何构建句子。
规则解析准备
通过审视先前设定的语法规则,我们可以辨识出两种类型的词汇。左侧的词汇具备进一步发展的潜力,而右侧的词汇则不具备这一特性。以形容词(adj)为例,我们接下来需要编写代码来解析这些语法规则。这些词汇在构建句子的过程中扮演着不同的角色,认识它们的特性是掌握解析规则的关键环节。
编写 adj 代码
adj_grammar = """
Adj* => null | Adj Adj*
Adj => 蓝色的 | 好看的 | 小小的
"""
首先,我们需要针对 adj 部分的语法编写代码。adj 语法遵循特定的格式,我们将依照这一格式进行处理。我们需要将字符串形式的语法规则转换成字典格式,这样做有利于计算机的识别与处理。比如,当我们解析 adj 的规则时,会得到特定的输出结果,这有助于更直观地展现规则的结构。
# 解析语法
def create_grammar(grammar_str, split = '=>', line_split = 'n'):
grammar = {}
for line in grammar_str.split(line_split):
if not line.strip():
continue # 跳过空行
else:
exp, stmt = line.split(split)
grammar[exp.strip()] = [s.split() for s in stmt.split('|')]
return grammar
完整规则解析
完成adj规则的字典解析后,我们还需将全部语法规则转换成字典格式。这样做可以让计算机全面掌握语法结构,为后续句子的生成提供准确的依据。一旦所有规则都顺利转换成字典形式,计算机便能够依据这些规则进行句子的组合与生成。
句子生成代码
现在我们已掌握了解析语法规则的能力,因此下一步是编写代码,使它能依据这些规则自动构建句子。借助这段代码,我们可以随机生成句子,以此来验证代码功能的正确性。这一过程揭示了语法规则如何被转化为实际的句子。每个生成的句子都体现了规则的具体应用。
# 生成句子
def generate(gram, target):
![图片[1]-通过Python利用预设语法规则和单词自动生成句子的方法介绍-东山笔记](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20582%20470'%3E%3C/svg%3E)
if target not in gram:
return target # means target is a terminal expression
# target in gram 意味着target是可以继续拓展下去的
else:
expaned = [generate(gram, t) for t in random.choice(gram[target])]
return ''.join([e if e!='/n' else 'n' for e in expaned if e != 'null'])
多语法效果展示
我们尝试引入两种新的语法规则,目的是让“人类”和“接待员”各自随机创造出五个句子。观察生成的句子,我们可以清楚地看到,计算机已经能够根据我们设定的语法规则自动生成句子了。多种语法规则的应用体现了句子生成器的多样性和可扩展性。不同的语法规则能够产生丰富多样的句子。
# 在西部世界里
# 一个”人类“的语言可以定义为:
human = """
human = 自己 寻找 活动
自己 = 我 | 俺 | 我们
寻找 = 找找 | 想找点
活动 = 乐子 | 玩的
"""
# 一个“接待员”的语言可以定义为
host = """
host = 寒暄 报数 询问 业务相关 结尾
报数 = 我是 数字 号 ,
数字 = 单个数字 | 数字 单个数字
单个数字 = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
寒暄 = 称谓 打招呼 | 打招呼
称谓 = 人称 ,
人称 = 先生 | 女士 | 小朋友
打招呼 = 你好 | 您好
询问 = 请问你要 | 您需要
业务相关 = 玩玩 具体业务
玩玩 = null
具体业务 = 喝酒 | 打牌 | 打猎 | 赌博
结尾 = 吗?
"""
阅读完这篇文章,你是否产生了想要自己设计和制作一个句子生成器的想法?然而,面对众多生成的句子,我们又该如何辨别哪一句更贴近人类的语言习惯?不妨在评论区留下你的见解,同时,也欢迎你为这篇文章点赞和转发。