最近需要选取网页的关键词,所以在网上down一个TF_IDF的代码,前天晚上看了一下,搞完数据所以就跑了一下看,这个代码还是写的很nice的,在这里我们阅读一下代码,来学习一下杰作,代码下载地址:http://download.csdn.net/download/blinkhow/9231909 列出了c和python 我只试了python
#-*- coding:utf-8 -*-
import math
import os
import fileinput
TEXT = 0 #某类别的文档数目
SUCCEED = 0
Docs = []
Path = "G:\\ciku\\1_2091_path_word".decode('utf8').encode('cp936') #综合分析,path地址实际上是存放训练数据的一个文件夹,文件夹内包含众多txt文件
w_Path = "G:\\ciku\\1_2091_path_word_TFIDF".decode('utf8').encode('cp936')
##计算权重函数,tf为某词在文章中出现的次数,df为包含该词的文档数,max文章中出现次数最多的词条数
##返回值为TF-IDF权重
##把特征向量按权重进行排序
def sort(terms,TF_IDF):
for i in range(0,len(terms)):#range生成一个0到len(terms)的数字序列
m = i
for j in range(i+1,len(terms)):
if TF_IDF[j]>TF_IDF[m]:
m = j
if i!=m:
temp = terms[i]
terms[i] = terms[m]
terms[m] = temp
v = TF_IDF[i]
TF_IDF[i] = TF_IDF[m]
TF_IDF[m] = v
def save_words(path):
global Docs , TEXT
terms = []
fp = open(path,"r")
while True:
line = fp.readline()
if not line : break
terms.append(line)
fp.close()
Docs.append(terms)
TEXT += 1
def GenerateIDF(path):#计算词的IDF,具体的计算方法是取文档总数除以出现这个词的文档数量之后的商取对数
global Docs , TEXT
terms = []
IDF = []
idf = 0.0
fp = open(path,"r") #综合前边的分析在这里path指向的是一个单行的词汇表,但是这样的组织形式和多篇文章的计算方法存在差别??
while True:
line = fp.readline()
if not line : break
flag = 0
for i in range(0,len(terms)):#这个循环的意思是对比两个相同的词汇表,如果固定一个词,这个词与已有的词汇库作对比,如果未发现相同的,则将这个词放入到terms,类似一个蛇头吃蛇尾的算法
if line == terms[i]:#使用了一个文件的次创造了两个词集,一个是不重复的词集
flag = 1
if flag == 0:
terms.append(line)#这一句的意思是创造一个terms list在这个list中均为不重复的term,也就是建立了一张词汇表
fp.close()
for j in range(0,len(terms)):#计算文档中是否存在这个词,存在则df自加1
df = 0
for i in range(0,len(Docs)):
#在这里terms与df为对应关系,
#对应于每个词的idf值,方法是固定总的词,拿每篇文章的词与其对比,
#如发现相同则循环终止,df自加1
flag = 0
doc = Docs[i]
for k in range(0,len(doc)):#设置一个flag来检测循环终止
if terms[j] == doc[k]:#在这里Docs为一个二维的矩阵,每一行代表一篇文章,doc为其某一行,即代表一篇文章,遍历单篇文章如发现文章穿线terms则此时中断且df自加1
flag = 1
break
if flag == 1:
df += 1
idf = math.log(float(TEXT)/float(df)+0.01)#文章总数与出现本词的文章总数比值取对数
IDF.append(idf)#TEXT为文章总数 df为出现这个词的文档总数
return IDF,terms
def GenerateTF(path,terms):#计算TF值,具体的TF计算方法为某个词在一篇文章中出现的次数
all_terms = []
TF = []
terms_count = len(terms)#term总数量,这个terms实际是一个全部词汇的不重复的词汇集
fp = open(path,"r")#打开数据集
while True:#使用按行读取生成一个terms的词集
line = fp.readline()
if not line : break
all_terms.append(line)
for i in terms:#固定i比较terms中某个词和总的all_terms命中次数,即出现的次数
tf = 0
for j in all_terms:
if i == j:
tf +=1
TF.append(float(tf)/float(terms_count))
fp.close()
return TF
def save_weight(TF,IDF,terms,path):
global SUCCEED
TF_IDF = []
top = 200
if len(TF)<top:
top = len(TF)
for i in range(0,len(TF)):
TF_IDF.append(float(TF[i])*float(IDF[i]))
fp = open(path,"w+")#这里的path为传入的w_Path地址,用来存储相应的
sort(terms,TF_IDF)#使用词与TF_IDF作为输入进入到分类函数中
for i in range(0,top):
string = terms[i].strip()+" "+str(TF_IDF[i])+'\n'
fp.write(string)
SUCCEED += 1
fp.close()
def read_dir(path,w_path):
global SUCCEED
file_list = []
files = os.listdir(path)#遍历文件路径,输出目录下的文件名和文件夹名
print "please wait......"
for f in files:
file_list.append(f) #file_list为文件名,与os.listdir对应
r_name = path + '\\' + f #数据集的目录加具体的文件路径
save_words(r_name)#TEXT加1,且terms成为完整路径,函数实现读取词语的功能
print "sum of docs is:%d"%TEXT #TEXT为读取的词语的总数
for i in file_list:#对每一个训练文件名,加上完整的路径,输出为name来为后边的函数服务
print i
name = path + '\\' + i
w_name = w_path + '\\' + i
IDF,terms = GenerateIDF(name)#在这里输出一个词语不重复的terms词汇表,和每个词语的IDF值
TF = GenerateTF(name,terms)#根据输出的词汇表来计算每个词的TF值
save_weight(TF,IDF,terms,w_name)
print "succeed:%d"%SUCCEED
if __name__=="__main__":
print("main")
read_dir(Path,w_Path)
print "-------------------Finished-----------------------"
代码可以直接运行,只要将路径设置好,后续的我出现了一些乱码,我正在查看是否是我的数据出了问题,随后再来说