Python 红楼梦人物关系与文本特征可视化分析(词云,共现网络,角色热度,情节密度)
1. 红楼梦文本分析的技术准备
想要用Python分析《红楼梦》这部古典名著,首先需要搭建好技术环境。我推荐使用Anaconda来管理Python环境,它能很好地解决依赖包冲突的问题。安装完Anaconda后,创建一个新的conda环境:
conda create -n hongloumeng python=3.8
conda activate hongloumeng
接下来安装必要的分析库,这些库构成了我们分析工作的技术基础:
pip install jieba wordcloud matplotlib networkx pyecharts imageio
jieba是中文分词利器,wordcloud用于生成词云,matplotlib和pyecharts负责数据可视化,networkx处理人物关系网络,imageio则用于读取图片作为词云的形状模板。
《红楼梦》的文本可以从古腾堡计划等公开资源获取,建议使用120回完整版本。我通常会创建一个专门的data文件夹存放文本文件:
project/
├── hongloumeng.py
└── data/
├── 红楼梦.txt
└── chinese_stopwords.txt
中文停用词表很重要,它能过滤掉"的"、"了"这类无实际意义的词汇。我整理了一份包含1200多个常用停用词的文本,在实际分析中可以根据需要增减。
2. 人物热度分析与词云可视化
2.1 人物出场频次统计
《红楼梦》中有名有姓的角色多达数百人,我们首先需要识别主要人物。使用jieba分词时,要注意古典人名的特殊性:
import jieba
jieba.load_userdict('data/character_names.txt') # 自定义人物名称词典
我整理了一份包含120个主要角色名称的词典文件,这样可以提高分词的准确性。统计人物出场次数时,还需要处理同人异名的情况:
name_mapping = {
'宝玉': '贾宝玉',
'黛玉': '林黛玉',
'宝钗': '薛宝钗',
'凤姐': '王熙凤',
'老祖宗': '贾母'
}
统计结果显示,贾宝玉以2100+次的出场高居榜首,王熙凤、林黛玉紧随其后。这个数据可以反映作者对人物的侧重程度:
top_characters = sorted(counts.items(), key=lambda x: x[1], reverse=True)[:15]
for name, count in top_characters:
print(f"{name}: {count}次")
2.2 主题词云生成
词云能直观展示文本的高频词汇。我推荐使用WordCloud库,并配合自定义形状:
from wordcloud import WordCloud
import imageio
mask = imageio.imread('data/red_mansion.png') # 使用红楼梦场景图作为形状
wc = WordCloud(
font_path='simhei.ttf',
background_color='white',
max_words=500,
mask=mask,
colormap='Reds' # 使用红色系配色
)
生成词云时,可以调整这些参数获得最佳效果:
- max_font_size:控制最大字号
- relative_scaling:调整词频与大小的关系
- collocations=False:避免重复显示相似词
3. 人物关系网络分析
3.1 共现关系提取
人物关系网络的核心是计算共现频率。我的做法是按段落分析人物同现:
paragraphs = text.split('\n') # 按段落分割
co_occurrence = defaultdict(int)
for para in paragraphs:
present_chars = [name for name in all_characters if name in para]
for i in range(len(present_chars)):
for j in range(i+1, len(present_chars)):
pair = tuple(sorted([present_chars[i], present_chars[j]]))
co_occurrence[pair] += 1
这种方法的优势是能捕捉场景级的互动关系,比简单的章节共现更精确。
3.2 网络可视化
使用NetworkX绘制关系图时,我习惯用以下配置:
plt.figure(figsize=(20,20))
pos = nx.spring_layout(G, k=0.15) # k控制节点间距
nx.draw_networkx_nodes(
G, pos,
node_size=[v*50 for v in dict(G.degree()).values()],
node_color='coral',
alpha=0.9
)
nx.draw_networkx_edges(
G, pos,
width=[d['weight']*5 for (u,v,d) in G.edges(data=True)],
edge_color='gray',
alpha=0.5
)
关键参数说明:
- k值:太小会导致节点重叠,太大会使图形分散
- node_size:通常与节点度数成正比
- width:反映边权重大小
- alpha:调整透明度避免视觉混乱
4. 情节结构与叙事节奏分析
4.1 章回字数统计
分析章回字数变化能揭示叙事节奏。首先需要准确分割章回:
import re
chapters = re.split(r'第[一二三四五六七八九十百]+回', text)[1:]
chapter_lengths = [len(chap) for chap in chapters]
用pyecharts绘制折线图时,可以添加标记点突出关键节点:
line = (
Line()
.add_xaxis(xaxis_data=[f"第{i+1}回" for i in range(120)])
.add_yaxis(
series_name="字数",
y_axis=chapter_lengths,
markpoint_opts=opts.MarkPointOpts(
data=[
opts.MarkPointItem(type_="max", name="最长"),
opts.MarkPointItem(type_="min", name="最短"),
opts.MarkPointItem(coord=[39, chapter_lengths[38]], name="元妃省亲")
]
)
)
)
4.2 情节密度分析
情节密度可以通过事件数量来衡量。我定义了一个简单算法:
event_keywords = ['宴', '诗会', '病', '婚', '葬', '抄检']
density = []
for chap in chapters:
count = sum(chap.count(keyword) for keyword in event_keywords)
density.append(count / len(chap) * 1000) # 每千字事件数
将字数变化与情节密度叠加分析,能清晰看到如"大观园试才题对额"等高潮章节的叙事特征。
5. 进阶分析与可视化技巧
5.1 时间线可视化
用Timeline组件展示人物活动轨迹:
from pyecharts import Timeline
timeline = Timeline()
for year in range(1, 16):
year_data = process_year_data(text, year)
bar = create_year_bar(year_data)
timeline.add(bar, f"第{year}年")
timeline.render("红楼梦时间线.html")
5.2 情感分析应用
虽然古典文学的情感分析较复杂,但可以尝试简单实现:
sentiment_dict = {
'笑': 1, '喜': 1, '悲': -1, '哭': -1
}
def analyze_sentiment(text):
score = 0
for word, value in sentiment_dict.items():
score += text.count(word) * value
return score / len(text) * 100
将情感分数按章回绘制,能观察到"黛玉葬花"等经典场景的情感波动。
6. 项目优化与实践建议
在实际操作中,我发现几个常见问题需要注意:
- 文本编码问题:古典文本常用GBK编码,建议统一转为UTF-8
- 特殊符号处理:删除"【】"等排版符号
- 分词优化:添加"通灵宝玉"等专有名词到自定义词典
- 性能优化:大文本处理时使用生成器而非列表
一个实用的调试技巧是抽样检查:
sample = random.sample(paragraphs, 50)
for para in sample:
print(para)
print("识别到的人物:", extract_characters(para))
print("---")
这样能快速验证分析逻辑的准确性。
更多推荐


所有评论(0)