Python2.7:使用字典生成tf:idf脚本
我想编写一个脚本,使用字典来获取tf:idf(比率?) 其思想是让脚本使用os.WACK查找目录及其子目录中的所有.txt文件:Python2.7:使用字典生成tf:idf脚本,python,tf-idf,Python,Tf Idf,我想编写一个脚本,使用字典来获取tf:idf(比率?) 其思想是让脚本使用os.WACK查找目录及其子目录中的所有.txt文件: files = [] for root, dirnames, filenames in os.walk(directory): for filename in fnmatch.filter(filenames, '*.txt'): files.append(os.path.join(root, filename)) 然后,它使用列表查找所有单
files = []
for root, dirnames, filenames in os.walk(directory):
for filename in fnmatch.filter(filenames, '*.txt'):
files.append(os.path.join(root, filename))
然后,它使用列表查找所有单词以及它们出现的次数:
def word_sort(filename3):
with open(filename3) as f3:
passage = f3.read()
stop_words = "THE OF A TO AND IS IN YOU THAT IT THIS YOUR AS AN BUT FOR".split()
words = re.findall(r'\w+', passage)
cap_words = [word.upper() for word in words if word.upper() not in stop_words]
word_sort = Counter(cap_words)
return word_sort
term_freq_per_file = {}
for file in files:
term_freq_per_file[file] = (word_sort(file))
word_sort = {}
for term in cap_words:
word_sort[term] = cap_words.count(term)
它最终会有这样一本字典:
'/home/seb/Learning/ex15_sample.txt': Counter({'LOTS': 2, 'STUFF': 2, 'HAVE': 1,
'I': 1, 'TYPED': 1, 'INTO': 1, 'HERE': 1,
'FILE': 1, 'FUN': 1, 'COOL': 1,'REALLY': 1}),
在我看来,这给了我每个文件的词频
我怎样才能找到真正的tf呢
我怎样才能找到以色列国防军
我所说的tf是指术语频率,它是一个单词(术语)在文档中出现的次数
TF(t)=(术语t在文档中出现的次数)/(文档中术语的总数)
我所说的idf是指逆文档频率,文档频率是指单词出现的文档数量
IDF(t)=log_e(文档总数/其中包含术语t的文档数)
为了澄清,我的问题是如何提取这些值并将它们放入公式中,我知道它们存在,但我不知道如何提取它们并进一步使用它们
我已决定制作另一本词典,该词典保存了该词在哪些文件中的使用情况,例如:
{word : (file1, file2, file3)}
通过像这样迭代第一个字典:
for file in tfDic:
word = tfDic[file][Counter]
for word in tfDic:
if word not in dfDic.keys():
dfDic.setdefault(word,[]).append(file)
if word in dfDic.keys():
dfDic[word].append(file)
这一行的问题在于:
word = tfDic[file][Counter]
我以为它会“导航”到单词,但我注意到这些单词是计数器字典中的键,它是tfDic(文件)的值
我的问题是,我如何告诉它遍历单词(“计数器”字典的键)?如果您想坚持使用当前的数据结构,您必须深入研究每个单词的每个文件的整个结构,以计算其
idf
# assume the term you are looking for is in the variable term
df = 0
for file in files:
if term in term_freq_per_file[file]:
df += 1
idf = math.log(len(files)/df)
这个答案的早期版本包含了一个替代数据结构的草图,但这可能已经足够好了。(最后)
我决定回去更改我的字数计算公式,这样就可以代替:
word_sort = Counter(cap_words)
我反复浏览了列表中的单词,并根据它们出现的次数制作了自己的词典:
def word_sort(filename3):
with open(filename3) as f3:
passage = f3.read()
stop_words = "THE OF A TO AND IS IN YOU THAT IT THIS YOUR AS AN BUT FOR".split()
words = re.findall(r'\w+', passage)
cap_words = [word.upper() for word in words if word.upper() not in stop_words]
word_sort = Counter(cap_words)
return word_sort
term_freq_per_file = {}
for file in files:
term_freq_per_file[file] = (word_sort(file))
word_sort = {}
for term in cap_words:
word_sort[term] = cap_words.count(term)
因此,我不再每次都使用子字典(计数器),而是为tfDic使用以下内容:
'/home/seb/Learning/ex17output.txt': {'COOL': 1,
'FILE': 1,
'FUN': 1,
'HAVE': 1,
'HERE': 1,
'I': 1,
'INTO': 1,
'LOTS': 2,
'REALLY': 1,
'STUFF': 2,
'TYPED': 1},
然后我遍历tfDic[file]的键,创建另一个字典,保存给定单词使用过的文件中的信息:
for file in tfDic:
word = tfDic[file].keys()
for word in tfDic[file]:
if word not in dfDic.keys():
dfDic.setdefault(word,[]).append(file)
if word in dfDic.keys():
dfDic[word].append(file)
最终结果如下:
'HERE': ['/home/seb/Learning/ex15_sample.txt',
'/home/seb/Learning/ex15_sample.txt',
'/home/seb/Learning/ex17output.txt'],
现在我打算“提取”这些值,并将它们放入我前面提到的公式中。除非这是一个关于tf idf如何工作的学习练习,否则我建议使用内置类来完成这项工作 首先,为每个文件创建计数字典数组。然后将计数字典数组馈送到,然后将输出稀疏矩阵馈送到
从sklearn.feature\u提取导入DictVectorizer
从sklearn.feature_extraction.text导入TFIDF转换器
dv=DictVectorizer()
D=[{'foo':1,'bar':2},{'foo':3,'baz':1}]
X=dv.fit_变换(D)
tv=TfidfTransformer()
tfidf=tv.fit\u变换(X)
打印(tfidf.to_array())
您可以通过解释您期望的tf
和idf
是什么,以及它们对您意味着什么……它们是否由某些词语加权?您已经有了“术语t在文档中出现的次数”、“文档总数”和“包含术语t的文档数量”,你的问题是“如何获得文档中术语的总数?”?你对tf的定义是错误的:tf只是文档中术语的频率。你已经有tf了。idf是一个计数的问题(单循环可以做到这一点)并应用公式。tf*idf
是一个产品。idf
中的i
代表“逆”,因此它也可以表示为一个比率tf/df
。我用一个完全不同的答案替换了我的答案。请刷新。您可能希望删除现在已过时的注释,就像我对我的注释所做的那样。(点击右边的灰色小X,当你将鼠标悬停在它上面时,它是可见的。)谢谢你,我怎么知道在“如果”后面放什么?我收到一个错误,说没有定义名称“term”。这是让我困惑的事情之一。我是否需要更改我的函数,使其对“term”或“word”作出“反应”?如注释所述,变量应包含要计算其tf*idf值的单词。我现在刚刚解决了问题,将发布它并结束此问题,非常感谢您的帮助和时间aCounter
只是dict的一个子类,因此它具有相同的方法。我同意在输出中使用计数器有点误导;出于您的目的,它实际上只是一个dict,您应该忽略计数器
标识符。