十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用Python进行《琵琶行》文本分析:从NLP基础到情感计算实战

用Python进行《琵琶行》文本分析:从NLP基础到情感计算实战 最近在整理经典古诗文学习资料时发现很多朋友对白居易的《琵琶行》停留在“背诵全文”的层面对其背后的创作背景、情感内核、艺术手法以及如何将其转化为可分析、可应用的“数据”理解不深。作为一首将音乐描写推向极致的叙事长诗它不仅是文学瑰宝也蕴含着丰富的情感逻辑和叙事结构非常适合作为文本分析、情感计算乃至文化项目开发的绝佳案例。本文将从一个技术实践者的视角重新拆解《琵琶行》。我们将不仅回顾诗文本身更会探讨如何利用现代技术如Python对其进行量化分析例如情感倾向分析、高频词统计、意象挖掘等并尝试构建一个简单的交互式赏析应用。无论你是文学爱好者、中文信息处理的学习者还是想寻找一个有趣编程项目的开发者都能从中获得启发和可直接复用的代码。1. 背景与核心概念为何《琵琶行》是技术分析的优质样本《琵琶行》是唐代诗人白居易创作的一首长篇叙事诗收录于《白氏长庆集》。诗前小序点明了创作背景元和十一年816年白居易被贬为江州司马次年秋夜送客浔阳江头偶遇一位技艺高超却漂泊沦落的琵琶女有感于“同是天涯沦落人”的共鸣创作此诗。从技术分析的角度看这首诗具有以下突出特点使其成为理想的文本分析对象叙事结构完整清晰诗作拥有完整的故事线相遇-演奏-倾诉-感慨段落分明便于进行篇章结构分析和情节划分。情感曲线跌宕起伏情感从“醉不成欢惨将别”的沉闷到听曲时的“如听仙乐耳暂明”的激昂再到了解身世后的“江州司马青衫湿”的悲怆变化显著适合做情感时序分析。语言密度与意象丰富诗中运用了大量比喻“大弦嘈嘈如急雨”、通感“冰泉冷涩弦凝绝”和典故词汇丰富意象“枫叶荻花”、“江月”集中便于进行词频、共现网络和意象分析。音乐描写数据化潜力对琵琶乐声的描绘极其生动通过一系列比喻将抽象的听觉感受转化为具体的视觉和触觉意象这为“音乐文本化”及情感映射提供了绝佳素材。理解这些特点我们就能超越单纯的文学赏析将其视为一个结构化的、富含多维特征的数据集从而应用自然语言处理NLP的基础技术进行探索。2. 环境准备与版本说明为了进行后续的文本分析和小型应用开发我们需要搭建一个Python编程环境。本文的示例将主要使用Jupyter Notebook进行交互式分析并使用几个核心库。基础环境操作系统Windows 10/11, macOS, 或 Linux (如 Ubuntu) 均可。Python版本 3.8。本文示例在 Python 3.9 下测试通过。包管理工具pip(通常随Python安装)。核心Python库及版本我们将使用以下库请通过pip安装。# 在终端或命令提示符中执行以下命令进行安装 pip install jieba0.42.1 # 中文分词工具 pip install wordcloud1.8.2.2 # 词云生成 pip install matplotlib3.5.3 # 绘图库 pip install numpy1.22.4 # 数值计算 pip install snownlp0.12.3 # 中文自然语言处理库用于情感分析 pip install streamlit1.19.0 # 用于构建交互式Web应用可选用于第6节IDE/编辑器推荐VS Code安装 Python 扩展和 Jupyter 扩展。PyCharm专业的 Python IDE。Jupyter Lab直接在浏览器中进行交互式编程。项目结构建议创建一个项目文件夹例如pipaxing_analysis内部结构如下pipaxing_analysis/ │ ├── data/ │ └── pipaxing.txt # 存放《琵琶行》纯文本 │ ├── images/ # 存放生成的图片如词云 │ ├── notebooks/ # 存放Jupyter Notebook分析文件 │ └── 01_text_analysis.ipynb │ ├── scripts/ # 存放可执行的Python脚本 │ ├── 01_word_freq.py │ └── 02_sentiment_analysis.py │ └── app/ # 存放Streamlit应用文件可选 └── app.py《琵琶行》文本准备在data/pipaxing.txt文件中存入诗文全文需去除标题、作者和注释。确保文本编码为UTF-8。3. 核心分析技术与原理拆解在对《琵琶行》进行分析前我们需要理解几个关键的NLP基础概念和对应工具的使用方法。3.1 中文分词从连续字符到有意义的词语中文文本没有像英文那样的天然空格分隔分词是第一步。jieba库是最常用的中文分词工具。原理基于统计模型如隐马尔可夫模型HMM和词典将连续的中文序列切分成一个个独立的词。关键方法jieba.lcut(text): 精确模式返回列表适合文本分析。jieba.lcut_for_search(text): 搜索引擎模式在精确模式基础上对长词再次切分。jieba.add_word(word, freqNone, tagNone): 添加自定义词典对于古诗文中的专有名词如“浔阳江”、“虾蟆陵”特别有用。示例import jieba text 浔阳江头夜送客枫叶荻花秋瑟瑟。 seg_list jieba.lcut(text) print(seg_list) # 输出[浔阳, 江头, 夜, 送客, , 枫叶, 荻花, 秋, 瑟瑟, 。]为什么这么做精确分词是后续词频统计、情感分析的基础。错误的分词会导致“江头”被误认为“江”和“头”影响分析结果。3.2 词频统计与词云生成洞察文本焦点词频统计是了解文本主题最直观的方法。词云则能可视化展示高频词。原理统计分词后每个词语出现的次数并过滤掉无实际意义的“停用词”如“的”、“了”、“和”。关键工具collections.Counter: Python内置模块用于高效计数。wordcloud.WordCloud: 生成词云对象。停用词表需要自己准备或从网上下载一个中文停用词表文件stopwords.txt。注意事项古诗文中的虚词“之”、“乎”、“者”、“也”和某些常用字“人”、“月”可能频率很高但信息量低需要根据分析目标谨慎设置停用词。3.3 情感分析量化情感波动情感分析旨在判断一段文本所表达的情感倾向积极、消极、中性。对于《琵琶行》这种情感强烈的文本可以分析其情感变化。原理SnowNLP库基于朴素贝叶斯模型在已标注的情感语料上训练可以计算文本的情感极性值sentiments范围通常在0到1之间越接近1表示越积极越接近0表示越消极。局限性通用模型对古诗文的适配性可能不佳因为古今汉语表达差异大。但对于宏观的情感趋势分析仍有参考价值。示例from snownlp import SnowNLP s1 SnowNLP(同是天涯沦落人相逢何必曾相识) s2 SnowNLP(满座重闻皆掩泣。座中泣下谁最多江州司马青衫湿。) print(f句子1情感值{s1.sentiments:.3f}) # 可能输出 0.6xx 感慨中带消极 print(f句子2情感值{s2.sentiments:.3f}) # 可能输出 0.1xx 明显消极为什么这么做通过将全诗按句或按联分割计算每部分的情感值并绘制折线图可以直观看到白居易情感随叙事推进的起伏过程。3.4 简单意象分析发现核心意象群意象是古诗的灵魂。我们可以通过寻找特定主题词如自然意象月、水、花音乐意象弦、声、泣的出现位置和上下文来进行分析。原理结合分词结果和自定义的意象词典统计特定意象词的出现频率、分布段落并可以结合其相邻词进行简单分析。方法使用正则表达式或简单的字符串查找与统计。4. 完整实战案例《琵琶行》多维文本分析现在我们将结合上述技术对《琵琶行》进行一次完整的分析。4.1 数据加载与预处理首先读取文本并进行基础清洗。# 文件路径scripts/01_data_preprocess.py import re def load_and_clean_text(filepath): 加载文本并移除数字、标点保留必要句读以分析情感等 with open(filepath, r, encodingutf-8) as f: text f.read() # 移除诗题、作者、注释行假设它们以数字或特殊字符开头 lines text.split(\n) cleaned_lines [line for line in lines if line.strip() and not re.match(r^[0-9【】()]*$, line.strip())] full_text \n.join(cleaned_lines) # 为了分词和词频可以移除所有标点但保留空格和换行 text_for_word_analysis re.sub(r[^\w\s\u4e00-\u9fff], , full_text) # 移除非汉字、非单词字符、非空格 # 为了情感分析保留句读按句分割 sentences_for_sentiment re.split(r[。], full_text) sentences_for_sentiment [s.strip() for s in sentences_for_sentiment if s.strip()] return full_text, text_for_word_analysis, sentences_for_sentiment if __name__ __main__: raw_text, clean_text, sentences load_and_clean_text(../data/pipaxing.txt) print(f原始文本行数示例\n{raw_text[:200]}...) print(f\n清洗后文本用于分词\n{clean_text[:200]}...) print(f\n分割后的句子数{len(sentences)}) print(前5句, sentences[:5])4.2 分词与词频统计加载停用词表进行分词和词频统计。# 文件路径scripts/02_word_frequency.py import jieba from collections import Counter import matplotlib.pyplot as plt # 1. 加载文本 with open(../data/pipaxing.txt, r, encodingutf-8) as f: text f.read() # 简单清洗只保留汉字 chinese_text re.sub(r[^\u4e00-\u9fff], , text) # 2. 添加自定义词典针对古诗文专有名词 jieba.add_word(浔阳江) jieba.add_word(虾蟆陵) jieba.add_word(善才) jieba.add_word(秋娘) jieba.add_word(青衫湿) # 3. 分词 words jieba.lcut(chinese_text) print(f分词总数{len(words)}) print(f前20个分词{words[:20]}) # 4. 加载停用词表 def load_stopwords(filepath): with open(filepath, r, encodingutf-8) as f: stopwords [line.strip() for line in f] return set(stopwords) stopwords load_stopwords(stopwords_cn.txt) # 你需要准备这个文件 # 可以额外添加古诗文常见虚词 extra_stopwords {之, 乎, 者, 也, 矣, 焉, 哉, 曰, 尔, 兮} stopwords.update(extra_stopwords) # 5. 过滤停用词并统计词频 filtered_words [w for w in words if w not in stopwords and len(w) 1] # 通常单字信息量少也过滤掉 word_freq Counter(filtered_words) # 6. 输出最高频的20个词 top_n 20 most_common_words word_freq.most_common(top_n) print(f\n出现频率最高的前{top_n}个词二字及以上) for word, freq in most_common_words: print(f{word}: {freq}) # 7. 简单可视化 words_list, freqs_list zip(*most_common_words) # 解包 plt.figure(figsize(12, 6)) plt.bar(words_list, freqs_list) plt.title(《琵琶行》高频词统计过滤停用词后) plt.xlabel(词语) plt.ylabel(出现次数) plt.xticks(rotation45) plt.tight_layout() plt.savefig(../images/word_freq_bar.png, dpi300) plt.show()运行结果分析你可能会发现“琵琶”、“江州”、“司马”、“天涯”、“沦落”、“月明”等词频率很高这直接呼应了诗的主题和核心情感。4.3 生成词云将词频结果可视化。# 文件路径scripts/03_wordcloud_gen.py from wordcloud import WordCloud import matplotlib.pyplot as plt # 从上一节的 word_freq 继续 # word_freq 是一个 Counter 对象 # 生成词云设置字体路径否则中文乱码 font_path SimHei.ttf # 你需要指定一个系统中文字体路径如‘C:/Windows/Fonts/simhei.ttf’ wc WordCloud( font_pathfont_path, width800, height600, background_colorwhite, max_words100, contour_width1, contour_colorsteelblue ).generate_from_frequencies(word_freq) # 直接从词频生成 plt.figure(figsize(10, 8)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.title(《琵琶行》词云图, fontsize16) plt.tight_layout() plt.savefig(../images/wordcloud.png, dpi300, bbox_inchestight) plt.show()4.4 情感趋势分析按诗句分析全诗情感走向。# 文件路径scripts/04_sentiment_analysis.py from snownlp import SnowNLP import matplotlib.pyplot as plt import numpy as np # 使用 4.1 节中分割好的 sentences 列表 # sentences [...] sentiment_values [] valid_sentences [] for sent in sentences: if len(sent) 2: # 过滤过短的句子 continue try: s SnowNLP(sent) # SnowNLP的情感分析对古文可能不准这里主要看趋势 sentiment_values.append(s.sentiments) valid_sentences.append(sent) except Exception as e: print(f分析句子 {sent} 时出错{e}) continue print(f成功分析了 {len(sentiment_values)} 个句子的情感。) # 绘制情感趋势图 plt.figure(figsize(15, 6)) x np.arange(len(sentiment_values)) plt.plot(x, sentiment_values, markero, linestyle-, linewidth1, markersize4) plt.axhline(y0.5, colorr, linestyle--, alpha0.5, label中性线 (0.5)) plt.title(《琵琶行》句子情感值变化趋势, fontsize14) plt.xlabel(句子序列) plt.ylabel(情感值 (越接近1越积极)) plt.grid(True, alpha0.3) plt.legend() plt.tight_layout() # 在关键位置添加注释需要手动根据诗句内容判断 # 例如找到情感值最低点的句子 min_idx np.argmin(sentiment_values) plt.annotate(f最低点: {valid_sentences[min_idx][:10]}..., xy(min_idx, sentiment_values[min_idx]), xytext(min_idx, sentiment_values[min_idx]-0.1), arrowpropsdict(arrowstyle-), fontsize9) plt.savefig(../images/sentiment_trend.png, dpi300) plt.show() # 输出情感最积极和最消极的几句 print(\n 情感最积极的5句SnowNLP判断) sorted_positive sorted(zip(sentiment_values, valid_sentences), reverseTrue)[:5] for val, sent in sorted_positive: print(f[{val:.3f}] {sent}) print(\n 情感最消极的5句SnowNLP判断) sorted_negative sorted(zip(sentiment_values, valid_sentences))[:5] for val, sent in sorted_negative: print(f[{val:.3f}] {sent})结果解读虽然SnowNLP对古文的判断绝对数值可能不准但趋势图能清晰展示情感低谷如琵琶女自述身世、诗人感慨自身遭遇时和短暂的高峰如初闻琵琶时的惊喜。这印证了诗歌情感结构的起伏。4.5 意象分析示例寻找“月”与“水”我们手动分析诗中的核心意象。# 文件路径scripts/05_imagery_analysis.py import re # 使用原始文本 with open(../data/pipaxing.txt, r, encodingutf-8) as f: full_text f.read() # 定义意象关键词 imagery_dict { 月: [月, 明月, 秋月, 江月, 月明], 水: [水, 江, 河, 海, 流, 浪, 波, 浔阳江, 江水], 音乐: [琵琶, 弦, 声, 音, 乐, 嘈嘈, 切切, 幽咽], 悲情: [泣, 哭, 泪, 湿, 掩泣, 青衫湿, 沦落, 天涯] } # 统计意象词出现次数 for category, keywords in imagery_dict.items(): count 0 found_phrases [] for kw in keywords: # 使用正则表达式查找避免部分匹配 pattern re.compile(kw) matches pattern.findall(full_text) count len(matches) if matches: found_phrases.extend([kw] * len(matches)) # 记录匹配到的词 print(f意象类别【{category}】出现总次数{count}) if found_phrases: # 统计该类别下哪个词出现最多 from collections import Counter freq Counter(found_phrases) print(f 主要构成{freq.most_common(3)}) print(- * 40) # 查找“月”出现的上下文 print(\n ‘月’意象出现的位置及上下文 ) lines full_text.split(\n) for i, line in enumerate(lines): if 月 in line: # 显示该行及前后一行 start max(0, i-1) end min(len(lines), i2) context \n.join(lines[start:end]) print(f第{i1}行附近\n{context}\n{-*60})这个分析能直观展示“月”作为核心意象如何贯穿全诗渲染了孤寂、清冷的氛围。5. 常见问题与排查思路在实践上述分析过程中你可能会遇到以下问题问题现象常见原因解决思路jieba分词结果不准确专有名词被切散默认词典未收录古诗文专有名词使用jieba.add_word()手动添加词汇或加载自定义词典文件。词云图显示乱码方框未指定正确的中文字体路径WordCloud初始化时设置font_path参数指向系统内的中文字体文件如‘SimHei.ttf’。SnowNLP情感分析结果异常所有值接近0.51. 句子过短或不含情感词。2. 模型对古文不适应。1. 过滤掉过短句子。2. 重点观察相对趋势而非绝对数值。3. 考虑使用针对古诗词训练的情感词典如BosonNLP情感词典进行基于规则的分析。停用词过滤后高频词仍包含很多无意义单字停用词表未包含古诗文虚词或过滤时未排除单字1. 扩充停用词表加入“之乎者也矣焉哉”等。2. 在统计词频时通过len(w) 1条件过滤掉单字词。运行脚本时提示ModuleNotFoundError未安装所需Python库或不在正确的虚拟环境中1. 使用pip list检查库是否安装。2. 在终端使用pip install -r requirements.txt一次性安装所有依赖需先创建requirements文件。文本文件读取时编码错误 (UnicodeDecodeError)文件保存的编码不是UTF-81. 用记事本或代码编辑器如VS Code将文件另存为UTF-8编码。2. 尝试使用encodinggbk或encodinggb2312如果文件是GBK编码。6. 最佳实践与工程建议将一次性的分析脚本转化为更稳健、可复用的项目需要考虑以下工程化实践配置与路径管理不要将文件路径硬编码在代码中。使用配置文件如config.yaml或通过命令行参数传递。使用os.path.join()或pathlib.Path来构建路径保证跨平台兼容性。from pathlib import Path DATA_DIR Path(__file__).parent / data text_file DATA_DIR / pipaxing.txt代码模块化将不同的功能封装成函数或类。例如创建TextAnalyzer类包含load_data,clean_text,calculate_word_freq,plot_sentiment等方法。将工具函数如停用词加载放在独立的utils.py模块中。数据持久化将中间分析结果如词频字典、情感值列表保存为JSON或Pickle文件避免每次重新计算。import json with open(word_freq.json, w, encodingutf-8) as f: json.dump(dict(word_freq), f, ensure_asciiFalse, indent2)构建交互式应用可选进阶使用Streamlit可以快速将分析结果构建成一个Web应用方便非技术用户交互探索。# 文件路径app/app.py import streamlit as st import pandas as pd from scripts.word_frequency import analyze_word_freq # 假设你的分析函数已模块化 st.title(《琵琶行》交互式赏析分析仪) uploaded_file st.file_uploader(上传你的《琵琶行》文本文件, type[txt]) if uploaded_file: text uploaded_file.read().decode(utf-8) if st.button(开始分析): word_freq_df analyze_word_freq(text) # 返回一个DataFrame st.subheader(高频词表) st.dataframe(word_freq_df.head(20)) # 可以继续添加词云、情感图等组件分析结果的批判性审视始终记住工具是辅助。SnowNLP的情感分析结果需要结合诗歌背景人工校验。词频统计的高频词需要结合停用词表的设计来解读避免过度解读。最好的分析是“人文解读”与“数据验证”相结合。扩展方向更高级的NLP模型尝试使用BERT、RoBERTa等预训练模型进行更深度的情感分析或文本分类需微调。关系图谱利用NetworkX库基于词共现关系绘制诗中人物、地点、意象之间的关系网络图。风格对比分析白居易其他诗作如《长恨歌》与《琵琶行》进行用词、情感风格的对比。通过这样一个从文本处理到可视化再到简单应用构建的完整流程我们不仅重温了《琵琶行》的文学魅力更实践了一套可复用的文本数据分析方法论。这不仅能用于古诗文也能迁移到现代文本的分析中为你的数据分析或人文计算项目打下基础。
返回列表