TF-IDF——自然语言处理——红楼梦案例

打印 上一主题 下一主题

主题 1774|帖子 1774|积分 5322



目录

一、红楼梦数据分析
(1)红楼梦源文件
(2)数据预处理——分卷实现思绪
(3)分卷代码
二、分卷处理,删除停用词,将文章转换为标准格式
1.实现的思绪及细节
2.代码实现(遍历所有卷的内容,并添加到内存中)
3、代码实现“1”中剩余的步调
(1)数据展示
(2)代码及方法
三、计算红楼梦分词后文件的 TF_IDF的值


一、红楼梦数据分析

(1)红楼梦源文件

预计要实现的效果:观察下面的文件截图,我们希望将红楼梦每一回的文件内容存在文件中,将文件的“上卷 第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀”第几次,这一整行作为文件的名字,每一回作为一个文件,储存到指定的路径下。



最终效果:

(2)数据预处理——分卷实现思绪

(1)使用os是python的标准库,读取红楼梦源文件
(2)以写的格式打开一个以"红楼梦开头.txt"为名字的文件,用以存储文件开头的内容,如下:

(3)使用for循环,逐行读取文件内容,通过观察,每一回的开头,都会有“卷 第 ”这样的字,如下

我们可以通过in来判断是否读取到这一行,满足条件则对这行执行strip()方法,去除行前后的空格和换行符。
(4)使用os.path.join方法构建一个完整的路径,将路径(根据自己的现实情况来写)和文件名拼接在一起,这里是把前面写的路径,与后面读取的文件名拼接起来了,分卷最好放置在一个单独的文件夹中,为了更有条理。
os.path.join 会自动添加成斜杠,会根据系统自动增补路径中的斜杠,对不同系统有适配性,windows 斜杠\,macos 斜杠/,Linux 斜杠 /。
效果

(5)关闭先前存储文件开头的juan_file这个文件,使用close()方法。
(6)按照上面第(4)步拼接的路径,打开文件,然后使用continue跳出本次循环,向文件中逐行写入第一回的内容
(7)发如今每一回的下一行都会有这样一行内容,我们希望将其剔除,剔除方法如下:

if '手机电子书·大门生小说网' in line: #过滤掉无用的行 continue
这里表现假如发现读取的行中存在'手机电子书·大门生小说网'这个内容,就直接跳出循环,即跳过这一行,循环读取文件下一行的内容。
(8)按照上面的方法不断地循环,最终我们就能将整个红楼梦文件按照每一回存储在一个文件中的格式将红楼梦分卷处理。
效果:

(3)分卷代码

  1. import os
  2. file=open("./data/红楼梦/红楼原数据/红楼梦.txt",encoding='utf-8')    #读取红楼梦原数据集
  3. juan_file=open('./data/红楼梦/红楼梦开头.txt','w',encoding='utf-8')   #这里会创建并打开,以红楼梦开头.txt为名字的文件
  4. #逐行读取读取红楼梦.txt中的文件内容
  5. for line in file:
  6.     if '卷 第'in line:      #为了将第几回这一行,每一回的标头作为文件的名字,这里需要能够识别到这样的行,通过文字匹配来匹配,如果满足这个条件则会执行下面的其他代码
  7.         juan_name=line.strip()+'.txt'     #去除行前后的空格和换行符,与.txt拼接成文件名
  8.         path = os.path.join('.\\data\\红楼梦\\分卷\\',juan_name)   #使用os.path.join方法将路径和文件名拼接在一起
  9.         print(path)
  10.         juan_file.close()
  11.         juan_file=open(path,'w',encoding='utf-8')
  12.         continue
  13.     if '手机电子书·大学生小说网' in line:    过滤掉无用的行
  14.         continue
  15.     juan_file.write(line)     #将文件的其他内容写入到juan_file中
  16. juan_file.close()
复制代码
二、分卷处理,删除停用词,将文章转换为标准格式

(词之间通过空格分隔),即进行分词处理
1.实现的思绪及细节

(1)遍历所有卷的内容,并添加到内存中
(2)将红楼梦词库添加到jieba库中(jieba不一定能识别出红楼梦中所有的词,需要手动添加词库)
(3)读取停用词(删除无用的词)
(4)对每个卷进行分词,
(5)将所有分词后的内容写入到分词后汇总.txt
分词后汇总.txt的效果为:

可以看出,红楼梦的原文被分成上图的格式,词与词之间以空格分隔,同时每一行就是一个分卷的内容,也就是每一行是一回的内容。
2.代码实现(遍历所有卷的内容,并添加到内存中)

(1)os.walk()s.walk是直接对文件夹进行遍历,统共会有三个返回值第一个是文件的路径,第二个是路径下的文件夹,第三个是路径下的文件。
for root,dirs,files in os.walk(r"./data/红楼梦/分卷"):
这里我们分别用三个变量去吸收,os.walk的返回值。
  1. import pandas as pd
  2. import os
  3. filePaths=[]    #用于保存文件的路径
  4. fileContents=[]    #用于保存文件的内容
  5. for root,dirs,files in os.walk(r"./data/红楼梦/分卷"):
  6.     for name in files:    #对files进行遍历,依次取出文件操作
  7.         filePath=os.path.join(root,name)    #将文件的路径和名字拼接到一起形成一个完整的路径,并将路径存储在filepath这个变量中
  8.         print(filePath)
  9.         filePaths.append(filePath)    #将完整路径存储到filepathS这个列表中
  10.         f=open(filePath,'r',encoding='utf-8')    #根据上面拼接好的路径,打开文件
  11.         fileContent=f.read()    #读取文章内容,一次性读取全文
  12.         f.close()    #关闭文件减少内存占用
  13.         fileContents.append(fileContent)    #将文章内容添加到filecontents这个列表中
  14. corpos=pd.DataFrame(    #使用pandas的DataFrame方法,将filepath和filecontent存储成dataframe类型
  15.     {
  16.         "filePath":filePaths,
  17.         "fileContent":fileContents
  18.     }
  19. )
  20. print(corpos)
复制代码
corpos内部存储的效果:每一行是一个分卷的内容,第一列是文件存储的路径,第二列是每个分卷的内容。

3、代码实现“1”中剩余的步调

(1)数据展示

红楼梦词库(红楼梦词库.txt):

停用词(StopwordsCN.txt):

(2)代码及方法

load_userdict():是jieba库中加载新词到jieba的辞海中,针对海量的新词可以使用这个方法,对文件格式也有要求,文件的每一行是一个停用词。
iterrows():遍历pandas数据,逐行读取,返回值有两个,行索引和pandas类型数据的全部内容
“if seg not in stopwords.stopword.values and len(seg.strip())>0:”其中stopwords.stopword.values是stopwords变量下stopword列对应的值调用。
  1. import jieba
  2. jieba.load_userdict(r".\data\红楼梦\红楼原数据\红楼梦词库.txt")
  3. #读取停用词
  4. stopwords=pd.read_csv(r"./data/红楼梦/红楼原数据/StopwordsCN.txt",encoding='utf-8',engine='python',index_col=False)
  5. file_to_jieba=open(r'./data/红楼梦/分词后汇总.txt','w',encoding='utf-8')
  6. for index,row in corpos.iterrows():
  7.     juan_ci=''
  8.     filePath=row['filePath']    #获取文件路径
  9.     fileContent=row['fileContent']     #获取文件内容   
  10.     segs=jieba.cut(fileContent)    #使用cut()方法对第一行的内容进行切分,也可以使用lcut(),并将分词后的结果存储在segs中
  11.     for seg in segs:    #利用for循环过滤掉文章中的停用词
  12.         if seg not in stopwords.stopword.values and len(seg.strip())>0:
  13.             
  14.         #if如果满足,当前词不在停用词中,并且词不为空的前提下,将这个词添加到juan_ci+保存
  15.             juan_ci+=seg+' '
  16. #将没一回的内容写入到file_to_jieba这个文件中,我们希望每一回在同一行,所以这里在每一回的内容后加上"\n"换行符
  17.    
  18.     file_to_jieba.write(juan_ci+'\n')
  19. file_to_jieba.close()    #等所有分卷的内容全部写入后关闭file_to_jieba(分词后汇总.txt)这个文件,减少内存的占用
复制代码
为什么总是把处理完成的文件生存下来呢,预处理结束将文件生存到本地,这样做的目的是代码分块化实现,防止调试代码时每次都要全部执行,每做一步将处理好的效果生存下来,可以加快调试的服从。
三、计算红楼梦分词后文件的 TF_IDF的值

  1. from sklearn.feature_extraction.text import TfidfVectorizer
  2. import pandas as pd
  3. #读取分词后汇总,并逐行读取文件内容,存储在corpos变量中
  4. inFile = open(r"./data/红楼梦/分词后汇总.txt","r",encoding='utf-8')
  5. corpos = inFile.readlines()
  6. #实例化对象,使用fit_transfrom计算每个词的TF-IDF的值
  7. vectorizer=TfidfVectorizer()
  8. tfidf=vectorizer.fit_transform(corpos)
  9. print(tfidf)
  10. #使用get_feature_names方法获取红楼梦的所有关键词
  11. wordlist=vectorizer.get_feature_names()
  12. print(wordlist)
  13. #将tfidf转化为稀疏矩阵
  14. df=pd.DataFrame(tfidf.T.todense(),index=wordlist)
  15. print(df)
  16. #逐列排序,输出tfidf排名前十的关键词及TF-IDF值
  17. for i in range(len(corpos)):
  18.     featurelist=df[[i]]
  19.     feature_rank=featurelist.sort_values(by=i,ascending=False)
  20.     print(f"第{i+1}回的关键词是:{feature_rank[:10]}")
复制代码
wordlistte特征值的个数33703个为:

输出效果为:我们就能得到每一回的关键词以及对应的TF-IDF值


代码汇总:
此处代码为上面的整合,去除了部分注释,可以将其放在一个.py文件中,安装好指定的库即可运行,需要注意文件的路径与你自己的文件路径对应,数据集文件可以到我的数据集中获取(有单独的一篇文章注明了数据集)
  1. """通过os系统标准库,读取红楼梦的原始数据,并将每一回的数据文本存储到不同的txt文件中。"""
  2. import os
  3. file=open("./data/红楼梦/红楼原数据/红楼梦.txt",encoding='utf-8')    #读取红楼梦原数据集
  4. juan_file=open('./data/红楼梦/红楼梦开头.txt','w',encoding='utf-8')   #这里会创建并打开,以红楼梦开头.txt为名字的文件
  5. #逐行读取读取红楼梦.txt中的文件内容
  6. for line in file:
  7.     if '卷 第'in line:      #为了将第几回这一行,每一回的标头作为文件的名字,这里需要能够识别到这样的行,通过文字匹配来匹配,如果满足这个条件则会执行下面的其他代码
  8.         juan_name=line.strip()+'.txt'     #去除行前后的空格和换行符,与.txt拼接成文件名
  9.         path = os.path.join('.\\data\\红楼梦\\分卷\\',juan_name)   #使用os.path.join方法将路径和文件名拼接在一起
  10.         print(path)
  11.         juan_file.close()
  12.         juan_file=open(path,'w',encoding='utf-8')
  13.         continue
  14.     if '手机电子书·大学生小说网' in line:    #过滤掉无用的行
  15.         continue
  16.     juan_file.write(line)     #将文件的其他内容写入到juan_file中
  17. juan_file.close()
  18. import pandas as pd
  19. import os
  20. filePaths=[]
  21. fileContents=[]
  22. for root,dirs,files in os.walk(r"./data/红楼梦/分卷"):
  23.     for name in files:
  24.         filePath=os.path.join(root,name)
  25.         print(filePath)
  26.         filePaths.append(filePath)
  27.         f=open(filePath,'r',encoding='utf-8')
  28.         fileContent=f.read()
  29.         f.close()
  30.         fileContents.append(fileContent)
  31. corpos=pd.DataFrame(
  32.     {
  33.         "filePath":filePaths,
  34.         "fileContent":fileContents
  35.     }
  36. )
  37. print(corpos)
  38. import jieba
  39. jieba.load_userdict(r".\data\红楼梦\红楼原数据\红楼梦词库.txt")
  40. stopwords=pd.read_csv(r"./data/红楼梦/红楼原数据/StopwordsCN.txt",encoding='utf-8',engine='python',index_col=False)
  41. file_to_jieba=open(r'./data/红楼梦/分词后汇总.txt','w',encoding='utf-8')
  42. for index,row in corpos.iterrows():
  43.     juan_ci=''
  44.     filePath=row['filePath']
  45.     fileContent=row['fileContent']
  46.     segs=jieba.cut(fileContent)
  47.     for seg in segs:
  48.         if seg not in stopwords.stopword.values and len(seg.strip())>0:
  49.             juan_ci+=seg+' '
  50.     file_to_jieba.write(juan_ci+'\n')
  51. file_to_jieba.close()
  52. from sklearn.feature_extraction.text import TfidfVectorizer
  53. import pandas as pd
  54. inFile = open(r"./data/红楼梦/分词后汇总.txt","r",encoding='utf-8')
  55. corpos = inFile.readlines()
  56. vectorizer=TfidfVectorizer()
  57. tfidf=vectorizer.fit_transform(corpos)
  58. print(tfidf)
  59. wordlist=vectorizer.get_feature_names()
  60. print(wordlist)
  61. df=pd.DataFrame(tfidf.T.todense(),index=wordlist)
  62. print(df)
  63. for i in range(len(corpos)):
  64.     featurelist=df[[i]]
  65.     feature_rank=featurelist.sort_values(by=i,ascending=False)
  66.     print(f"第{i+1}回的关键词是:{feature_rank[:10]}")
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表