用Python+Jieba打造你的专属中文小说分析工具(以《斗罗大陆》为例)

当你第一次接触自然语言处理时,教科书和教程里总是充斥着各种英文语料库和NLTK的示例。但作为一个中文开发者,你是否想过:那些炫酷的文本分析技术,能不能用在我们熟悉的中文网络小说上?今天,我们就用《斗罗大陆》这部经典作品,带你从零构建一个真正实用的中文小说分析工具。

1. 为什么选择中文小说作为语料库?

传统NLP教学往往从英文语料库开始,但中文处理有着独特的挑战和魅力。网络小说作为当代中文的重要载体,包含了丰富的语言现象:

  • 口语化表达 :比新闻语料更贴近真实语言使用
  • 专有名词密集 :"武魂"、"魂环"等虚构概念构成特殊词汇
  • 长文本结构 :章节分明,适合段落分析和情节追踪
# 简单统计《斗罗大陆》的基本信息
import jieba

with open('斗罗大陆.txt', 'r', encoding='utf-8') as f:
    text = f.read()
    
chars_count = len(text)
words_list = list(jieba.cut(text))
words_count = len(words_list)
unique_words = len(set(words_list))

print(f"总字符数:{chars_count}")
print(f"总词数:{words_count}") 
print(f"唯一词数:{unique_words}")

提示:中文分词是处理的第一步,Jieba虽然简单但效果不错,后续我们会优化分词结果

2. 从原始文本到结构化语料库

拿到原始小说文本只是开始,我们需要一系列预处理步骤:

2.1 数据清洗实战

中文网络小说常有特殊符号和排版问题,需要针对性处理:

import re

def clean_text(text):
    # 去除HTML标签
    text = re.sub(r'<[^>]+>', '', text)
    # 统一替换全角空格和特殊空白符
    text = re.sub(r'[\u3000\xa0\u200b]', ' ', text)
    # 保留中文、标点和必要符号
    text = re.sub(r'[^\u4e00-\u9fa5,。!?、;:"'()《》…\-\s]', '', text)
    # 合并连续空白
    text = re.sub(r'\s+', ' ', text)
    return text

cleaned_text = clean_text(text)

2.2 专业分词优化

默认分词可能不适合小说场景,我们需要:

  1. 添加自定义词典 :加入小说特有词汇
  2. 调整分词模式 :平衡精度与效率
# 添加《斗罗大陆》专有名词
jieba.add_word('武魂', freq=1000)
jieba.add_word('魂环', freq=1000)
jieba.add_word('小舞', freq=1000)

# 使用更精确的搜索引擎模式
words = jieba.cut_for_search(cleaned_text)

3. 构建NLTK兼容的中文语料库

虽然NLTK主要为英文设计,但我们可以巧妙利用它:

3.1 创建Text对象

from nltk import Text

# 将分词结果转换为NLTK Text对象
text_obj = Text(list(words))

# 现在可以使用NLTK的各种功能
print("'武魂'出现的上下文:")
text_obj.concordance('武魂', width=50, lines=5)

3.2 词频分析与可视化

from nltk import FreqDist
import matplotlib.pyplot as plt

fdist = FreqDist(text_obj)

# 前20高频词
top_words = fdist.most_common(20)
print("高频词统计:")
for word, count in top_words:
    print(f"{word}: {count}")

# 绘制词频分布图
plt.rcParams['font.sans-serif'] = ['SimHei']
fdist.plot(20, cumulative=False)
plt.title('《斗罗大陆》词频分布')
plt.show()

4. 高级分析技巧

基础统计只是开始,我们还能做更有趣的分析:

4.1 人物关系网络

通过共现分析构建人物关系:

from collections import defaultdict

# 主要人物列表
characters = ['唐三', '小舞', '戴沐白', '奥斯卡', '马红俊']

# 构建共现矩阵
co_occurrence = defaultdict(int)
window_size = 50  # 共现窗口大小

words = list(text_obj)
for i in range(len(words)):
    if words[i] in characters:
        for j in range(max(0, i-window_size), min(len(words), i+window_size)):
            if words[j] in characters and words[j] != words[i]:
                pair = tuple(sorted((words[i], words[j])))
                co_occurrence[pair] += 1

# 输出强关联人物
print("人物共现频率:")
for pair, count in sorted(co_occurrence.items(), key=lambda x: -x[1])[:10]:
    print(f"{pair[0]} & {pair[1]}: {count}次")

4.2 情节发展分析

通过关键词密度追踪情节变化:

import numpy as np

# 按章节分割文本
chapters = re.split(r'第[一二三四五六七八九十百]+章', cleaned_text)[1:]

# 计算各章节关键词密度
keyword = '武魂'
chapter_density = []
for chap in chapters:
    words = list(jieba.cut(chap))
    density = words.count(keyword) / len(words) * 10000  # 每万字出现频率
    chapter_density.append(density)

# 绘制情节发展曲线
plt.plot(np.arange(len(chapters)), chapter_density)
plt.xlabel('章节顺序')
plt.ylabel(f'"{keyword}"出现频率(每万字)')
plt.title(f'"{keyword}"在《斗罗大陆》中的分布')
plt.show()

5. 构建可复用的分析工具

将上述功能封装成工具类:

class ChineseNovelAnalyzer:
    def __init__(self, filepath):
        with open(filepath, 'r', encoding='utf-8') as f:
            self.raw_text = f.read()
        self.cleaned_text = self._clean_text()
        self.words = self._tokenize()
        self.text_obj = Text(self.words)
        
    def _clean_text(self):
        # 实现清洗逻辑
        pass
        
    def _tokenize(self):
        # 实现分词逻辑
        pass
        
    def keyword_analysis(self, keyword):
        # 实现关键词分析
        pass
        
    def character_network(self, characters):
        # 实现人物关系分析
        pass
        
    def plot_trend(self, keyword):
        # 实现趋势分析
        pass

# 使用示例
analyzer = ChineseNovelAnalyzer('斗罗大陆.txt')
analyzer.keyword_analysis('魂环')

这套工具不仅能用于《斗罗大陆》,稍作调整就能分析其他中文小说。我在分析《诡秘之主》时发现,只需更新自定义词典,同样的代码就能揭示完全不同的语言特征。

更多推荐