机器学习——TF-IDF文本特征提取评估权重 + Jieba 库进行分词(以《红楼梦》为例)


使用 Jieba 库进行 TF-IDF 关键词提取(以《红楼梦》为例)

在中文文本分析中,TF-IDF(Term Frequency - Inverse Document Frequency) 是最常用的关键词提取方法之一。它通过评估词在单个文档中的出现频率和在所有文档中的稀有程度,来衡量该词的重要性。

本文将以《红楼梦》分卷文本为例,演示如何使用 jieba 库完成分词、停用词过滤,并最终进行 TF-IDF 关键词提取


一、TF-IDF 的定义

TF-IDF(Term Frequency-Inverse Document Frequency,词频 - 逆文档频率)是文本挖掘领域中一种常用技术,其核心作用是评估某个词语在特定文档中的重要程度。该指标由两部分构成:

  • 词频(TF):指一个词语在当前文档中出现的频率。
  • 逆文档频率(IDF):用于衡量该词语在整个文档集合中的普遍重要性(即该词是否在多数文档中都频繁出现)。

通常来说,一个词语的 TF-IDF 值越高,就意味着它在当前文档中的重要性越高。

二、选择 jieba 库的原因

jieba 是一款优秀的中文分词工具库,其突出特点使其成为众多场景下的优选,包括:

  • 支持三种不同的分词模式,可适应多样化的分词需求。
  • 允许用户导入自定义词典,提升对特定领域词汇的分词准确性。
  • 具备高效的词性标注功能,能快速为词语标注所属词性。
  • 内置 TF-IDF 关键词提取功能,方便直接从文本中提取关键信息。
  • 整体设计轻量,且操作简单易懂,易于上手使用。

代码一:准备数据

我们将准备 ./红楼梦 文件夹,其中:

  • 红楼梦正文:红楼梦.txt

  • 用户自定义词典红楼梦词库.txt(保证人名、地名等专业词汇的分词准确性)

  • 中文停用词表StopwordsCN.txt(去除“的”“了”等无意义的高频词) 

  • 空文件夹./红楼梦/分卷:用于存放代码产生分卷


《红楼梦》按卷分割文本代码详解

import os# 打开整本红楼梦文本
file = open('.\\红楼梦\\红楼梦.txt', encoding='utf-8')flag = 0  # 标记是否已打开分卷文件# 遍历整本小说每一行
for line in file:# 如果该行包含“卷 第”,表示这是卷的开头if '卷 第' in line:juan_name = line.strip() + '.txt'  # 用该行作为分卷文件名path = os.path.join('.\\红楼梦\\分卷', juan_name)print(path)if flag == 0:# 第一次遇到卷标题,打开分卷文件准备写入juan_file = open(path, 'w', encoding='utf-8')flag = 1else:# 遇到新的卷标题时,先关闭之前的分卷文件,再打开新的juan_file.close()juan_file = open(path, 'w', encoding='utf-8')continue# 过滤空行和广告信息(如“手机电子书·大学生小说网”)if line.strip() != "" and "手机电子书·大学生小说网" not in line:juan_file.write(line)  # 写入当前分卷文件# 最后关闭最后一个分卷文件及整本书文件
juan_file.close()
file.close()

代码流程说明

  1. 打开整本《红楼梦》文本文件

    • 使用 open 以 utf-8 编码打开 .\\红楼梦\\红楼梦.txt 文件,准备逐行读取。

  2. 初始化标记变量 flag

    • flag = 0 表示还没有打开分卷文件。

  3. 逐行读取整本小说内容

    • 使用 for line in file: 依次处理每一行文本。

  4. 判断是否遇到新分卷开头

    • 通过判断字符串 '卷 第' 是否在当前行中,识别分卷标题行。

    • 例如“卷 第1卷”,代表这是一个新的分卷开始。

  5. 新卷文件的创建与切换

    • 如果是第一次遇到分卷标题(flag == 0),则新建一个对应的分卷文件,准备写入。

    • 如果之前已经打开了分卷文件,先关闭旧文件,再打开新分卷文件。

    • 文件名以当前行内容加 .txt 后缀命名,并保存在 .\\红楼梦\\分卷 目录下。

  6. 非分卷标题行内容处理

    • 过滤空行(line.strip() != "")和广告信息(不包含 "手机电子书·大学生小说网")。

    • 合格的行写入当前打开的分卷文件中。

  7. 结束时关闭所有文件

    • 循环结束后,关闭当前分卷文件和整本小说文件。


运行效果

  • 红楼梦.txt按照“卷 第X卷”的行作为分界点,生成多个如“卷 第1卷.txt”、“卷 第2卷.txt”等文件,分别保存在 红楼梦\分卷 文件夹中。

  • 每个分卷文件包含对应的章节内容,便于后续的分词和关键词分析。


代码二:对每个分卷提取词典

1. 导入必要库

import pandas as pd
import os
import jieba
  • pandas 用于创建和操作结构化数据(DataFrame),方便后续处理。

  • os 用于遍历文件夹,获取分卷文件路径。

  • jieba 是一个常用的中文分词库,用于将连续文本切分成词语。


2. 读取分卷文本

filePaths = []
fileContents = []
for root, dirs, files in os.walk(r"./红楼梦/分卷"):for name in files:filePath = os.path.join(root, name)  # 获取每个分卷的完整路径print(filePath)filePaths.append(filePath)  # 记录该路径到filePaths列表f = open(filePath, 'r', encoding='utf-8')fileContent = f.read()  # 读取整个文件内容为字符串f.close()fileContents.append(fileContent)  # 把内容加入列表
  • 使用 os.walk 递归遍历 ./红楼梦/分卷 文件夹,获取所有分卷文本文件路径和名称。

  • 将每个分卷文件的路径和对应的文本内容分别存储到 filePathsfileContents 两个列表中。

  • 读取文件时用 UTF-8 编码,保证中文字符正确读取。


3. 构建 pandas DataFrame

corpos = pd.DataFrame({'filePath': filePaths,'fileContent': fileContents
})
  • 将分卷的路径和内容以字典形式传入,生成一个二维表格结构的 DataFrame。

  • 每一行对应一个分卷文件,包含:

    • filePath:该分卷的文件路径

    • fileContent:该分卷对应的文本内容(字符串)

这样方便后续批量处理。


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

jieba.load_userdict(r"./红楼梦/红楼梦词库.txt")
stopwords = pd.read_csv(r"./红楼梦/StopwordsCN.txt",encoding='utf-8', engine='python', index_col=False)
  • jieba.load_userdict() 用来加载用户定义的词典,解决默认词库中可能没有的专有名词、人名地名、书中特殊词汇的分词准确度问题。

  • stopwords 读取停用词文件,一般是高频无实际含义的词(如“的”、“了”、“在”等),需要过滤掉,避免影响后续分析。

stopwords是一个 DataFrame,其中一列(假设列名为stopword)包含所有停用词。


5. 创建分词输出文件

file_to_jieba = open(r"./红楼梦/分词后汇总.txt", 'w', encoding='utf-8')
  • 打开一个新的文本文件,用来存储所有分卷的分词结果。

  • 使用写入模式,每个分卷分词结果写入一行,方便后续分析。


6. 对每个分卷逐条处理

for index, row in corpos.iterrows():juan_ci = ''filePath = row['filePath']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')  # 写入该卷分词结果,换行区分不同卷
  • corpos.iterrows() 按行遍历 DataFrame,每行对应一个分卷。

  • 取出文本内容后,用 jieba.cut() 对文本分词,得到一个可迭代的词语序列。

  • 对每个词:

    • 判断它是否为停用词(通过停用词列表过滤)

    • 判断是否为空白(防止多余空格或特殊符号)

  • 过滤后的词汇拼接成字符串,用空格分隔,形成分词后的“句子”。

  • 每个分卷的分词结果写入一行,方便后续按行读取、TF-IDF等分析。


7. 关闭文件

file_to_jieba.close()
  • 关闭分词结果文件,保证写入完整。


运行结果:


代码三:计算 TF-IDF

from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd

1. 读取分词后的汇总文本

File = open(r".\红楼梦\分词后汇总.txt", 'r', encoding='utf-8')
corpus = File.readlines()  # 每行作为一个文档内容
  • 每行对应一卷(或一回)的分词结果。

  • corpus 是一个列表,corpus[i] 表示第 i 卷的文本。


2. 初始化并计算 TF-IDF

from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer()
tfidf = vectorizer.fit_transform(corpus)
wordlist = vectorizer.get_feature_names()
  • TfidfVectorizer() 自动执行:

    • 统计每个词的词频(TF)

    • 计算逆文档频率(IDF)

    • 得到每个词在每个文档中的 TF-IDF 值

  • wordlist 是词汇表(所有出现的词)。


3. 构建 DataFrame 存储结果

df = pd.DataFrame(tfidf.T.todense(), index=wordlist)
  • tfidf 是稀疏矩阵(需要 .todense() 转成稠密矩阵才能放进 DataFrame)。

  • 转置 .T 后:

    • 行(index)是词汇

    • 列是文档(每卷)


 可以打印出部分数据直观理解:

print(wordlist)
print(tfidf)
# print(tfidf.todense())
print(df.head(20))

wordlist:词汇表

tfidf:

(0,14385)即表示一个二维坐标

  • 0/119 → 这是文档编号(row index),表示这是第 1 篇文档(编号从 0 开始)。

  • 14385→ 这是词在词汇表(vocabulary)中的编号(column index),对应某个特定的单词,比如可能是 "machine""learning"(具体要看 vectorizer.get_feature_names_out() 对应表)。

  • 0.01659769526115283→ 这是这个单词在该文档中的 TF-IDF 权重,数值越大,说明这个单词在这篇文章中越重要(出现频率高,但在其他文档中不常见)。

df:

  • 行索引(index)_______txt一一 等是分词后的词语。

  • 列索引(0, 1, 2, ...):表示第几卷(文档),从 0 列到 119 列,说明总共有 120 卷/文档。

  • 单元格的数值:该词在该卷里的 TF-IDF 权重(越大表示该词在这卷中越重要)。


4. 提取每卷的 Top 10 关键词

for i in range(len(corpus)):top_keywords = df.iloc[:, i].sort_values(ascending=False).head(10)print(f'第{i+1}回的核心关键词:\n{top_keywords}')
  • 取第 i 列(即第 i 卷的所有词的 TF-IDF 值)

  • sort_values(ascending=False) 降序排列

  • head(10) 取权重最高的 10 个关键词

结果:


扩展:可视化每卷 Top 10 关键词

以第 1 卷为例,绘制柱状图:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# [:, 0]取第1回,[:, 119]取第120回
top_keywords = df.iloc[:, 0].sort_values(ascending=False).head(10)plt.figure(figsize=(8,5))
plt.barh(top_keywords.index, top_keywords.values, color='skyblue')
plt.gca().invert_yaxis()  # 倒序
plt.title("第1回的TF-IDF关键词")
plt.xlabel("TF-IDF权重")
plt.show()


改进建议

  1. 自动去掉空行

    corpus = [line.strip() for line in corpus if line.strip()]
    

    避免空文档导致向量化器报错。

  2. 指定分隔符
    因为你的分词结果是用空格分隔的,可以告诉 TfidfVectorizer

    vectorizer = TfidfVectorizer(token_pattern=r"(?u)\b\w+\b")
    
  3. 保存结果
    直接把每卷关键词存到 CSV,便于后续分析:

    all_keywords = {}
    for i in range(len(corpus)):all_keywords[f"第{i+1}回"] = df.iloc[:, i].sort_values(ascending=False).head(10).index.tolist()
    pd.DataFrame.from_dict(all_keywords, orient='index').to_csv("红楼梦_TF-IDF关键词.csv", encoding="utf-8-sig")
    

总结

本文实现了从原始《红楼梦》文本关键词提取的完整流程:

  1. 对正文进行分卷

  2. 读取分卷内容

  3. 自定义词典 + 停用词过滤

  4. 分词并保存

  5. 使用 jieba.analyse.extract_tags 进行 TF-IDF 关键词提取

  6. TfidfVectorizer计算 TF-IDF

  7. 扩展:可视化权重排序

通过这种方式,我们不仅能提取整本书的主题关键词,还能按卷分析主题变化,为文本挖掘、主题建模、人物关系分析等工作打下基础。

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

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

相关文章

一周学会Matplotlib3 Python 数据可视化-多子图及布局实现

锋哥原创的Matplotlib3 Python数据可视化视频教程: 2026版 Matplotlib3 Python 数据可视化 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 课程介绍 本课程讲解利用python进行数据可视化 科研绘图-Matplotlib,学习Matplotlib图形参数基本设置&…

Spark执行计划与UI分析

文章目录1.Spark任务阶段划分1.1 job,stage与task1.2 job划分1.3 stage和task划分2.任务执行时机3.task内部数据存储与流动4.根据sparkUI了解Spark执行计划4.1查看job和stage4.2 查看DAG图4.3查看task1.Spark任务阶段划分 1.1 job,stage与task 首先根据…

16-docker的容器监控方案-prometheus实战篇

文章目录一.前置知识1.监控与报警2.监控系统的设计3.监控系统的分类二、prometheus概述1.什么是prometheus2.prometheus的历史3.为什么要学习prometheus4.prometheus的使用场景5.prometheus的宏观架构图6.prometheus软件下载地址三、部署prometheus server监控软件1.同步集群时…

集成电路学习:什么是Image Processing图像处理

Image Processing,即图像处理,是计算机视觉、人工智能、多媒体等领域的重要基础。它利用计算机对图像进行分析、加工和处理,以达到预期目的的技术。以下是对图像处理的详细解析: 一、定义与分类 定义: 图像处理是指用计算机对图像进行分析,以达到所需结果的技术,又称…

基于Android的随身小管家APP的设计与实现/基于SSM框架的财务管理系统/android Studio/java/原生开发

基于Android的随身小管家APP的设计与实现/基于SSM框架/android Studio/java/原生开发

Web 开发 16

1 在 JavaScript(包括 JSX)中,函数体的写法和返回值处理在 JavaScript(包括 JSX)中,函数体的写法和返回值处理确实有一些简洁的语法规则,尤其是在箭头函数中。这些规则常常让人混淆,…

超高车辆碰撞预警系统如何帮助提升城市立交隧道安全?

超高车辆带来的安全隐患立交桥和隧道的设计通常基于常规车辆的高度标准。然而,随着重型运输业和超高货车的增加,很多超高车辆会误入这些限高区域,造成潜在的安全隐患。超高车辆与立交桥梁或隧道顶盖发生碰撞时,可能导致结构受损&a…

三种变量类型在局部与全局作用域的区别

一、基本概念作用域(Scope): 全局作用域:定义在所有函数外部的变量或函数,具有文件作用域,生命周期为整个程序运行期间。局部作用域:定义在函数、块(如 {})或类内部的变量…

InfluxDB 数据迁移工具:跨数据库同步方案(二)

六、基于 API 的同步方案实战6.1 API 原理介绍InfluxDB 提供的 HTTP API 是实现数据迁移的重要途径。通过这个 API,我们可以向 InfluxDB 发送 HTTP 请求,以实现数据的读取和写入操作。在数据读取方面,使用GET请求,通过指定数据库名…

JVM安全点轮询汇编函数解析

OpenJDK 17 源码的实现逻辑,handle_polling_page_exception 函数在方法返回时的调用流程如下:调用流程分析:栈水印检查触发跳转:当线程执行方法返回前的安全点轮询时(MacroAssembler::safepoint_poll 中 at_returntrue…

Linux怎么查看服务器开放和启用的端口

在 Linux 系统中,可以通过以下方法查看 服务器开放和启用的端口。以下是详细的步骤和工具,适用于不同场景。1. 使用 ss 查看开放的端口ss 是一个现代化工具,用于显示网络连接和监听的端口。1.1 查看正在监听的端口运行以下命令:ba…

XF 306-2025 阻燃耐火电线电缆检测

近几年随着我国经济快速的发展,电气火灾呈现高发趋势,鉴于电线电缆火灾的危险性,国家制定了阻燃,耐火电线电缆的标准,为企业,建设方,施工方等的生产,选材提供了指引。XF 306-2025 阻…

【Java|第二十篇】面向对象(十)——枚举类

目录 (四)面向对象: 12、枚举类: (1)概述: (2)枚举类的定义格式: (3)编译与反编译: (4)Enum类…

第二十一天-OLED显示实验

一、OLED显示原理1、OLED名词解释OLED可以自发光,无需背光光源。2、正点原子OLED模块模块总体概述模块接口模式选择MCU与模块外部连接8080并口读写过程OLED显存因为要进行显示,所以需要有显存。显存容量为128 x 8 byte,一个点用一位表示。SSD…

会议系统核心流程详解:创建、加入与消息交互

一、系统架构概览 会议系统采用"主进程线程池进程池"的分层架构,实现高并发与业务隔离: #mermaid-svg-fDJ5Ja5L3rqPkby0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fDJ5Ja5L3r…

Spring 创建 Bean 的 8 种主要方式

Spring(尤其是 Spring Boot)提供了多种方式来让容器创建和管理 Bean。Component、Configuration Bean、EnableConfigurationProperties 都是常见方式。 下面我为你系统地梳理 Spring 创建 Bean 的所有主要方式,并说明它们的使用场景和区别。…

React 第七十节 Router中matchRoutes的使用详解及注意事项

前言 matchRoutes 是 React Router v6 提供的一个核心工具函数,主要用于匹配路由配置与当前路径。它在服务端渲染(SSR)、数据预加载、权限校验等场景中非常实用。下面详细解析其用法、注意事项和案例分析: 1、基本用法 import { m…

iSCSI服务配置全指南(含服务器与客户端)

iSCSI服务配置全指南(含服务器与客户端)一、iSCSI简介 1. 概念 互联网小型计算机系统接口(Internet Small Computer System Interface,简称iSCSI)是一种基于TCP/IP的协议,其核心功能是通过IP网络仿真SCSI高…

堆(Heap):高效的优先级队列实现

什么是堆?堆是一种特殊的完全二叉树,满足以下性质:堆序性:每个节点的值与其子节点满足特定关系最小堆:父节点 ≤ 子节点(根最小)最大堆:父节点 ≥ 子节点(根最大&#xf…

朝花夕拾(四) --------python中的os库全指南

目录 Python os模块完全指南:从基础到高阶文件操作 1. 引言:为什么需要os模块? 1.1 os模块的重要性 1.2 适用场景 1.3 os模块的"瑞士军刀"特性 2. os模块基础功能 2.1 文件与目录操作 2.1.1 核心方法介绍 2.1.2 避坑指南 …