目录

用 TF-IDF 挖掘《红楼梦》各回目核心关键词:一个 NLP 实践案例

一、案例背景与目标

二、实现步骤

步骤 1:数据准备与分卷处理

1. 导入模块与创建目录

2. 打开源文件并初始化变量

3. 逐行处理文本内容

4. 写入卷内容并过滤前两行

5. 关闭最后一卷并输出完成信息

步骤2:文本预处理与分词

1. 导入依赖库

2. 读取分卷文本文件

3. 数据存储为 DataFrame

4. 加载自定义词库和停用词表

5. 分词与清洗处理

3.基于 TF-IDF 的《红楼梦》关键词提取

1. 导入依赖库

2. 读取分词后的数据

3. 初始化 TF-IDF 向量器并计算矩阵

4. 获取词汇表并转换为 DataFrame

5. 提取并打印每回目的 Top10 关键词

完整代码及运行结果如下:


用 TF-IDF 挖掘《红楼梦》各回目核心关键词:一个 NLP 实践案例

在自然语言处理中,TF-IDF 是一种经典的文本特征提取方法,尤其适合挖掘文本中的核心关键词。本文以《红楼梦》为例,通过 Python 实现从文本分卷、分词到 TF-IDF 关键词提取的完整流程,带大家直观感受 NLP 技术在古典文学分析中的应用。

一、案例背景与目标

《红楼梦》是中国古典小说的巅峰之作,全书共 120 回,情节复杂,人物众多(仅主要人物就超过 400 个)。各回目围绕不同的核心事件展开(如黛玉进府、元妃省亲、抄检大观园等),蕴含丰富的主题信息。

本案例目标

  1. 将《红楼梦》全文按回目拆分,建立分卷文本库;
  2. 对文本进行分词、去停用词等预处理;
  3. 利用 TF-IDF 算法提取每回目的 Top10 核心关键词;
  4. 通过关键词分析各回目的主题侧重,验证 TF-IDF 在古典文学分析中的有效性。

数据集如下:

二、实现步骤

步骤 1:数据准备与分卷处理

整个代码分为三个主要部分:

  1. 创建存储分卷文件的目录
  2. 读取全文并按卷拆分
  3. 关闭文件并输出完成信息

1. 导入模块与创建目录

import os
os.makedirs('.\\红楼梦\\红楼梦分卷', exist_ok=True)
  • import os:导入 Python 的 os 模块,用于处理文件和目录操作
  • os.makedirs(...):创建多级目录

    • 路径.\\红楼梦\\红楼梦分卷表示在当前目录下创建 "红楼梦" 文件夹,其内再创建 "红楼梦分卷" 子文件夹
    • exist_ok=True是一个非常实用的参数:如果目录已存在则不报错,避免程序因目录已存在而终止

    2. 打开源文件并初始化变量

with open('红楼梦.txt', 'r', encoding='utf-8') as file:current_juan = None  # 当前卷的文件对象line_counter = 0  # 计数当前卷的行数(用于跳过前两行)
  • with open(...) as file:使用 with 语句打开源文件,自动管理文件关闭
  • '红楼梦.txt'是源文件路径(假设与脚本在同一目录)
  • 'r'表示只读模式
  • encoding='utf-8'指定编码为 utf-8,确保中文正常读取
  • current_juan = None:用于保存当前正在写入的卷文件对象,初始化为 None
  • line_counter = 0:计数器,用于记录当前卷已读取的行数,方便后续过滤前两行

3. 逐行处理文本内容

for line in file:# 检测到新卷标题if '卷 第' in line:# 关闭上一卷(如果存在)if current_juan:current_juan.close()# 生成新卷文件名和路径juan_name = line.strip() + '.txt'path = os.path.join('.\\红楼梦\\红楼梦分卷', juan_name)print(f"正在写入:{path}")# 打开新卷文件,重置行数计数器current_juan = open(path, 'w', encoding='utf-8')line_counter = 0  # 新卷从0开始计数continue
  • for line in file:逐行读取源文件内容
  • if '卷 第' in line:判断当前行是否包含卷标题标记(如 "卷 第一"、"卷 第二十")
  • 如果是新卷标题,先检查current_juan是否存在(即是否已有打开的卷文件),如果存在则关闭
  • juan_name = line.strip() + '.txt':处理卷标题,strip()去除换行符和空格,加上.txt作为文件名
  • os.path.join(...):拼接目录和文件名,生成完整路径
  • print(f"正在写入:{path}"):输出日志,方便跟踪进度
  • current_juan = open(...):以写入模式打开新的卷文件
  • line_counter = 0:重置计数器,新卷从 0 开始计数
  • continue:跳过当前行(不将卷标题写入文件)

4. 写入卷内容并过滤前两行

    if current_juan:line_counter += 1if line_counter > 2:  # 只写入第3行及以后的内容current_juan.write(line)
  • if current_juan:只有当存在打开的卷文件时才执行(避免处理文件开头到第一卷之前的内容)
  • line_counter += 1:行数计数器加 1
  • if line_counter > 2:判断是否超过前两行,只写入第 3 行及以后的内容(过滤卷标题后的空行或引言)
  • current_juan.write(line):将符合条件的行写入当前卷文件

5. 关闭最后一卷并输出完成信息

# 关闭最后一卷
if current_juan:current_juan.close()
print("分卷完成,已自动删除每卷前两行")
  • 循环结束后,检查是否还有未关闭的卷文件(最后一卷),如果有则关闭
  • 输出完成信息,提示用户分卷操作已完成

分卷结果如下:

                         

步骤2:文本预处理与分词

代码整体功能:

  1. 读取之前分卷处理好的《红楼梦》文本文件
  2. 使用 jieba 进行中文分词
  3. 过滤停用词(无意义的词汇)
  4. 将处理后的分词结果保存到文件

1. 导入依赖库

import pandas as pd
import os
import jieba
  • pandas:用于数据处理和存储
  • os:用于文件和目录操作
  • jieba:中文分词库,专门用于将中文文本拆分为词语

2. 读取分卷文本文件

filePaths = []
fileContents = []
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')fileContent = f.read()f.close()fileContents.append(fileContent)
  • filePaths:存储所有分卷文件的路径
  • fileContents:存储所有分卷文件的内容
  • os.walk(r"红楼梦"):遍历 "红楼梦" 目录及其子目录下的所有文件
  • root:当前目录路径
  • dirs:当前目录下的子目录列表
  • files:当前目录下的文件列表
  • 循环读取每个文件的完整路径和内容,分别存入两个列表

3. 数据存储为 DataFrame

corpos = pd.DataFrame({'filePath': filePaths,'fileContent': fileContents})
  • 将文件路径和内容组合成一个 DataFrame(表格型数据结构)
  • 这样处理便于后续按行遍历和处理每个分卷的内容
  • corpos DataFrame 包含两列:filePath(文件路径)和fileContent(文件内容)

4. 加载自定义词库和停用词表

停用词如下:

词库如下:

jieba.load_userdict("红楼梦词库.txt")
stopwords = pd.read_csv("stopwordsCN.txt", encoding='utf8', engine='python', index_col=False)
  • jieba.load_userdict("红楼梦词库.txt"):加载《红楼梦》专用词库
  • 词库中包含小说中的人名、地名、特定术语等,提高分词准确性
  • 例如确保 "贾宝玉" 不被拆分为 "贾"、"宝玉"
  • pd.read_csv(...):读取中文停用词表
  • 停用词包括 "的"、"了"、"在" 等无实际意义但出现频率高的词
  • engine='python':避免中文编码相关的警告
  • index_col=False:不将任何列作为索引

5. 分词与清洗处理

file_to_jieba = open('分词后汇总.txt', 'w', encoding='utf-8')
for index, row in corpos.iterrows():juan_ci = ''fileContent = row['fileContent']segs = jieba.cut(fileContent)for seg in segs: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()
  • open('分词后汇总.txt', 'w', encoding='utf-8'):创建文件存储分词结果
  • corpos.iterrows():遍历 DataFrame 中的每一行(即每一卷)
  • jieba.cut(fileContent):对当前卷的文本进行分词
  • 过滤逻辑:
    • seg not in stopwords.stopword.values:排除停用词
    • len(seg.strip()) > 0:排除空字符串和纯空格
  • juan_ci += seg + ' ':将过滤后的词语用空格连接
  • 每一卷的分词结果写入文件,一行对应一卷

处理之后的数据如下:

3.基于 TF-IDF 的《红楼梦》关键词提取

代码整体功能

  1. 读取分词后的文本数据
  2. 计算各回目的 TF-IDF 矩阵
  3. 提取每回目的 Top10 关键词并打印结果

1. 导入依赖库

from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
  • TfidfVectorizer:scikit-learn 中用于计算 TF-IDF 值的工具类,能自动完成词频统计、逆文档频率计算和标准化
  • pandas:用于数据处理,将 TF-IDF 矩阵转换为 DataFrame 便于分析

2. 读取分词后的数据

with open('分词后汇总.txt', 'r', encoding='utf-8') as infile:chapters = infile.readlines()
  • with open(...):以只读模式打开之前生成的分词结果文件
  • chapters = infile.readlines():按行读取文件内容,每一行对应《红楼梦》的一个回目(已分词并过滤停用词)
  • 此时chapters是一个列表,例如:["宝玉 黛玉 贾母 ...", "凤姐 平儿 大观园 ...", ...]

3. 初始化 TF-IDF 向量器并计算矩阵

vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(chapters)
  • TfidfVectorizer():初始化向量器,使用默认参数(后续可根据需求调整,如max_features限制词汇量)
  • fit_transform(chapters):对分词后的文本进行拟合和转换
    • 拟合(fit):分析文本,构建词汇表并计算每个词的逆文档频率(IDF)
    • 转换(transform):计算每个回目中每个词的词频(TF),并结合 IDF 生成 TF-IDF 值
    • 输出的tfidf_matrix是一个稀疏矩阵,形状为(回目数, 词汇数),例如:如果有 120 回目、5000 个独特词汇,矩阵形状为(120, 5000)

4. 获取词汇表并转换为 DataFrame

wordlist = vectorizer.get_feature_names_out()
df = pd.DataFrame(tfidf_matrix.T.todense(), index=wordlist)
  • vectorizer.get_feature_names_out():获取词汇表(所有不重复的词),返回一个数组,例如:["宝玉", "黛玉", "贾母", ...]
  • tfidf_matrix.T:将矩阵转置(行和列互换),形状从(回目数, 词汇数)变为(词汇数, 回目数)
  • todense():将稀疏矩阵转换为稠密矩阵(便于后续处理,小数据量适用)
  • pd.DataFrame(...):创建 DataFrame,行索引为词汇表中的词,列索引为回目索引,值为对应的 TF-IDF 值

5. 提取并打印每回目的 Top10 关键词

for chapter_idx in range(len(chapters)):# 获取当前回目的TF-IDF值(按词汇排序)chapter_tfidf = df.iloc[:, chapter_idx]# 按TF-IDF值降序排序,取前10个词top_keywords = chapter_tfidf.sort_values(ascending=False).head(10)# 打印结果print(f"第{chapter_idx + 1}章的前10关键字:")for word, score in top_keywords.items():print(f"{word}: {score:.6f}")  # 保留6位小数print("*" * 50)  # 分隔线,增强可读性
  • for chapter_idx in range(len(chapters)):遍历每个回目
  • df.iloc[:, chapter_idx]:提取当前回目的所有词的 TF-IDF 值(DataFrame 的一列)
  • sort_values(ascending=False).head(10):按 TF-IDF 值从高到低排序,取前 10 个词(核心关键词)
  • 打印格式说明:
  • chapter_idx + 1:回目编号(从 1 开始,而非 0)
  • word: score:关键词及其 TF-IDF 值,值越高说明该词对当前回目的代表性越强

运行结果如下:

完整代码及运行结果如下:

import os
os.makedirs('.\\红楼梦\\红楼梦分卷', exist_ok=True)# 打开源文件
with open('红楼梦.txt', 'r', encoding='utf-8') as file:current_juan = None  # 当前卷的文件对象line_counter = 0  # 计数当前卷的行数(用于跳过前两行)for line in file:# 检测到新卷标题if '卷 第' in line:# 关闭上一卷(如果存在)if current_juan:current_juan.close()# 生成新卷文件名和路径juan_name = line.strip() + '.txt'path = os.path.join('.\\红楼梦\\红楼梦分卷', juan_name)print(f"正在写入:{path}")# 打开新卷文件,重置行数计数器current_juan = open(path, 'w', encoding='utf-8')line_counter = 0  # 新卷从0开始计数continueif current_juan:line_counter += 1if line_counter > 2:  # 只写入第3行及以后的内容current_juan.write(line)# 关闭最后一卷if current_juan:current_juan.close()
print("分卷完成,已自动删除每卷前两行")import pandas as pd
import os
import jieba
filePaths = []
fileContents = []
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')fileContent = f.read()f.close()fileContents.append(fileContent)
corpos = pd.DataFrame({'filePath': filePaths,'fileContent': fileContents})
jieba.load_userdict("红楼梦词库.txt")
stopwords = pd.read_csv("stopwordsCN.txt", encoding='utf8', engine='python', index_col=False)
file_to_jieba = open('分词后汇总.txt', 'w', encoding='utf-8')
for index, row in corpos.iterrows():juan_ci = ''fileContent = row['fileContent']segs = jieba.cut(fileContent)for seg in segs: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()from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
with open('分词后汇总.txt', 'r', encoding='utf-8') as infile:chapters = infile.readlines()
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(chapters)
wordlist = vectorizer.get_feature_names_out()
df = pd.DataFrame(tfidf_matrix.T.todense(), index=wordlist)
for chapter_idx in range(len(chapters)):chapter_tfidf = df.iloc[:, chapter_idx]top_keywords = chapter_tfidf.sort_values(ascending=False).head(10)print(f"第{chapter_idx + 1}章的前10关键字:")for word, score in top_keywords.items():print(f"{word}: {score:.6f}")print("*" * 50)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/92986.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/92986.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/92986.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软考中级网络工程师】知识点之 IP QoS 技术

目录一、IP QoS 技术是什么1.1 定义与概念1.2 重要性和应用场景二、IP QoS 技术原理2.1 流量分类与标记2.2 流量整形与限速2.3 拥塞避免与管理2.4 资源预留协议(RSVP)三、IP QoS技术模型3.1 尽力而为服务模型3.2 综合服务模型(IntServ&#x…

Git 常用命令速查表

一、仓库初始化与克隆命令说明git init在当前目录初始化本地仓库git clone <远程仓库地址>克隆远程仓库到本地&#xff08;例&#xff1a;git clone https://github.com/user/repo.git&#xff09;二、文件状态与提交命令说明git status查看工作区 / 暂存区文件状态git a…

第五十四章:AI模型的“压缩大师”:GPTQ、AWQ与bitsandbytes实战量化

AI模型压缩前言&#xff1a;让训练好的AI模型“轻装上阵”第一章&#xff1a;回顾与挑战&#xff1a;训练后量化&#xff08;PTQ&#xff09;的必要性1.1 量化原理与精度类型回顾&#xff1a;FP32到INT4/INT81.2 PTQ&#xff08;Post-Training Quantization&#xff09;&#x…

在Word和WPS文字一页中实现一栏与多栏混排

在Word和WPS文字的一页中如何实现分栏和不分栏的内容混排&#xff1f;只需要使用分栏功能。把光标放在要分栏的位置&#xff0c;插入分栏即可&#xff0c;最关键的点是分栏应用于“插入点之后”。如果不需要分栏&#xff0c;则栏数选择为1即可。一、Word和WPS文字的分栏设置路径…

Python调用C/C++函数库的多种方法与实践指南

Python作为一门高级编程语言&#xff0c;以其简洁的语法和丰富的库生态赢得了开发者的青睐。然而&#xff0c;在计算密集型任务中&#xff0c;Python的性能往往无法满足要求。Python调用C/C函数库成为提升应用性能的关键技术路径&#xff0c;通过将底层计算逻辑用C/C实现&#…

【21】OpenCV C++实战篇——OpenCV C++案例实战二十七《角度测量》

OpenCV C案例实战二十七《角度测量》 利用opencv获取三点所形成直线的角度

程序在计算机中的运行方式

程序在计算机中的运行是一个涉及硬件、操作系统和软件协同工作的复杂过程。我们可以将其分解为几个关键阶段来理解&#xff1a;1. 程序的诞生&#xff1a;从源代码到可执行文件 编写代码&#xff1a;程序员使用高级编程语言&#xff08;如C、Python、Java&#xff09;编写源代码…

虚拟卡券管理平台详细设计文档

文章目录**1. 文档概述**1.1 目标1.2 核心能力**2. 业务场景分析**2.1 用户场景2.2 关键业务流程卡券核销流程&#xff1a;**3. 整体架构设计**3.1 技术栈3.2 微服务拆分**4. 功能模块详细设计**▶ 4.1 卡券生命周期管理**4.1.1 卡券类型设计****4.1.2 关键状态机**▶ 4.2 卡券…

Oracle参数Process

RDBMS&#xff1a; 19.28 参考文档&#xff1a; IF:How to determine an optimum value for PROCESSES parameter (Doc ID 2012693.1) All About the Initialization Parameter PROCESSES and the Related Issues (Doc ID 2673195.1) How to calculate the proper value from …

【数据结构入门】树

目录 1.树的概念 父子结点 根节点|叶节点 结点的度 叶子结点或终端结点 兄弟结点 树的度 结点的层次 树的高度或深度 结点的祖先 堂兄弟结点 子孙 森林 2. 树的结构定义 2.1 左孩子右兄弟结构 2.2 数组表示法 3.树&非树 1.树的概念 树是一种非线性的数据结…

手把手教你用 Flink + CDC 实现 MySQL 数据实时导入 StarRocks(干货)

手把手教你用 Flink CDC 实现 MySQL 数据实时导入 StarRocks&#xff08;干货&#xff09; 如何利用 Apache Flink 结合 CDC&#xff08;Change Data Capture&#xff0c;变更数据捕获&#xff09;技术&#xff0c;将 MySQL 的数据实时导入 StarRocks&#xff0c;打造高效的实…

Rust:anyhow 高效错误处理库核心用法详解

以下是 anyhow 库在 Rust 中的核心用法详解&#xff08;结合最佳实践和示例&#xff09;&#xff1a; &#x1f530; 一、anyhow 的核心价值 用于简化错误处理&#xff0c;尤其适合&#xff1a; 需要快速原型开发的应用需要丰富错误上下文&#xff08;Context&#xff09;的场…

阿里云服务linux安装单机版

一、单机安装Redis 阿里教程 下载地址:redis下载地址 1、首先需要安装Redis所需要的依赖&#xff1a; yum install -y gcc tcl 2、下载Redis 注&#xff1a;也可以自己下好然后上传到云服务 wget https://gitcode.net/weixin_44624117/software/-/raw/master/software/Li…

python之uv使用

文章目录安装与更新standalonepip 安装创建以及初始化项目依赖管理uv run直接在命令行运行python代码片段直接运行项目中可执行脚本文件运行python包中快捷指令uv项目本地运行调试细节vscode 中运行调试uv项目命令行运行深入理解 uv lock, uv sync, uv lockuv lock 行为解析:uv…

【CV 目标检测】①——目标检测概述

一、目标检测概述 1.目标检测 目标检测&#xff08;Object Detection&#xff09;的任务是找出图像中所有感兴趣的目标&#xff0c;并确定它们的类别&#xff08;分类任务&#xff09;和位置&#xff08;回归任务&#xff09; 目标检测中能检测出来的物体取决于当前任务&…

C#图形库SciChart与ScottPlot及LiveCharts2对比

一.概述 1.SciChart SciChart 是一个专为企业级应用设计的高性能数据可视化库&#xff0c;提供跨平台的图表解决方案&#xff0c;支持 .NET、JavaScript、iOS 和 Android 等多个平台。它以卓越的渲染性能、丰富的专业图表类型和强大的交互功能著称&#xff0c; 广泛应用于金…

Win10电脑密码忘记如何进入操作系统

http://xq128.com/zj.htmlhttps://share.feijipan.com/s/LbFdbUKl下载后&#xff0c;准备一个空的U盘&#xff0c;大于4G。将U盘制作为PE盘。之后将制作好的PE盘插入到电脑中&#xff0c;启动待去除密码的电脑台式机&#xff0c;启动后一直按住F12&#xff0c;进入BIOS。选择下…

[免费]基于Python的网易云音乐热门歌单可视化大屏项目(flask+pandas+echarts+request库)【论文+源码+SQL脚本】

大家好&#xff0c;我是python222_小锋老师&#xff0c;看到一个不错的基于Python的网易云音乐热门歌单可视化大屏项目(flaskpandasechartsrequest库)&#xff0c;分享下哈。 项目视频演示 【免费】基于Python的网易云音乐热门歌单可视化大屏项目(flaskpandasecharts爬虫) Py…

AR 智能眼镜:从入门到未来

从零看懂 AR 智能眼镜:未来 10 年技术演进与新手入门指南 在这个数字技术飞速迭代的时代,AR 智能眼镜正从科幻电影走进现实。从 2025 年重量不足 35 克的消费级产品,到 2030 年成为 “第二大脑” 的生活刚需,再到 2040 年进化为神经接口终端,AR 智能眼镜的发展将重塑人类…

初识Vue2及MVVM理解

1、什么是Vue Vue是一款用于构建用户界面的JavaScript框架。它基于标准HTML、CSS和JavaScript构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;可以高效地开发用户界面。 Vue.js是一套构建用户界面的渐进式框架&#xff0c;采用自底向上增量开发的设计&…