背景概述

诗歌是构筑唐代文化史高峰的一座巨大丰碑,唐代的诗歌空前繁荣,达到完美的艺术境界,成为大唐王朝时代的文化标志。本人热爱唐诗,希望从文本挖掘的角度去探索全唐诗,挑战不同场景下文本处理和分析的过程,锤炼自己的数据分析技能;结合数据之美和诗歌之雅,分享诗词之美,感受诗词之趣。

分析框架

数据获取

《全唐诗》是在网上下载的免费文本数据,全文总共4.8W+首诗,文件中每一行为一首诗,包括编号、题目、作者、诗歌内容。

全唐诗字词频率分析

用Python统计分析全唐诗的字频、词频和词性,并使用Tableau进行可视化展示。其中字频分析维度包括全唐诗中的全局高频词、季节、植物、动物和颜色等;词频分析为全局高频词语,词性分析维度包括全唐诗全局词性分析、地名词性和时间词性等。

def cut_qts_to_words(qts_file,saved_words_file):

save_dir = os.path.dirname((saved_words_file))

dumped_file=os.path.join(save_dir,"qts_words_stat_result.pkl")

char_counter = Counter() # 字频统计

author_counter = Counter() # 每个作者的写诗篇数

vocab = set() # 词汇库

word_counter = Counter() # 词频统计

genre_counter = defaultdict(Counter) # 针对每个词性的Counter

lex_analyzer=thulac.thulac() #分词器

with open(qts_file,'r',encoding='utf-8') as f:

for line in f:

text_segs=line.split()

#作者诗篇统计

author=text_segs[2]

author_counter[author]+=1

#字频统计

poem=text_segs[-1]

valid_char_list=[c for c in poem if '\u4e00' <= c <= '\u9fff' or c == ',' or c == '。']

for char in valid_char_list:

char_counter[char]+=1

#词汇库统计、词频统计、词性统计

regularized_poem=''.join(valid_char_list)

word_gener_pairs=lex_analyzer.cut(regularized_poem)

for word,gener in word_gener_pairs:

vocab.add(word)

word_counter[word]+=1

genre_counter[gener][word]+=1

#存储结果

dumped_data=[char_counter, author_counter, vocab, word_counter, genre_counter]

with open(dumped_file, 'wb') as f:

pickle.dump(dumped_data, f)

return char_counter, author_counter, word_counter,genre_counter

f_qts_words=open("qts_words_stat_result.pkl","rb")

char_counter, author_counter,vocab, word_counter,genre_counter=pickle.load(f_qts_words)

#1、字频分析——全局高频字

stopwords=[",","。","不","而","第","何","乎","乃","其","且","若","于","与","也","则","者","之","无","有","来","一",

"中","时","上","为","自","如","此","去","下","得","多","是","子","三","已"]

for w in stopwords:

del char_counter[w]#删除虚词

counter(char_counter.most_common())

#7、词性分析——地名词排名

counter(genre_counter['ns'].most_common(100))字频分析——全局高频字从该词云图可以看出,在全唐诗中“人”字排行第一,说明唐诗很好的秉承了“以人为本”的中华文化。李白的《将进酒》:“人生得意须尽欢,莫使金樽空对月”;王维《鸟鸣涧》:“人闲桂花落,夜静春山空”;柳宗元的《江雪》:“千山鸟飞绝,万径人踪灭”;

而后续的“山”、“风” 、“日” 、“月” 、“天”、“云”、“花”等都是在写景的诗句里经常出现的意象。字频分析——四季分析“春”字出现了11046次,排行榜首,著名的有白居易的《钱塘湖春行》:“孤山寺北贾亭西,水面初平云脚低。几处早莺争暖树,谁家新燕啄春泥。乱花渐欲迷人眼,浅草才能没马蹄。最爱湖东行不足,绿杨阴里白沙堤。”;杜甫的《春夜喜雨》:“好雨知时节,当春乃发生。随风潜入夜,润物细无声。野径云俱黑,江船火独明。晓看红湿处,花重锦官城。”

“秋”列第2位,有刘禹锡的《秋词》:“自古逢秋悲寂寥,我言秋日胜春朝。晴空一鹤排云上,便引诗情到碧霄。”;杜牧的《寄扬州韩绰判官》:“青山隐隐水迢迢,秋尽江南草未凋。二十四桥明月夜,玉人何处教吹箫?”

由此可以看出,在唐诗里,“伤春悲秋”是常见的诗歌题材。字频分析——植物分析“松”排在第一位,《论语》有“岁寒,然后知松柏之后凋也。”指在秋冬最寒冷的时节,只有松柏不改本色。由于这种自然属性,松柏历来成为古人赞美的对象。古人写诗使用松柏是对自己坚定志向的表达。比如李白的“南轩有孤松,柯叶自绵幂。清风无闲时,潇洒终日夕。”;刘长卿的“泠泠七丝上,静听松风寒”

“竹”紧排第二,诗人用竹来言志,象征着高风亮节的气节、谦虚的品格、坚忍不拔的毅力、气冲云霄的志气。例如刘禹锡的《庭竹》“露涤铅粉节,风摇青玉枝。依依似君子,无地不相依。”暗喻自己似和竹子一样的君子,无论到那里都可以清高自立。字频分析——动物分析“马”名列前茅,说明马在华夏文化中是一种神奇的动物,被赋予许多象征和寓意。在古代,马是人类最为重要的生活和生产伙伴,因此古人常用“千里马”来比喻杰出的人才,例如韩愈的《马说》中“世有伯乐,然后有千里马。千里马常有,而伯乐不常有。”;也常用马来象征显赫的功勋,例如杜甫的《房兵曹胡马诗》:“胡马大宛名,锋棱瘦骨成。竹批双耳峻,风入四蹄轻。所向无空阔,真堪托死生。骁腾有如此,万里可横行。”,正因为马具有如此重要的地位,所以文人墨客一直对其情有独钟。字频分析——颜色分析通过古语中对主颜色称谓的合并:

红色系:红、丹、朱、赤、绛等

黑色系:暗、玄、乌、冥、墨等

绿色系:绿、青、碧、翠、苍等

白色系:白、素、皎、皓等

以上饼图可以看出,绿色系的占比居多,“绿”“碧”“苍”“翠”“青”等大都用于写景,“绿树”、“碧水”、“苍松”、“翠柳”等,这些高频字从侧面反映出全唐诗中描写景物、寄情山水的诗句占比很大,透露出平静、清新、闲适和希望之感。词频分析——全局高频词从高频词可以看出,“何处”占居第一位,杜甫《蜀相》中有“丞相祠堂何处寻,锦官城外柏森森。”,杜牧《寄扬州韩绰判官》中有“二十四桥明月夜,玉人何处教吹箫。”这种长问的句式透露出诗人强烈的伤感和痛惜之情。而排名靠前的春风、人间、明月、秋风、白云、青山都为意象词语,从侧面反映出全唐诗中描写景物、寄情山水的诗句占比很大。词性分析——全局分析上图中,不同颜色代表不同词性,圆圈大小代表字词数量,可以看出,动词、副词、名词占比较大,副词“不”字为最大高频字。词性分析——地名分析江南风景优美,令诗人难忘,比如白居易说:“不道江南春不好,年年衰病减心情”,所以江南能位居第一,并不奇怪。

第二的长安是唐代的都城,盛唐时的长安有繁华盛世的气概,有举世瞩目的风采,诗人心中对长安同样也有说不清的爱。例如杜牧的“长安回望绣成堆,山顶千门次第开。一骑红尘妃子笑,无人知是荔枝来”

其他如洛阳,黄河,长江,洞庭,长沙,江城等都是游玩的好地方,“沧洲”在古文献中借指隐者居住的地方,也是一个高频地点。词性分析——时间分析前五名都是现在的意思,说明古人也都非常珍惜当下,关心当代时事和紧跟时代发展,表现出普遍的英雄气概和进取精神。例如崔护的《题都城南庄》“去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。”;刘禹锡的《酬乐天扬州初逢席上见赠》“沉舟侧畔千帆过,病树前头万木春。今日听君歌一曲,暂凭杯酒长精神。”

诗人社交关系分析

前段时间有个话题“很重视的友情对方却不看重,是一种怎样的体验?”讨论得很火,有网友给出以下回答 :

于是,想通过分析唐代诗人社交关系来解读诗人之间的朋友圈。

分析思路:利用CBDB数据库查找诗人的别名,得到诗人和别名列表字典。(eg杜甫:子美、杜二、杜工部;王维:王右丞、摩诘)

搜索诗人之间的引用关系。

引用关系的可视化(工具:Gephis)

#获取全唐诗列表qts_list【author,title,poem】、诗人列表authors_set

def read_qts(file_name):

qts_list = []

authors_set = set()

#逐行读取诗歌

with open(file_name,'r',encoding='utf-8') as f:

for line in f:

text_segs=line.split()

title=text_segs[1]

author = text_segs[2]

poem = text_segs[-1]

authors_set.add(author)

#除去非汉字字符

valid_char_list = [c for c in poem if '\u4e00' <= c <= '\u9fff' or c == ',' or c == '。']

validated_poem = ''.join(valid_char_list)

# 按照作者、标题、内容的格式保存

qts_list.append((author, title, validated_poem))

return qts_list,authors_set

#根据诗人列表从CBDB数据库中获取诗人们的别名

#db_file:CBDB数据库

#authors_set:诗人列表

def get_alter_names_from_CBDB(db_file,authors_set,manual_defuzzy_authors_id):

tang_begin_year = 618 # 唐朝建立年份

tang_end_year = 907 # 唐朝灭亡年份

manual_defuzzy_authors=set(manual_defuzzy_authors_id.keys())

authors_not_in_CBDB = set()

fuzzy_authors = set()

fuzzy_authors_details = {}

alter_names_dict = defaultdict(set)

#CDBD数据库需要通过sqlite3进行连接

conn=sqlite3.connect(db_file)

cursor=conn.cursor()

for author in authors_set:

# 如果作者在手动排查集合中,直接使用集合中的id

if author in manual_defuzzy_authors:

author_id=manual_defuzzy_authors_id[author]

else:

author_pattern='%'+author

#1、先从“BIOG_MAIN”表中通过诗人本名查找诗人id,以及出生和死亡时间(后面用此时间匹配朝代时间,排除重名现象)

cursor.execute('select c_personid, c_birthyear, c_deathyear FROM BIOG_MAIN WHERE c_name_chn LIKE?',(author_pattern,))

person_info_list=cursor.fetchall()

#获取诗人id,需排除重名现象

candidate_author_ids=[]

for person_id, birth_year, death_year in person_info_list:

if birth_year and death_year: # 生卒年俱全

if birth_year < tang_end_year and death_year > tang_begin_year:

# 一旦找到一个生卒年俱全且和唐朝有交集的,就不看其他的了

candidate_author_ids = [person_id]

break

elif birth_year or death_year: # 只有生年或者卒年

year = birth_year if birth_year else death_year

if year > tang_begin_year and year < tang_end_year:

candidate_author_ids.append(person_id)

# 候选名单为空或者多于一个人的候选名单都不要

if not candidate_author_ids:

authors_not_in_CBDB.add(author)

continue

elif len(candidate_author_ids)>1:

fuzzy_authors.add(author)

fuzzy_authors_details[author]=candidate_author_ids

continue

author_id=candidate_author_ids[0]

#2、根据author_id从“ALTNAME_DATA”中找出诗人别名

cursor.execute('select c_alt_name_chn FROM ALTNAME_DATA WHERE c_personid=?',(author_id,))

alter_names_list = cursor.fetchall()

for alt_name in alter_names_list:

if len(alt_name[0]) > 1:

alter_names_dict[author].add(alt_name[0])

conn.close()

# 经过CBDB过滤过的诗人,接下来只分析这些人之间的关系

authors_filtered_by_CBDB = authors_set - authors_not_in_CBDB - fuzzy_authors

return alter_names_dict,authors_filtered_by_CBDB

#将诗的标题正文、CBDB的诗人作者、诗人的本名和别名都存储到“alternames.pkl”文件中

def get_alter_names(qts_file,cbdb_file,save_dir):

alter_names_file=os.path.join(save_dir,"alternames.pkl")

# 读取全唐诗,并存储诗歌内容和作者

qts_list,authors_set=read_qts(qts_file)

#删除部分作者

authors_set -=manual_deleted_authors

#从CBDB中查找作者的别称

alter_names_dict,authors_filtered_by_CBDB=get_alter_names_from_CBDB(cbdb_file,authors_set,manual_defuzzy_authors_id)

#删除不要的别称

for k,v in mannual_deleted_alter_names.items():

alter_names_dict[k] -= v

#补充CBDB中缺少的别称

for k,v in mannual_added_alter_names.items():

alter_names_dict[k] |=v

#存储结果

with open(alter_names_file, 'wb') as f:

pickle.dump([qts_list, authors_filtered_by_CBDB, alter_names_dict], f)

return qts_list, authors_filtered_by_CBDB, alter_names_dict

def get_refer_relations(qts_list, authors_filtered_by_CBDB, alter_names_dict, save_dir):

reference_relations_file = os.path.join(save_dir, 'reference_relations.pkl')

reference_relations_counter=Counter()

reference_relations_text=defaultdict(list)

for name in authors_filtered_by_CBDB:

for author,title,text in qts_list:

if author not in authors_filtered_by_CBDB:

continue

poem = title + ' ' + text

if poem.find(name) != -1:

reference_relations_counter[(author,name)] += 1

reference_relations_text[(author,name)].append(title)

continue

alter_names=alter_names_dict[name]

for alter_name in alter_names:

if poem.find(alter_name) != -1:

reference_relations_counter[(author,name)] += 1

reference_relations_text[(author,name)].append(title)

break

with open(reference_relations_file,"wb") as f:

pickle.dump([reference_relations_counter, reference_relations_text],f)

由此得到诗人之间引用次数表,如下表:

根据此表,使用Gephis工具来绘制诗人之间的网络关系图,如下图:图中节点大小表示诗人受欢迎程度,节点颜色表示诗人朋友圈大小,边的粗细程度则表示了诗人们之间社交关系的强弱。

图中清晰地显示除了唐朝诗人的两个大型朋友圈:杜甫-李白朋友圈、白居易-元稹朋友圈,反映出他们分别是盛唐和中唐两个时期的核心诗人。

全唐诗中排名第一的好基友是陆龟蒙和皮日休,文学史上通常将两者合称为“皮陆”;排名第二的是白居易和元稹。二人在文学史上被合称为“元白”。

从排名前100引用关系来看,白居易绝对是唐朝诗人朋友圈中的明星,是大V中的大V

部分代码参考:前进四先生

python作者的诗_《全唐诗》Python文本分析相关推荐

  1. python作者的诗_用python和她一起唐诗宋词

    在一个夜黑风高的夜晚.在我拨了无数个无法接通后,我接到了一个未知男人的来电.他告诉我........... "别来骚扰我了,我教你还不行么" 在不求人这条路上我走了好久,痛定思痛后 ...

  2. python程序写诗_用Python作诗,生活仍有诗和远方

    原标题:用Python作诗,生活仍有诗和远方 报 名 来源:TheodoreXu链接: https://segmentfault.com/a/1190000013154329 常听说,现在的代码,就和 ...

  3. 用python画风景诗_关于Python turtle 绘图

    python2.6版本中后引入的一个简单的绘图工具,叫做海龟绘图(Turtle Graphics),turtle库是python的内部库,使用导入即可 import turtle 先说明一下turtl ...

  4. python程序写诗_将Python诗歌与D结合起来

    在与docker一起使用poetry时,需要记住以下几点. 安装 安装poetry的正式方法是通过:curl -sSL https://raw.githubusercontent.com/sdispa ...

  5. python字符串去掉空行_从python中的字符串中删除空格

    python字符串去掉空行 如何在python中删除字符串中的空格 (How to remove whitespaces in a string in python) str.lstrip()str. ...

  6. python作者龟叔_龟叔和他的Python

    经过了漫长的旅程,终于要看到主角Python了.Python是现在非常非常流行的编程语言,在我们能看到的大部分编程语言排行榜中,Python都能在前三甲中拥有一席之地 ,并且发展势头非常之猛,可以这么 ...

  7. python编辑器和终端_从python curses程序运行终端文本编辑器

    我想在python curses程序中使用外部终端文本编辑器和寻呼机.我使用子进程库.在大多数情况下,它工作得很好,除了当我退出文本编辑器时(与nemo和vi相同),我不能再次使光标不可见.另外,在调 ...

  8. python 写txt 换行_写入txt文本的内容为什么没换行效果?

    PHP把内容写入文件,并每次自动换行 weixin_4089680029712018-07-20 Java文本追加.换行.输出到TXT u01422837514692015-12-15 Android ...

  9. python词频统计西游记_使用python简单实现《西游记》文本分析,通过词频对比探索西游记的主角...

    使用jieba模块简单统计西游记词频,并进行同义词处理(如合并 行者,大圣为悟空)及排除词处理. [code]import jieba with open('西游记.txt','r',encoding ...

最新文章

  1. 错误时自动退出bash shell脚本[重复]
  2. 画Series的散点图
  3. DefaultSingletonBeanRegistry 的registerDependentBean()方法对属性注入
  4. 程序员应该了解的几个接单平台,私活,码农!
  5. vs连接oracle数据库报错,用VS连接oracle数据库时ORA-12504错误
  6. Linux APT VIM 的一些指令
  7. 对数线性模型:逻辑斯谛回归和最大熵模型
  8. Python爬虫实践(二) -- 爬虫进阶:爬取数据处理、数据库存储
  9. 【Flutter】IOS打包
  10. 2022新轻量级PHP解密在线工具源码V1.2版
  11. 2048游戏(C语言)
  12. BUUCTF Crypto BabyRSA
  13. LaTeX:overleaf latex 中文生僻字处理
  14. 【Python】输入一个整数,输出这个整数的所有数字和,例如输入256,则输出13
  15. Apollo分布式配置中心 - 服务中间件
  16. 联想小新padpro12.6 #Q706F 解锁输入TWRP教程
  17. CCNP Switching (300-115) Cert Prep: 1 Layer 2 Technologies CCNP交换(300-115)证书准备:1层2技术 Lynda课程中文字幕
  18. AndroidX了解一下
  19. Python 读文件错误: invalid start byte / illegal multibyte sequence
  20. 统信UOS如何给PPT嵌入字体

热门文章

  1. /opt/hbase/conf 中不能启动hbase_北京现代伊兰特不能启动
  2. 达人评测 i7 13700h和i7 13620h选哪个 酷睿i713700h和13620h对比
  3. VASP学习笔记--简单的VASP运行实例:CrI3做非磁的优化
  4. APK安装包如何安装到安卓手机上
  5. 技术问答站点与论坛为什么半死不活
  6. Vue中使用wangEditor实现自定义上传图片和视频
  7. 小飞鱼通达二开 通过开发工作流接口集成ERP系统(图文)
  8. android指南针功能,轻松实现Android指南针功能
  9. 基因组测序为什么没完没了?
  10. Delphi医保支付【支持重庆,湖南,湖北,河南,江苏,黑龙江,吉林等医保接口】