用nltk模仿海子写中文现代诗

前言

仅仅写英文诗还不够,我们又把主意打到了中文诗头上。不过要写古体诗还有一些困难,我们先尝试一下现代诗。

写中文现代诗的代码与英文诗类似,区别主要在语料的处理上,建议先看如何写英文诗

开始编程

寻找素材

同样的,要学海子写诗,第一步就是找到足够多海子本人写的诗。而内网的资源同样没眼看,我们还是把视线投向外网,这个网站上的资源还算不错,纯净度远高于我在一些网盘上找到的资源。
在这里插入图片描述

处理语料

大致的处理流程与英文语料类似,不过都是筛去不相干的一些“杂质”,再对文本进行划分。

去除杂质包括去除英文、阿拉伯数字以及一些带有符号的非诗句,用几个函数就可以判断:

fuhao=[':','-','(',')','、','—','(',')']
def is_English(ch):
    return (ch>=u'\u0041' and ch<=u'\u005a') or (ch>= u'\u0061' and ch<=u'\u007a')
def is_number(ch):
    return ch >= u'\u0030' and ch<=u'\u0039'
def check(s):
    for ch in s:
        if ch in fuhao or is_English(ch) or is_number(ch):
            return False
    return True

不过中文语料与英文语料最大的不同在于英文语料天然有空格作为分隔符,划分要容易得多;而中文却没有这种好事,要划分不同的成分困难得多。但是Python那是真的强的一批,jieba库直接解决这个问题:
在这里插入图片描述
借助jieba的帮助,我们就可以把文本划分为像英文诗那样的“单词”形式。

import jieba
import nltk
import random

fuhao=[':','-','(',')','、','—','(',')']
sentences=[]
def is_English(ch):
    return (ch>=u'\u0041' and ch<=u'\u005a') or (ch>= u'\u0061' and ch<=u'\u007a')
def is_number(ch):
    return ch >= u'\u0030' and ch<=u'\u0039'
def check(s):
    for ch in s:
        if ch in fuhao or is_English(ch) or is_number(ch):
            return False
    return True
with open('hz.txt','r',encoding='utf8') as f:
    for line in f.readlines():
        line=line.strip()
        if len(line)>3 and len(line)<30 and check(line):
            sentences.append(jieba.lcut(line))

一些类似的步骤

说实话,几乎一摸一样……

最后写诗的部分多加了一点随机,毕竟写的不一定是十四行诗嘛~

voc=set()
for line in sentences:
    for word in line:
        voc.add(word)
voc.add('<s>')
voc.add('</s>')
voc=list(voc)
n=3
all_ngrams=[]
for line in sentences:
    paddedline=nltk.lm.preprocessing.pad_both_ends(line,n)
    ngrams=list(nltk.ngrams(paddedline,n))
    all_ngrams.append(ngrams)
lm=nltk.lm.MLE(n)
lm.fit(all_ngrams,voc)
sonnet=[]
text_seed=['<s>']*(n-1)
while len(sonnet)<random.randint(5,20):
    while True:
        try:
            line=lm.generate(random.randint(8,15),text_seed=text_seed)
        except ValueError:
            continue
        else:
            line=[word for word in line if word not in['<s>','</s>']]
            sonnet.append("".join(line))
            break
print("\n".join(sonnet))

运行结果

问题与英文诗类似,每句单独生成,缺乏连贯,有时候还不完整。

而且由于海子的诗本身比较少,学习后多样化不足,会出现许多海子的原句……好多诗我觉得随机生成的不错,结果是人家海子早就写过的……

英文诗可能也有这个问题,不过我对英文和莎士比亚的十四行诗不够敏感,所以没有发觉。
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值