文章目录
- 前言
- 开始编程
- 寻找素材
- 处理语料
- 一些类似的步骤
- 运行结果
前言
仅仅写英文诗还不够,我们又把主意打到了中文诗头上。不过要写古体诗还有一些困难,我们先尝试一下现代诗。
写中文现代诗的代码与英文诗类似,区别主要在语料的处理上,建议先看如何写英文诗。
开始编程
寻找素材
同样的,要学海子写诗,第一步就是找到足够多海子本人写的诗。而内网的资源同样没眼看,我们还是把视线投向外网,这个网站上的资源还算不错,纯净度远高于我在一些网盘上找到的资源。
处理语料
大致的处理流程与英文语料类似,不过都是筛去不相干的一些“杂质”,再对文本进行划分。
去除杂质包括去除英文、阿拉伯数字以及一些带有符号的非诗句,用几个函数就可以判断:
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 Falsereturn True
不过中文语料与英文语料最大的不同在于英文语料天然有空格作为分隔符,划分要容易得多;而中文却没有这种好事,要划分不同的成分困难得多。但是Python那是真的强的一批,jieba
库直接解决这个问题:
借助jieba
的帮助,我们就可以把文本划分为像英文诗那样的“单词”形式。
import jieba
import nltk
import randomfuhao=[':','-','(',')','、','—','(',')']
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 Falsereturn 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:continueelse:line=[word for word in line if word not in['<s>','</s>']]sonnet.append("".join(line))break
print("\n".join(sonnet))
运行结果
问题与英文诗类似,每句单独生成,缺乏连贯,有时候还不完整。
而且由于海子的诗本身比较少,学习后多样化不足,会出现许多海子的原句……好多诗我觉得随机生成的不错,结果是人家海子早就写过的……
英文诗可能也有这个问题,不过我对英文和莎士比亚的十四行诗不够敏感,所以没有发觉。