《红楼梦》每一回都在说啥? 三步骤教你用TF-IDF找到答案!

目录

一、TF-IDF简介

二、代码实现

步骤一:提取红楼梦的每一回保存在一个文件夹下

步骤二:对每一回进行分词,并去除停用词

步骤三:打印出每一回中10个TF-IDF值最高的词

三、完整代码展示:


一、TF-IDF简介

TF-IDF(Term Frequency-Inverse Document Frequency)是一种常用的文本特征表示方法,用于评估一个词对于一个文档集合的重要性,它结合了词频(TF)和逆文档频率(IDF)的概念。简单来说:TF-IDF 可以帮助我们找到在一个文档集合中具有较高区分度和重要性的词汇。详情可见我的另一篇博客:TF-IDF:文本挖掘的基石

二、代码实现

需要用到以下几个文件(需要的可以自行下载):

红楼梦.txt

红楼梦词库.txt

StopwordsCN.txt

步骤一:提取红楼梦的每一回保存在一个文件夹下

1、导入jieba库用于中文分词,os库用于文件和目录操作。

import jieba
import os

 2、打开名为"红楼梦.txt"的文本文件,指定了文件的编码为UTF-8。

file=open('.\红楼梦.txt',encoding='utf8')

 3、加入一个标志变量,用于后面判断是否已经开始处理卷的内容。

flag=0

4、 创建一个文件对象,用于保存卷的开头内容。文件名为"红楼梦卷开头.txt",以写入模式('w')打开,并指定编码为UTF-8。

juan_file=open('.\红楼梦卷开头.txt','w',encoding='utf8')

 5、遍历文本文件的每一行,将文本文件按照卷进行拆分,并将每卷的内容保存到不同的文件中。

(具体操作请查看代码上方的注释)

for line in file:
# 检查当前行是否包含"卷 第"这个字符串,以判断是否为卷的开头行
    if '卷 第' in line:
# 如果当前行是卷的开头行,它将提取卷的名称,并加上".txt"后缀,以作为新卷文件的名称
        juan_name = line.strip() + '.txt'
# 使用os.path.join函数构建了新卷文件的完整路径,将卷文件保存在名为"分卷"的子目录下
        path = os.path.join('.\\分卷\\', juan_name)
        print(path)
# 这个条件检查flag变量的值,如果为0(表示尚未开始处理卷的内容),则创建新的卷文件,并将flag设置为1,表示已经开始处理卷的内容
        if flag == 0:
            juan_file = open(path, 'w', encoding='utf8')
            flag = 1
#如果flag不为0,表示已经开始处理卷的内容,那么需要关闭当前的卷文件,然后再次创建新的卷文件
        else:
            juan_file.close()
            juan_file = open(path, 'w', encoding='utf8')
# 继续处理下一行
        continue
# 将当前行写入当前卷文件中,实现卷内容的分割
    juan_file.write(line)
# 关闭最后一个卷文件,完成整个分卷操作
juan_file.close()

运行后所得文件夹‘‘分卷’’展示:

总结:

完成这一步骤后,我们已经将每一回的内容保存到不同的文件中,以便进一步的处理或分析。 

步骤二:对每一回进行分词,并去除停用词

1、导入pandas库,用于数据处理操作

import pandas as pd

 2、创建两个空列表,用于存储文件路径和文件内容。

filepaths=[]
filecontents=[]

3、 使用os.walk遍历目录".\分卷"下的文件。

(具体操作请查看代码上方的注释)

#使用os.walk遍历目录".\分卷"下的文件
for root,dirs,files in os.walk(r'.\分卷'):
    for name in files:
#构建文件路径,将目录和文件名合并为完整的路径
        filepath=os.path.join(root,name)
#将文件路径添加到filepaths列表中
        filepaths.append(filepath)
#打开文件,以只读模式读取文件内容,并指定编码为UTF-8
        f=open(filepath,'r',encoding='utf8')
#读取文件内容
        filecontent=f.read()
#关闭文件
        f.close()
#将文件内容添加到filecontents列表中
        filecontents.append(filecontent)

4、 使用pandas的DataFrame结构创建一个数据框,将文件路径和文件内容作为两列数据。

corpos=pd.DataFrame({
    'filepath':filepaths,
    'filecontent':filecontents
})

 5、导入自定义分词词典,通过加载词典提供更准确的分词。

jieba.load_userdict(r'.\红楼梦词库.txt')

6、 读取停用词表,该表包含需要过滤的无意义词语。这里使用pandas的read_csv函数读取文本文件,指定编码为UTF-8,使用Python的解析引擎。

stopwords=pd.read_csv(r'StopwordsCN.txt',encoding='utf8',engine='python',index_col=False)

7、 创建文件对象,以写入模式('w')打开,用于保存分词结果。文件名为"分词后汇总.txt"。

file_to_jieba=open(r'.\分词后汇总.txt','w',encoding='utf8')

 8、迭代DataFrame的每一行数据。

(具体操作请查看代码上方的注释)

for index,row in corpos.iterrows():
#创建一个空字符串,用于存储分词结果
    juan_ci=''
#获取当前行中的文件路径和文件内容
    filepath=row['filepath']
    filecontent=row['filecontent']
#使用jieba库对文件内容进行分词,返回一个分词生成器
    segs=jieba.cut(filecontent)
#遍历分词生成器中的每个分词
    for seg in segs:
#检查分词不属于停用词且不是空字符串
        if seg not in stopwords.stopword.values and len(seg.strip())>0:
#将符合条件的分词加入到juan_ci字符串,并用空格分隔
            juan_ci +=seg+' '
#将分词结果写入文件,并在末尾添加换行符
    file_to_jieba.write(juan_ci+'\n')
#关闭文件
file_to_jieba.close()

 运行后所得文件‘‘分词后汇总.txt’’展示:

 总结:这一步骤是读取分割后的《红楼梦》每一回的文件,使用jieba库进行中文分词,过滤停用词后将分词结果写入新文件,这里的每一行内容都是处理后的每一回的内容的分词。

步骤三:打印出每一回中10个TF-IDF值最高的词

1、导入 scikit-learn 库中的 TfidfVectorizer 类,用于计算 TF-IDF 特征。

from sklearn.feature_extraction.text import TfidfVectorizer

 2、打开分词后的文本文件,以读取模式打开,使用指定的 UTF-8 编码。

inFils=open(r'分词后汇总.txt','r',encoding='utf8')

3、 读取文件内容,将每一行作为一个文档存储在列表 corpus 中。

corpus=inFils.readlines()

4、 创建一个 TF-IDF 向量化器对象 vectorizer,用于将文本数据转换为 TF-IDF 特征。

vectorizer=TfidfVectorizer()

5、 使用 fit_transform() 方法将文本数据 corpus 转换为 TF-IDF 特征矩阵 tfidf

tfidf=vectorizer.fit_transform(corpus)

6、 获取特征词汇表,存储在列表 wordlist 中,这些词汇是 TF-IDF 特征的列标签。

wordlist=vectorizer.get_feature_names_out()

7、 创建一个 DataFrame 对象 df,其中包含 TF-IDF 特征矩阵 tfidf 的转置,并使用词汇表 wordlist 作为行索引。

df=pd.DataFrame(tfidf.T.todense(),index=wordlist)

8、 开始循环,遍历每个文档。

(具体操作请查看代码上方的注释)

for i in range(len(corpus)):
#获取当前文档的 TF-IDF 特征向量,并将其转换为列表 featurelist
    featurelist=df.iloc[:,i].to_list()
#创建一个空字典 resdict,用于存储每个词语的 TF-IDF 权重
    resdict={}
#开始内层循环,遍历词汇表中的每个词语
    for j in range(0,len(wordlist)):
#将词语和对应的 TF-IDF 权重添加到 resdict 字典中
        resdict[wordlist[j]]=featurelist[j]
#将 resdict 字典中的键值对按照 TF-IDF 权重进行降序排序,并存储在 resdict 中
    resdict=sorted(resdict.items(),key=lambda x:x[1],reverse=True)
#打印排序后的 resdict 字典中权重最高的前 10 个词语,即每个文档中 TF-IDF 最高的词语列表
    print(resdict[0:10])

9、运行结果:

总结:

这样就得到了《红楼梦》中每一回里TF-IDF值最高的10个词,我们就可以大概知道这一回主要讲了什么内容。 

三、完整代码展示:

#红楼梦每一回关键字提取(tf-idf实现)
#步骤1:提取红楼梦的每一回保存在一个文件夹下
import jieba
import os

file=open('.\红楼梦.txt',encoding='utf8')
flag=0
juan_file=open('.\红楼梦卷开头.txt','w',encoding='utf8')
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='utf8')
            flag=1
        else:
            juan_file.close()
            juan_file=open(path,'w',encoding='utf8')
        continue
    juan_file.write(line)
juan_file.close()
# #步骤2:对每一回进行分词,并去除停用词
import pandas as pd
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)
        f=open(filepath,'r',encoding='utf8')
        filecontent=f.read()
        f.close()
        filecontents.append(filecontent)
corpos=pd.DataFrame({
    'filepath':filepaths,
    'filecontent':filecontents
})
# print(corpos)

jieba.load_userdict(r'.\红楼梦词库.txt')#导入分词库
stopwords=pd.read_csv(r'StopwordsCN.txt',encoding='utf8',engine='python',index_col=False)
file_to_jieba=open(r'.\分词后汇总.txt','w',encoding='utf8')
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')
file_to_jieba.close()

#步骤3:打印出每一回中10个tf-idf值最高的词
from sklearn.feature_extraction.text import TfidfVectorizer
inFils=open(r'分词后汇总.txt','r',encoding='utf8')
corpus=inFils.readlines()
vectorizer=TfidfVectorizer()
tfidf=vectorizer.fit_transform(corpus)
wordlist=vectorizer.get_feature_names_out()
df=pd.DataFrame(tfidf.T.todense(),index=wordlist)
for i in range(len(corpus)):
    featurelist=df.iloc[:,i].to_list()
    resdict={}
    for j in range(0,len(wordlist)):
        resdict[wordlist[j]]=featurelist[j]
    resdict=sorted(resdict.items(),key=lambda x:x[1],reverse=True)
    print(resdict[0:10])
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值