主页 > 手机  > 

自然语言处理NLP03案例——提取小说红楼梦各卷关键词TOP10

自然语言处理NLP03案例——提取小说红楼梦各卷关键词TOP10

如下图,是红楼梦的本文小说,现在我们要提取出红楼梦每卷排名前十的关键词

为了更顺利的完成要求,我们将任务拆解为以下四个节点

将这个文件中上下卷共120卷拆分开,每一卷内容保存为一个新的文本文件,文件名是相应卷名 ,所有卷放入文件夹 .\红楼梦

打印出每卷地址与内容

对每一卷进行分词

计算TF-IDF值,保存每卷TOP10关键词

(快速跳转) 

                          拆分红楼梦120卷并另存

打印分卷地址与内容

对每一卷进行分词

计算TF-IDF值并保存每卷中top10关键词


拆分红楼梦120卷并另存

步骤:

按卷分割文件:

代码通过检测每一行是否包含 卷 第,来判断是否需要开始一个新的分卷文件。

每个分卷文件以卷名命名,并保存在 红楼梦分卷 目录下。

初始文件:

代码会先创建一个临时文件 红楼梦开头.txt,用于保存尚未分卷的内容。

如果发现 卷 第 后,会关闭临时文件,并开始按卷保存内容。

文件路径:

使用 os.path.join 生成分卷文件的完整路径,确保路径跨平台兼容。

文件操作:

使用 open() 打开文件,write() 写入文件,close() 关闭文件。

代码:

import os ​ # 打开《红楼梦》的原始文本文件,指定编码为utf-8 file = open('红楼梦.txt', encoding='utf-8') # 设置一个标志变量flag,用于判断是否需要创建新的分卷文件 flag = 0 # 打开一个临时文件'红楼梦开头.txt',用于保存未分卷的内容 chapter_file = open('.\红楼梦开头.txt', 'w', encoding='utf-8') ​ # 逐行读取《红楼梦》的原始文件 for line in file:    # 检查当前行是否包含“卷 第”,这是分卷的标志    if '卷 第' in line:        # 提取卷名,并去掉空白字符,生成分卷文件的名称        chapter_name = line.strip() + '.txt'        # 生成分卷文件的完整路径,保存在`红楼梦分卷`目录下        path = os.path.join('.\\红楼梦分卷\\', chapter_name)        print(path)  # 打印分卷文件的路径        # 如果flag为0,表示这是第一个分卷,直接创建并写入文件        if flag == 0:            chapter_file = open(path, 'w', encoding='utf-8')            flag = 1  # 将flag置为1,表示已开始分卷        else:            # 如果flag不为0,表示之前已经有分卷文件了,先关闭当前文件            chapter_file.close()            # 再创建一个新的分卷文件            chapter_file = open(path, 'w', encoding='utf-8')        # 跳过本行,不将分卷标志行写入分卷文件        continue    # 将当前行写入分卷文件    chapter_file.write(line) # 循环结束后,关闭最后一个分卷文件 chapter_file.close()

运行结果:

1)分卷

2)红楼梦未分卷的内容

打印分卷地址与内容

步骤:

文件遍历:

使用 os.walk 遍历 .\红楼梦分卷 目录及其子目录下的所有文件。

对每个文件,获取其完整路径并打印。

文件读取:

打开文件并读取所有行。

跳过前两行(从第3行开始)拼接文件内容。

数据存储:

将文件路径和文件内容分别存储在列表 filePaths 和 fileContents 中。

创建 DataFrame:

使用 pandas 将文件路径和文件内容组合成一个 DataFrame。

输出结果:

打印 DataFrame,显示文件路径和文件内容的对应关系。

代码: ​

import pandas as pd import os # 初始化两个列表,分别用于存储文件路径和文件内容 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')        lines = f.readlines()  # 读取文件的所有行        fileContent = ''.join(lines[2:])  # 从第3行开始拼接文件内容(跳过前两行)        f.close()  # 关闭文件 ​        fileContents.append(fileContent)  # 将文件内容添加到列表中 ​ # 使用 pandas 创建一个 DataFrame,包含文件路径和文件内容 corpos = pd.DataFrame({    'filePath': filePaths,  # 文件路径列    'fileContent': fileContents  # 文件内容列 }) ​ # 打印 DataFrame print(corpos)

运行结果:

对每一卷进行分词

步骤:

加载自定义词典:

使用 jieba.load_userdict 加载 红楼梦词库.txt,确保分词时能正确识别《红楼梦》中的专有词汇(例如人名、地名等)。

读取停用词表:

使用 pandas 读取停用词表 StopwordsCN.txt,停用词是分词后需要过滤掉的无意义词(例如“的”、“了”、“是”等)。

遍历文件内容:

通过 corpos.iterrows() 遍历 corpos DataFrame 中的每一行,获取文件路径和文件内容。

分词处理:

使用 jieba.cut 对文件内容进行分词。

遍历分词结果,过滤掉停用词和空白词(长度为 0 的词)。

保存分词结果:

将处理后的分词结果写入到 红楼梦分词后汇总.txt 文件中。

代码:

import jieba # 加载自定义词典,确保分词结果符合《红楼梦》的专有词汇 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='utf-8') ​ # 遍历 corpos DataFrame 中的每一行 for index, row in corpos.iterrows():    juan_ci = ''  # 初始化一个空字符串,用于保存当前卷的分词结果    filePath = row['filePath']  # 获取当前文件路径    fileContent = row['fileContent']  # 获取当前文件内容    # 使用 jieba 对文件内容进行分词    segs = jieba.cut(fileContent)    # 遍历分词结果,去除停用词和空白词    for seg in segs:        # 如果当前词不是停用词且长度大于 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()

运行结果:

1)运行成功界面

2)红楼梦分词后汇总.txt

计算TF-IDF值并保存每卷中top10关键词

步骤:

读取分词结果:

打开分词后的汇总文件 红楼梦分词后汇总.txt,读取所有行作为语料库。

计算 TF-IDF 值:

使用 TfidfVectorizer 对语料库进行向量化,生成 TF-IDF 矩阵。

获取词汇列表:

使用 get_feature_names_out() 获取所有词汇(特征词)。

转换为 DataFrame:

将 TF-IDF 矩阵转换为 DataFrame,转置是为了让每一列对应一卷,每一行对应一个词汇。

提取核心关键词:

遍历每一卷,提取其 TF-IDF 值最高的前 10 个核心关键词。

保存结果:

将每回的核心关键词 TOP10 写入文件 红楼梦分节关键词排名TOP10.txt。

代码:

# 导入所需的库 from sklearn.feature_extraction.text import TfidfVectorizer import pandas as pd ​ # 打开分词后的汇总文件,读取所有行作为语料库 inFile = open(r'.\红楼梦分词后汇总.txt', 'r', encoding='utf-8') corpus = inFile.readlines()  # 语料库,每个元素是一行(即一卷的分词结果) # 初始化 TfidfVectorizer,用于计算 TF-IDF 值 vectorizer = TfidfVectorizer() # 使用语料库计算 TF-IDF 矩阵 tfidf = vectorizer.fit_transform(corpus) # 获取所有词汇(特征词) wordlist = vectorizer.get_feature_names_out()  # 注意:`get_feature_names` 已弃用,推荐使用 `get_feature_names_out` # 将 TF-IDF 矩阵转换为 DataFrame,便于后续操作 # 转置矩阵是为了让每一列对应一卷,每一行对应一个词汇 df = pd.DataFrame(tfidf.T.todense(), index=wordlist) # 打开文件,用于保存每回的核心关键词排名 file_keywords = open(r'.\红楼梦分节关键词排名TOP10.txt', 'w', encoding='utf-8') ​ # 遍历每一卷,提取其核心关键词 TOP10 for i in range(len(corpus)):    # 获取当前卷的 TF-IDF 值列表    featurelist = df.iloc[:, i].to_list()    # 初始化一个字典,用于存储词汇及其对应的 TF-IDF 值    resdict = {}    # 将词汇和 TF-IDF 值一一对应    for j in range(0, len(wordlist)):        resdict[wordlist[j]] = featurelist[j]    # 对字典按 TF-IDF 值进行降序排序    resdict = sorted(resdict.items(), key=lambda x: x[1], reverse=True)    # 将当前卷的核心关键词 TOP10 写入文件    file_keywords.write(f'第{i+1}回的核心关键词:' + str(resdict[0:10]) + '\n')    # 如果需要在控制台打印结果,可以取消注释以下代码    print('第{}回的核心关键词:'.format(i+1), resdict[0:10]) # 关闭关键词文件 file_keywords.close()

运行结果:

标签:

自然语言处理NLP03案例——提取小说红楼梦各卷关键词TOP10由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“自然语言处理NLP03案例——提取小说红楼梦各卷关键词TOP10