本项目以 “文本结构化→特征量化→结果分析” 为核心逻辑,先将非结构化的全文 txt 拆分为结构化章节文件,再通过分词和 TF-IDF 算法实现词汇重要性量化,可快速适配其他长篇文本的分析需求
关键技术点包括:正则匹配定位章节、jieba 分词适配古典文学、TF-IDF 算法量化词汇重要性。
一、技术栈准备
本次实战所需的核心库:
- 基础库:
os(文件 / 路径处理)、re(正则匹配)、pandas(数据结构化); - 中文处理:
jieba(中文分词),支持自定义词库; - 算法库:
sklearn.feature_extraction.text.TfidfVectorizer(TF-IDF 特征提取)。
二、实战步骤:从文本拆分到关键词提取
(一)步骤 1:拆分《红楼梦》为 120 个章节文件
import os # python标准库,不需要安装。关于操作系统的库
import re
import pandas as pd
# ===================== 核心优化:适配文本格式+解决报错 =====================
# 1. 确保保存目录存在(避免路径不存在报错)
output_dir = r'.\红楼梦\分卷1'
os.makedirs(output_dir, exist_ok=True)
# 2. 打开源文件(使用with语句自动关闭,更安全)
with open(r'.\红楼梦\红楼梦.txt', encoding='utf-8') as file:
flag = 0 # 用来标记当前是不是在第一次保存文件
juan_file = None # 初始化文件对象,避免未定义报错
# 定义:清理Windows非法文件名字符(解决OSError报错)
def clean_filename(filename):
illegal_chars = r'[\\/:*?"<>|,。?!;:""''《》()()【】]'
clean_name = re.sub(illegal_chars, '', filename) # 移除非法字符
return clean_name[:50] + '.txt' # 限制文件名长度,避免超长
# 定义:精准匹配“卷+回”标题(适配文本中“上卷 第一回 XXX”格式)
chapter_pattern = re.compile(r'^[ \s]*([上下]卷\s+第[一二三四五六七八九十百零]+回.*)$', re.MULTILINE)
# chapter_pattern = re.compile(r'^[ \s]*([上下]卷)?\s*第([一二三四五六七八九十百]+|[\d]{1,3})回.*$', re.MULTILINE)
for line in file: # 开始遍历整个红楼梦
line_strip = line.strip()
# 精准匹配“卷+回”标题(核心:只识别章节标题行)
match = chapter_pattern.match(line_strip)
if match:
# 提取纯净的标题(去除前后空格/全角空格)
juan_title = match.group(1).strip()
# 清理文件名(关键:避免非法字符)
juan_name = clean_filename(juan_title)
# 构建完整路径
path = os.path.join(output_dir, juan_name)
print(f"正在创建文件:{path}")
if flag == 0: # 判断是否是第1次读取到卷+回标题
# 关闭初始可能存在的空文件
if juan_file:
juan_file.close()
# 创建第1个卷文件
juan_file = open(path, 'w', encoding='utf-8')
# 写入标题(保留原格式)
juan_file.write(line)
flag = 1
else: # 不是第1次读取到卷+回标题
# 关闭上一次的文件对象
juan_file.close()
# 创建新的卷文件
juan_file = open(path, 'w', encoding='utf-8')
# 写入标题(保留原格式)
juan_file.write(line)
continue
# 写入章节内容(仅当文件对象已创建时,避免空写)
if juan_file is not None:
juan_file.write(line)
# 最终关闭文件(避免资源泄露)
if juan_file:
juan_file.close()
print(f"\n✅ 拆分完成!共生成{flag}个卷文件,保存在:{output_dir}")
- 正则匹配:覆盖《红楼梦》所有回目标题格式,确保 120 回都能被精准识别;
- 文件名清理:避免因特殊字符导致文件创建失败;
- 文件管理:通过
current_file变量管理当前写入的文件,确保章节内容正确归属
(二)步骤 2:结构化读取章节数据
import pandas as pd
import os # 处理操作系统的文件,python标准库,和操作系统打交道!
# 41
filePaths = [] # #[#保存文件的路径] filePaths: ['.\\红楼梦\\分卷\\上卷 第一回 甄士隐梦幻识通灵\\u3000']
fileContents = [] # #[#保存文件路径对应的内容] fileContents: []
# 42
for root, dirs, files in os.walk(r'.\红楼梦\分卷1'): # os.walk是直接对文件夹进行遍历 #os.list
for name in files: # name: '下卷 第八十四回 试文字宝玉始提亲 探惊风贾环重结怨.txt'
filePath = os.path.join(root, name) # root+'\\'+name获取每个文件的路径 #filePath:
filePaths.append(filePath) # 将文件路径添加到列表filePaths中
f = open(filePath, 'r', encoding='utf-8') # f: <_io.TextIOWrapper name='.\\红楼梦\\
fileContent = f.read() # 读取每一个的文件中内容 fileContent: "
f.close()
fileContents.append(fileContent) # 将每一卷的文件内容添加到列表fileContents中
corpos = pd.DataFrame({ # 将文件路径及文件内容添加为DataFrame框架中 numpy ->c corpos: f
'filePath': filePaths, # 'int64' str() float('3.142')
'fileContent': fileContents}) # 训练大家的数据处理能力
print(corpos)
目录遍历:自动获取所有章节文件,无需手动指定路径;
结构化存储:将文件路径和内容关联,便于后续按章节处理。
(三)步骤 3:中文分词 + 停用词过滤
import jieba # 保存的词库就是 辞海, 形容词、语气词 不会作为核心关键词的。提前我就剔除TF-IDF的。
jieba.load_userdict(r'.\红楼梦\红楼梦词库.txt') # 导入分词库,把红楼梦专属的单词添加到jieba词库中。
# 导入停用词库 ,把无关心的词提出。
stopwords = pd.read_csv(r'.\红楼梦\StopwordsCN.txt', # StopwordsCN.txt保存的是 常见的助动词
encoding='utf8', engine='python', index_col=False) # engine读取文件时的解析引擎
file_to_jieba = open(r'.\红楼梦\分词后汇总1.txt', 'w', encoding='utf-8') # 创建一个新文本 file_to
for index, row in corpos.iterrows(): # iterrows遍历行数据 index: 119 row: ('filePath',
juan_ci = '' # 空的字符串,处理后的单词依次添加到juan_ci后面 juan_ci: '手机 电子书 大学生 小说
fileContent = row['fileContent']
segs = jieba.cut(fileContent) # 对文本内容进行分词,返回一个可遍历的迭代器 segs: <gen
for seg in segs: # 遍历每一个词 seg: '\n'
if seg not in stopwords.stopword.values and len(seg.strip()) > 0: # 剔除停用词和字符为
juan_ci = juan_ci + seg + ' ' # juan_ci = juan_ci + '电子' + '电子'
file_to_jieba.write(juan_ci + '\n')
file_to_jieba.close()
自定义词库:解决 jieba 对 “贾宝玉、林黛玉” 等古典文学词汇的识别问题;
停用词过滤:移除无意义词汇,仅保留核心语义词汇,提升后续分析准确性。
(四)步骤 4:TF-IDF 提取核心关键词
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
inFile = open(r".\红楼梦\分词后汇总1.txt", 'r', encoding='utf-8')
corpus = inFile.readlines() # 返回一个列表,列表一个元素就是一行内容,一行内容一篇分词后的文章
vectorizer = TfidfVectorizer() # 类,转为TF-IDF的向量器
tfidf = vectorizer.fit_transform(corpus) # 传入数据,返回包含TF-IDF的向量值
wordlist = vectorizer.get_feature_names_out() # 获取特征名称,所有的词
df = pd.DataFrame(tfidf.T.todense(), index=wordlist) # tfidf.T.todense() 恢复为稀疏矩阵
# 下面的任务就是对表格进行排序 pandas
for i in range(len(corpus)): # 排序,将重要的关键词排序在最前面
featurelist = df.iloc[:, i].to_list() # 通过索引号获取第i列的内容并转换为列表
resdict = {} # 排序以及看输出结果对不对
for j in range(0, len(wordlist)):
resdict[wordlist[j]] = featurelist[j] # [('贾宝玉',0.223), ()]
resdict = sorted(resdict.items(), key=lambda x: x[1], reverse=True) # 字典的键值对,元组数据类型
print('第{}回的核心关键词:'.format(i+1), resdict[0:10])
TF-IDF 向量转换:将分词文本转为数学矩阵,量化词汇重要性;
关键词排序:按 TF-IDF 值降序排序,提取前 10 个关键词,快速定位章节核心内容。
运行结果:


转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/m0_74373135/article/details/158852888



