Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python2.7:使用字典生成tf:idf脚本_Python_Tf Idf - Fatal编程技术网

Python2.7:使用字典生成tf:idf脚本

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)) 然后,它使用列表查找所有单

我想编写一个脚本,使用字典来获取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))
然后,它使用列表查找所有单词以及它们出现的次数:

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值的单词。我现在刚刚解决了问题,将发布它并结束此问题,非常感谢您的帮助和时间a
Counter
只是dict的一个子类,因此它具有相同的方法。我同意在输出中使用
计数器有点误导;出于您的目的,它实际上只是一个dict,您应该忽略
计数器
标识符。