Python练习7-统计日记中最重要的词
第 0006 题:你有一个目录,放了你一个月的日记,都是 txt,为了避免分词的问题,假设内容都是英文,请统计出你认为每篇日记最重要的词。
之前已经练习过使用正则匹配文本中的单词,也练习过了文件遍历,这次算是两者结合起来的综合应用吧。由于之前在写文件遍历的时候使用了递归,遍历文件函数原型 travelf(dir,dest,func) 由于处理函数func当成参数传入,所以这次只需写个简单的统计函数func即可,此时也显现出了泛型编程的优势。
统计函数看了网上许多例子,都是简单的统计每篇日记中单词的频率,好一点的会有个过滤单词列表,比如{ is, the, a}这样的单词频率很大,但却不是最重要的单词,所以需要过滤掉。但是单纯的添加过滤表很麻烦,由于之前学过信息检索,所以简单的将tf-idf算法运用在这里,十分方便。
使用tf-idf除了能够计算出每篇日记中最重要的单词,并且不需要手动添加过滤词库之外,还能够得到某个单词关联度最大的日记,你可以理解为最简单的搜索引擎。
至于tf-idf算法,是信息检索中最经典,入门级的算法,推荐一篇不错的博客tf-idf算法
写代码过程中唯一遇到的坑就是统计的时候都是整数,结果计算权重要用到除法,导致结果都是整数,没有区分度,debug了好久才找到。
下面是代码:
#coding=utf-8 import re import os #匹配单词正则表达式 regular=r'\b[a-zA-Z]+\b' src="D:\\project\\tf-idf\\diary" dest="D:\\project\\tf-idf\\result.txt" tf={} idf={} fnum=0 #递归遍历文件夹 def travelf(dir,dest,func): for fildir,folders,files in os.walk(dir): for folder in folders: travelf(folder,dest,func) for file in files: func(fildir,file,dest) #tf-idf def func(fildir,file,dest): global fnum fname = file.split('.') if fname[1] == 'txt': fnum+=1 f=open(fildir+os.sep+file).read() words=re.findall(regular,f) tf[fname[0]]={} #计算每个单词词频 for word in words: if word in tf[fname[0]]: tf[fname[0]][word]+=1 else: tf[fname[0]][word] =1 total=len(words) #计算每个单词占比 for key,value in tf[fname[0]].items(): if key in idf: idf[key]+=1 else: idf[key]=1 tf[fname[0]][key]=float(tf[fname[0]][key])/total if __name__=='__main__': result=open(dest,'w') result.write('Diary\t\tKeyWord\t\tWeight\n') travelf(src,dest,func) #得到文件总数之后才可计算idf for key,value in idf.items(): idf[key]=float(fnum)/value for fname,value in tf.items(): w='' maxFreq=0 for word,freq in tf[fname].items(): tf[fname][word]=freq*idf[word] if tf[fname][word]>maxFreq: w=word maxFreq=tf[fname][word] result.write(fname+'\t\t'+w+'\t\t%f\n'%maxFreq)