从莎士比亚到数据可视化:《哈姆雷特》词频统计全流程解析(含停用词处理技巧)
当“生存还是毁灭”的经典独白,遇上现代数据科学的冰冷算法,会碰撞出怎样的火花?这不仅仅是文学爱好者的遐想,更是每一位希望提升文本处理技能的中级开发者可以亲身实践的绝佳项目。通过分析《哈姆雷特》这样的文学巨著,我们不仅能重温经典,更能将抽象的文本分析技术——从数据清洗、词频统计到生成直观的词云图——置于一个具体、有趣且富含意义的场景中。这篇文章,就是为你准备的深度实操指南。我们将抛开简单的代码复制,深入探讨每一个步骤背后的“为什么”和“怎么做”,分享那些在教科书和速成教程里很少提及的细节与技巧,尤其是如何聪明地处理停用词,让你的分析结果从“一堆数据”变成“有洞察的发现”。无论你是想丰富自己的数据科学作品集,还是希望将文本分析能力应用到更广泛的业务场景,这次从莎士比亚戏剧到数据可视化的旅程,都将为你提供扎实的实践经验和全新的思考视角。
1. 项目起点:获取与理解你的文本数据
在敲下第一行代码之前,我们需要像侦探一样,先了解我们的“案发现场”——也就是《哈姆雷特》的原始文本。直接从可靠的来源获取原始数据是数据分析的第一步,它避免了因版本差异导致的统计偏差。通常,我们可以从古登堡计划(Project Gutenberg)等权威的公共数字图书馆获取经典文学作品的纯文本版本。
拿到 hamlet.txt 文件后,别急着运行代码。先用文本编辑器打开它,快速浏览一下。你会发现,除了戏剧台词,文件可能还包含一些“元数据”,比如项目信息、版权声明、章节标题等。例如:
The Tragedy of Hamlet, Prince of Denmark
by William Shakespeare
ACT I. Scene I. Elsinore. A platform before the castle.
...
这些非台词部分如果不经处理就直接进行词频统计,会引入大量噪音。比如“ACT”、“Scene”等词会毫无意义地占据高频位置。因此,数据清洗的第一步往往是基于领域知识的筛选。对于文学分析,我们可能只关心台词部分。这就引出了一个比简单替换标点更高级的技巧:基于正则表达式的模式匹配与截取。
提示:在处理任何外部数据源时,花10分钟进行人工审查和数据探索(Data Exploration),其价值远超事后花费数小时去调试奇怪的统计结果。
下面是一个更健壮的文本读取与初步清洗函数示例,它考虑了编码问题,并提供了选择性读取的接口:
import re
def load_and_inspect_text(filepath, encoding='utf-8', start_marker='ACT I', end_marker='THE END'):
"""
加载文本文件,并允许根据标记截取核心内容。
"""
try:
with open(filepath, 'r', encoding=encoding) as f:
full_text = f.read()
except UnicodeDecodeError:
# 尝试其他常见编码
with open(filepath, 'r', encoding='latin-1') as f:
full_text = f.read()
# 打印前500字符,快速了解结构
print("---文本前500字符预览---")
print(full_text[:500])
print("-" * 30)
# 如果提供了开始和结束标记,则截取中间部分
if start_marker and end_marker and start_marker in full_text and end_marker in full_text:
start_index = full_text.find(start_marker)
end_index = full_text.find(end_marker) + len(end_marker)
core_text = full_text[start_index:end_index]
print(f"已根据标记截取核心文本,长度从{len(full_text)}缩减至{len(core_text)}字符。")
return core_text
else:
print("未找到标记或未提供标记,返回全文。")
return full_text
# 使用示例
raw_text = load_and_inspect_text('hamlet.txt', start_marker='ACT I', end_marker='THE END')
这个函数不仅解决了编码兼容性问题,还通过标记截取帮助我们快速聚焦到戏剧正文,为后续的清洗打下了更干净的基础。<

&spm=1001.2101.3001.5002&articleId=154221857&d=1&t=3&u=ddd9c672b0d64b698a96aed177b48bdf)
39

被折叠的 条评论
为什么被折叠?



