《红楼梦》文本分析实战:从分卷处理到关键词提取

在文本分析领域,经典文学作品是非常好的研究对象。本文以《红楼梦》为例,详细介绍从原始文本分卷、关键词提取到TF-IDF分析的完整流程,包含可直接运行的代码及原理说明,适合文本处理初学者参考。

一、数据分析:《红楼梦》文本分卷处理

1. 导入模块和初始设置

import os  # 导入os模块,用于处理文件路径等操作系统相关功能
file = open('红楼梦.txt', encoding='utf-8')  # 打开源文件,使用utf-8编码
flag = 0  # 标记是否已经创建过分卷文件,0表示未创建,1表示已创建
juan_file = None  # 用于存储当前打开的分卷文件对象,初始化为None
i = 1  # 分卷编号,从1开始计数

2. 空白行处理标记

skip_blank_lines = False  # 新增标记:是否正在跳过空白行,False表示不跳过

3. 主循环:逐行处理文本

for line in file:  # 遍历源文件的每一行
    stripped_line = line.strip()  # 去除行首尾的空白字符(空格、换行符等),用于判断和匹配
    
    # 处理需要跳过空白行的情况
    if skip_blank_lines:  # 如果处于跳过空白行状态
        if stripped_line == '':  # 当前行是空白行
            continue  # 跳过当前行,继续处理下一行
        else:  # 当前行不是空白行
            skip_blank_lines = False  # 关闭跳过空白行状态
    
    # 过滤广告内容
    if '手机电子书·大学生小说网' in stripped_line:  # 如果当前行包含这个广告文本
        skip_blank_lines = True  # 开启跳过空白行模式,处理广告后的空白行
        continue  # 跳过当前广告行,不写入分卷文件
    
    # 处理分卷标记行
    if '卷 第' in stripped_line:  # 如果当前行是分卷标记(如"卷 第一")
        # 生成分卷文件名,格式为"01_卷 第一.txt",确保编号是两位数
        juan_name = f"{i:02d}_{stripped_line}.txt"
        i += 1  # 分卷编号自增1
        
        # 创建分卷文件的完整路径,将分卷文件保存在"分卷"文件夹下
        path = os.path.join('分卷', juan_name)
        print(path)  # 打印当前分卷文件的路径,方便查看进度
        
        # 关闭上一个分卷文件(如果存在)
        if flag == 1 and juan_file is not None:  # 如果已经创建过分卷文件
            juan_file.close()  # 关闭上一个分卷文件
        
        # 创建并打开当前分卷文件,用于写入内容
        juan_file = open(path, 'w', encoding='utf-8')
        flag = 1  # 更新标记,表示已经创建过分卷文件
        continue  # 跳过当前分卷标记行,不写入分卷文件(也可以根据需要决定是否写入)
    
    # 写入内容到当前分卷文件
    if juan_file is not None:  # 如果当前有打开的分卷文件
        juan_file.write(line)  # 将当前行写入分卷文件(使用原始line而不是stripped_line,保留原始格式)

4. 清理工作:关闭文件

# 关闭最后一个分卷文件(如果存在)
if juan_file is not None:
    juan_file.close()
 
# 关闭源文件
file.close()

二、关键词提取:基于分词的文本预处理

1. 导入必要的库

import pandas as pd  # 用于数据处理和分析,构建DataFrame和处理停用词
import os  # 用于文件和目录操作,遍历文件夹等
import jieba  # 中文分词库,用于将中文文本分割成词语

2. 遍历文件夹收集文件路径和内容

# 初始化两个列表,分别存储文件路径和文件内容
filePaths = []
fileContents = []
 
# 遍历"./分卷"目录下的所有文件(包括子目录中的文件)
# os.walk()返回一个三元组:当前目录路径、当前目录下的子目录列表、当前目录下的文件列表
for root, dirs, files in os.walk(r"分卷"):
    for name in files:  # 遍历当前目录下的所有文件
        # 拼接完整的文件路径(根目录+文件名)
        filePath = os.path.join(root, name)
        filePaths.append(filePath)  # 将文件路径添加到列表
        
        # 读取文件内容
        f = open(filePath, 'r', encoding='utf-8')  # 以只读模式打开文件,指定编码为utf-8
        fileContent = f.read()  # 读取整个文件内容
        f.close()  # 关闭文件
        fileContents.append(fileContent)  # 将文件内容添加到列表

3. 构建 DataFrame 存储数据

# 使用pandas构建一个数据框(类似表格),包含两列:filePath(文件路径)和fileContent(文件内容)
corpos = pd.DataFrame({
    'filePath': filePaths,
    'fileContent': fileContents
})

4. 加载自定义资源

# 加载《红楼梦》专属分词补充词库,让jieba更好地识别小说中的专有名词(如人名、地名等)
jieba.load_userdict("红楼梦词库.txt")
 
# 读取中文停用词表
# stopwordsCN.txt是包含中文停用词的文件(如"的"、"了"、"在"等无实际意义的词)
# encoding='utf8'指定编码,engine='python'避免编码相关的解析问题
# index_col=False表示不将任何一列作为索引
stopwords = pd.read_csv("stopwordsCN.txt", encoding='utf8', engine='python', index_col=False)

5. 分词处理与停用词过滤

# 打开一个文件用于写入分词结果
file_to_jieba = open('分词后汇总.txt', 'w', encoding='utf-8')
 
# 遍历corpos数据框中的每一行(即每一卷的内容)
for index, row in corpos.iterrows():
    juan_ci = ''  # 用于存储当前卷的分词结果
    fileContent = row['fileContent']  # 获取当前行的文件内容
    
    # 使用jieba进行分词,cut()方法返回一个可迭代的生成器
    segs = jieba.cut(fileContent)
    
    # 遍历每个分词结果
    for seg in segs:
        # 过滤条件:
        # 1. 该词不在停用词表中(seg not in stopwords.stopword.values)
        # 2. 去除空白字符后长度大于0(避免空字符串)
        if seg not in stopwords.stopword.values and len(seg.strip()) > 0:
            juan_ci += seg + ' '  # 将符合条件的词添加到结果字符串,并用空格分隔
    
    # 将当前卷的分词结果写入文件,每行对应一卷的内容
    file_to_jieba.write(juan_ci + '\n')
 
# 关闭文件,释放资源
file_to_jieba.close()

三、TF-IDF模拟:提取各卷核心关键词

1. 导入必要的库

import pandas as pd  # 用于数据处理和分析,构建DataFrame展示结果
from sklearn.feature_extraction.text import TfidfVectorizer  # 从scikit-learn库导入TF-IDF向量器

2. 读取分词后的文本数据

# 打开分词后的汇总文件,读取所有行内容
infile = open('分词后汇总.txt','r',encoding='utf-8')
corpus = infile.readlines()  # 读取文件所有行,存储为列表,每个元素对应一卷的分词结果

3. 计算 TF-IDF 矩阵

# 初始化TF-IDF向量器
vectorizer = TfidfVectorizer()
 
# 对语料库进行拟合(学习词汇表)并转换为TF-IDF矩阵
tfidf = vectorizer.fit_transform(corpus)
 
# 获取词汇表(所有分词后的词语列表)
wordlist = vectorizer.get_feature_names()  # 注意:较新的sklearn版本建议使用get_feature_names_out()

4. 构建 TF-IDF 数据框

# 将TF-IDF矩阵转置(词汇为行,文档为列),转换为稠密矩阵,再构建DataFrame
df = pd.DataFrame(tfidf.T.todense(), index=wordlist)

5. 定义提取 Top N 关键词的函数

def get_top_keywords(col, top_n=10):
    # 过滤出当前文档(列)中TF-IDF值大于0的词语(即该词在文档中出现过)
    non_zero = col[col > 0]
    # 返回TF-IDF值最大的前top_n个词语及其值(按降序排列)
    return non_zero.nlargest(top_n).items()

6. 应用函数提取所有文档的关键词

# 对DataFrame的每一列(每个文档)应用get_top_keywords函数,提取前10个关键词
top_keywords_result = df.apply(
    lambda col: get_top_keywords(col, top_n=10),
    axis=0)  # axis=0表示按列应用函数

7. 打印结果

# 遍历结果,按文档编号(从1开始)打印每卷的核心关键词
for doc_idx, top_items in enumerate(top_keywords_result, start=1):
    print(f"第{doc_idx}回的核心关键词:{list(top_items)[:10]}")

四、泛用性:代码的扩展与适配场景

一、代码核心逻辑与可修改点

原代码流程可概括为:

​​原始文本收集→分卷/分块处理→分词与过滤→TF-IDF关键词提取→结果输出​​

核心可修改点:

  • 文本来源(输入文件/文件夹路径)

  • 分块规则(按标记、长度、章节等)

  • 分词补充词库(领域专属词汇)

  • 停用词表(过滤无意义词汇)

  • 关键词提取参数(Top N数量、算法调整)

二、简单修改后的可能作用

  1. ​​文本结构化处理​​

    通过修改分块规则(如按"章节""段落""时间戳"等标记),可将长文本拆分为结构化子文本,方便按单元分析(如小说按"章节"拆分、报告按"小节"拆分)。

  2. ​​领域专属词汇提取​​

    替换自定义词库(如"红楼梦词库.txt"改为"医学词库.txt""法律词库.txt")和停用词表,可精准识别领域内专业术语,过滤通用无意义词汇。

  3. ​​关键信息快速定位​​

    调整TF-IDF参数(如修改top_n数量、增加词语最小/最大出现频率限制),可提取每段文本的核心关键词,快速定位重点(如章节核心人物、报告核心观点)。

  4. ​​文本特征对比分析​​

    通过输出各分块的关键词差异,可对比不同文本单元的内容侧重(如不同章节的主题变化、不同作者的写作风格差异)。

三、典型应用场景

  1. ​​文学/历史文本分析​​

    • 修改点:分块规则按"回目""章节标题"拆分(如《三国演义》《史记》);补充词库添加古代人名、地名、官职(如"丞相""节度使")。

    • 作用:提取每章节核心人物、事件关键词,分析情节发展脉络(如"某章节关键词以'战争''计谋'为主,反映军事主题")。

  2. ​​学术论文/报告整理​​

    • 修改点:分块规则按"摘要""引言""实验部分"等标题拆分;停用词表添加学术通用虚词(如"研究表明""综上所述")。

    • 作用:快速提取各部分核心术语(如实验方法、结论关键词),生成论文结构摘要。

  3. ​​企业文档/客服记录分析​​

    • 修改点:文本来源读取"客服对话记录""会议纪要"文件夹;分块规则按"日期""对话ID"拆分单条记录;补充词库添加企业产品名、行业术语(如"APP闪退""退款流程")。

    • 作用:提取高频问题关键词(如"登录失败""物流延迟"),定位客户需求或业务痛点。

  4. ​​社交媒体/舆情分析​​

    • 修改点:文本来源读取"微博评论""论坛帖子"文本文件;停用词表添加网络流行虚词(如"哈哈哈""绝了")。

    • 作用:按时间段或话题分块,提取热点关键词(如某事件的讨论焦点),辅助舆情监控。

总结

本文代码本质是一套"文本预处理+关键词提取"的通用工具,通过修改分块规则、词库和输入来源,可快速适配文学、学术、企业、舆情等多领域的文本分析需求,核心价值是降低长文本处理成本,实现关键信息的自动化提取与对比。

 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐