1. 项目背景与核心价值
去年在GitHub上看到一个有趣的91行代码创意赛,要求参赛者用不超过91行代码实现一个有创意的项目。当时我正好在研究自然语言处理中的文本生成技术,于是决定尝试开发一个智能诗词生成器。这个项目的核心价值在于:用极简的代码实现一个能自动生成符合格律要求的古诗词程序,既考验算法设计能力,又兼具文化创意。
传统诗词生成器往往需要复杂的规则引擎和庞大的语料库,而91行的代码限制迫使我必须找到最精炼的实现方式。最终完成的程序不仅能生成五言/七言绝句,还能保持基本的平仄押韵规则。下面我就来拆解这个项目的技术实现和优化思路。
2. 技术方案选型
2.1 为什么选择马尔可夫链
在有限代码量下要实现文本生成,马尔可夫链是最合适的选择。相比深度学习模型需要大量训练数据和复杂结构,马尔可夫链只需要统计词频和转移概率,实现简单但效果不错。具体实现时我采用了二阶马尔可夫模型,即当前词的选择取决于前两个词。
python复制# 示例:构建马尔可夫转移矩阵
def build_markov_chain(corpus):
chain = {}
for i in range(len(corpus)-2):
prefix = (corpus[i], corpus[i+1])
suffix = corpus[i+2]
if prefix not in chain:
chain[prefix] = []
chain[prefix].append(suffix)
return chain
2.2 语料库的精选与处理
使用《全唐诗》作为基础语料库,但做了以下优化处理:
- 仅保留五言和七言诗句
- 对每句诗进行分词处理(按字分割)
- 标注每首诗的韵脚和平仄模式
- 建立单独的诗句开头词库
注意:原始语料需要先进行清洗,去除标点、注释等非诗句内容。这个过程虽然不计入91行代码,但对生成质量至关重要。
3. 核心算法实现
3.1 诗句生成流程
- 随机选择韵脚(从常见韵部中选取)
- 根据诗体(五言/七言)确定平仄模板
- 从开头词库选择符合平仄的首词
- 按照马尔可夫链生成后续词,同时校验平仄
- 末字必须押韵且符合平仄要求
python复制def generate_line(start_words, markov_chain, rhyme, pattern):
word1 = random.choice([w for w in start_words if check_tone(w, pattern[0])])
word2 = random.choice([w for w in markov_chain[(word1,)] if check_tone(w, pattern[1])])
line = [word1, word2]
for i in range(2, len(pattern)-1):
next_words = markov_chain.get((line[-2], line[-1]), [])
valid_words = [w for w in next_words if check_tone(w, pattern[i])]
if not valid_words:
return None # 生成失败
line.append(random.choice(valid_words))
# 处理最后一个字(韵脚)
last_word = random.choice([w for w in markov_chain.get((line[-2], line[-1]), [])
if w.endswith(rhyme) and check_tone(w, pattern[-1])])
line.append(last_word)
return ''.join(line)
3.2 平仄校验算法
实现了一个简化的平仄校验函数,将汉字分为平(1)、仄(0)两类:
python复制def check_tone(word, required_tone):
# 简化版:只检查最后一个字的平仄
last_char = word[-1]
# 这里应有实际的平仄判断逻辑
actual_tone = get_char_tone(last_char)
return actual_tone == required_tone
4. 代码优化技巧
4.1 空间换时间的优化
为了节省代码行数,采用了以下策略:
- 使用字典推导式代替多重循环
- 将多个功能合并到生成函数中
- 用三元运算符简化条件判断
- 预计算并缓存常用数据
4.2 行数压缩示例
原始代码可能这样写:
python复制if condition:
x = func1()
else:
x = func2()
优化为:
python复制x = func1() if condition else func2()
5. 实际生成效果与调优
5.1 典型生成示例
经过调优后,程序可以生成如下诗句:
code复制春风拂柳绿
夜雨润花红
远山含黛色
近水映晴空
虽然不及古人作品精妙,但基本符合五言绝句的格律要求。
5.2 质量提升技巧
- 增加语义约束:对生成的词语组合进行简单语义检查,避免明显不通顺的组合
- 主题引导:允许用户输入关键词,优先选择相关词汇
- 后处理过滤:对生成的多首作品进行评分,只输出最佳结果
6. 常见问题与解决方案
6.1 生成结果不符合格律
问题现象:生成的句子平仄混乱或韵脚不对
解决方法:
- 检查平仄标注数据库是否准确
- 验证马尔可夫链是否包含足够多的有效转移
- 增加生成失败时的重试机制
6.2 代码行数超出限制
问题现象:实现所有功能后代码超过91行
优化策略:
- 将多个相似函数合并为通用函数
- 使用更简洁的语法结构
- 移除非核心功能的装饰性代码
7. 项目扩展思路
虽然比赛限制91行代码,但后续可以考虑以下扩展方向:
- 增加词牌生成:支持生成符合特定词牌(如浣溪沙、水调歌头)的作品
- 引入用户反馈:让用户对生成结果评分,用于改进模型
- 混合生成模式:结合规则引擎和神经网络模型提升质量
这个项目最有趣的地方在于,在严格的代码限制下,如何平衡算法复杂度和生成质量。最终不仅完成了比赛要求,还创造了一个可以实际运行的小工具。对于想学习NLP和Python的朋友,这类微型项目是很好的练手材料。