全唐诗数据集:https://github.com/todototry/AncientChinesePoemsDB
从郑州大学图书馆网站上爬取下来的全唐诗库,收录了唐代诗人2539人的诗作42863首,共计900卷。
该数据集格式为:每首诗一个txt文件,按照卷进行排序和命名。其中有一些为空白文件,总大小为5MB左右。
中华古诗数据集:https://github.com/jackeyGao/chinese-poetry
唐宋两朝14000名古诗人,55000首唐诗,260000首宋词,用数据分析抽丝剥茧文化内涵。
该数据集格式为:每一千首诗词一个json文件,其中包含平仄、作者、诗句和题目。诗句均为繁体。
[
{
"strains": [
"仄仄仄仄平仄仄,平平仄平○仄仄。",
"平平仄仄平仄平,仄仄平平?仄仄。"
],
"author": "宋太祖",
"paragraphs": [
"欲出未出光辣達,千山萬山如火發。",
"須臾走向天上來,逐却殘星趕却月。"
],
"title": "日詩"
},
...
]
首先,将4万多个古诗词文件合并为一个大txt,每行一首诗。
为了去除空白文件,将文件读入集合后,将集合元素逐行写入txt中。
如果文件过多或过大,为防止内存溢出,可以使用os.path.getsize('./ks_accumulate.csv')
判断文件是否为空,再逐个文件写入大txt。
分析发现部分诗句中含有括号,形如
先生自舞琴。(《三乐达节》)波上人如潘玉儿,掌中花似赵飞燕。(《采莲曲》,以上并见《乐书》)
部分诗句后含有多余文本,形如
弟子已攀桂,先生犹卧云。把得新诗草里论。枯井夜闻邻果落,废巢寒见别禽来。卷六百五十四
用正则表达式对这种文本进行处理,去除括号中的内容和诗句后多余内容。
其中还有少部分问题诗句,如包含多个句号的、有特殊符号的等等。
微官同侍苍龙阙,直谏偏推白马生。。
傩击鼓长笛,瘦鬼染面惟齿白。暗中拽茅鞭,。。倮足朱行戚戚。ń相顾笑声冲庭燎,桃弧射矢时独叫。
卷263_46【九日登高】严维诗家九日怜芳菊,迟客高斋瞰浙江。汉浦浪花摇素壁,西陵树色入秋窗。木奴向熟悬金实,桑落新开泻玉缸。四子醉时争讲德,笑论黄霸屈为邦。
五杂组,四豪客。往复还,阡与陌。不得已,长沙谪。__张荐五杂组,五辛盘。往复还,马上鞍。不得已,左降官。__李崿五杂组,甘咸醋。往复还,乌与兔。不得已,韶光度。__颜真卿五杂组,五色丝。往复还,回文诗。不得已,失喜期。__皎然
进一步分析发现,部分诗句不是以句号结尾的。为了后续任务分析,对感叹号结尾的替换为句号,对没有标点或者多个标点的,去除最后一句,令其句号或问号结尾。但这种语句不多,也可手动处理。
三径何寂寂,主人山上山。亭空檐月在,水落钓矶闲。药院鸡犬静,酒垆苔藓班。知君少机事,当待暮云还
弟兄俱已尽,松柏问何人。闻道茂陵山水好,碧溪流水有桃源。赤城峭壁无人到,丹灶芝田有鹤来。三千宫女露蛾眉,笑煮黄金日月迟。,
浮生共多故,聚宿喜君同。人息时闻磬,灯摇乍有风。霜阶疑水际,夜木似山中。一愿持如意,长来事远公。知
最后从全部诗中提取带有数字的诗句,去除含特殊符号的句子,并将多个句号替换为一个句号。
def MergeTxt(filepath,outfile):
poemset = set()
for parent, dirnames, filenames in os.walk(filepath):
for filepath in filenames:
txtPath = os.path.join(parent, filepath)
f = open(txtPath)
line = f.read()
line = line.replace('!', '。') # 将感叹号替换为句号
line = '。'.join(line.split('。')[:-1])+'。' # 令句子以最后一个句号结尾
poem = re.sub("(.*?)", "", line) # 去除括号里的内容
poem = re.sub("。卷.*", "。", poem) # 去除“卷六百五十四”这种
poemset.add(poem)
print(len(poemset))
k = open(outfile, 'w', encoding='utf-8')
for poem in poemset:
if poem!='':
k.write(poem+"\n")
k.close()
print("merge finished!")
def extractNumberPoemtry(inputfile,outfile):
with open(inputfile,'r',encoding="utf-8") as f1, open(outfile,'w') as f2:
for line in f1:
if '_' in line:
continue
if re.match(".*[一二三四五六七八九十百千万亿].*",line):
f2.write(line.replace('。。','。'))
注意:
文件在close()之前只能读取一次,不能f.read()之后再f.readlines(),或f.readlines()f.read()之后再这样将输出为空。
首先从json中提取诗词,合并为一个大txt,每行一首诗词。
这个数据集全部为繁体字,所以涉及到繁简转换,这里用到的工具是langconv.py
和zh_wiki.py
,只需要把这两个文件下载下来,保存到与代码同一目录下即可。工具放在我的GitHub里,地址见后文。
这个数据集同样有一些特殊字符,如{},“”,□等。
莽莽荒茨岸,回回乱石滩。雨寒收市早,风急泊舟难。{宀禹}县兵犹鬭,乾坤网正宽。慇懃嘱龙剑,莫久卧波澜。
遥泉滴滴度更迟,秋夜霜天入竹扉。明月自随山影去,清风长送白云归。(同前书卷六)-1033-。
云中古城郁嵯峨,塞上行吟麦秀歌。感时伤古今如此,报主怀恩奈老何!。
子瞻词里贬眉汉,鲁直诗中返哺僧。□□□□□□针,血写南山□□□。□□□□□□□,□□□□□来似。不曾□□□□□,□□□□□□□。
花榭香红烟景迷,满庭芳草绿萋萋,金铺闲掩绣帘底。YY紫燕一双娇语碎,翠屏十二晚峰齐,梦魂消散醉空闺。
金陵朱世英官长沙,或有画箕踞而坐者号大着肚。旧有赞颂皆鄙语,朱为题小诗其上以易之。其尾云“但将贮酒三千锺,莫话容卿数百辈。”馀爱其语有味,更作此诗以广其意。
处理方法类似:
# 合并同一个文件夹下多个txt
def MergeTxt(filepath,outfile):
poemset = set()
for parent, dirnames, filenames in os.walk(filepath):
for filepath in filenames:
txtPath = os.path.join(parent, filepath)
with open(txtPath, encoding='utf-8') as f:
s = json.load(f)
for item in s:
sentence = ''.join(item["paragraphs"])
sentence = Converter('zh-hans').convert(sentence) # 繁体转简体
poem = re.sub("{.*?}", "", sentence) # 去除{}里的内容
poem = re.sub("(.*?)", "", poem) # 去除()里的内容
poem = re.sub("-.*?。", "", poem) # 去除“-143-。”这种内容
poem.replace("。。", "。") # 将两个句号替换为一个句号
poemset.add(poem)
print(len(poemset))
k = open(outfile, 'w', encoding='utf-8')
for poem in poemset:
if poem != '':
k.write(poem + "\n")
k.close()
print("merge finished!")
# 提取出带数字的诗
def extractNumberPoemtry(inputfile,outfile):
with open(inputfile,'r',encoding="utf-8") as f1, open(outfile,'w',encoding="utf-8") as f2:
for line in f1:
if '□' in line:
continue
if re.match(".*[一二三四五六七八九十百千万亿].*",line):
f2.write(line.replace('。。', '。').replace('!。', '。').replace('!', '。').replace('Y', '').replace('。”。', '。').replace(':“',',').replace('”','').replace('“',','))
注意:replace如果放在MergeTxt()里,速度会慢,放在extractNumberPoemtry()里更快一些。
最后,将两个数据集中提取的带数字的古诗词合并去重即可。
# 把几个数据集的文本合起来
def mergefile(inputfile1,inputfile2,outfile):
poemset = set()
with open(inputfile1, 'r', encoding="utf-8") as f1, open(inputfile2, 'r', encoding="utf-8") as f2, open(outfile, 'w', encoding="utf-8") as f3:
for line1 in f1:
poemset.add(line1)
for line2 in f2:
poemset.add(line2)
for line in poemset:
f3.write(line)
注意,txt文件可能需要在文本编辑器里手动转成utf-8编码。
这部分为从百度知道等地方找的少部分诗句,需要看是否包含在合并数据集里,如果没有,则手动加入。
with open(mergefile, 'r', encoding="utf-8") as f1,open(finefile,'r',encoding="utf-8") as f2:
forfindlines = f2.readlines()
alllines = f1.read()
print(type(alllines))
for line in forfindlines:
if ''.join(line.split('\n')[0]) not in alllines:
print(''.join(line.split('\n')[0]))
最后得到的带数字的古诗词数据集约为十八万首。
处理脚本和繁简转换工具的全部代码在:https://github.com/vivianLL/PoetryWithNumber