我正在使用Python在Web应用程序中实现tf-idf算法,但它运行速度极慢。我基本上做的是:
1)创建2个词典:
现在,有一个请求用户获取文件d的tfidf结果。我所做的是:
2)循环文档d的第二个字典的唯一单词,并为每个唯一的单词w得到:
2.1)tf得分(在d:循环显示文档第一个字典的单词列表中w出现的次数)
2.2)df得分(多少个文档包含w:循环遍历所有文档的单词集(第二个字典)并检查是否包含w)。我正在使用一个集合,因为检查集合是否包含与列表相比的单词似乎更快。
步骤2.2非常慢。例如,拥有1000个文档,对于具有2313个唯一字的文档,输出结果大约需要5分钟。
还有其他方法可以让步骤2.2更快吗?字典是否会减慢迭代次数?
答案 0 :(得分:5)
好吧,你必须以某种方式重新思考和重新设计数据的方式,换句话说,实现“倒排索引”的“正统”版本。
您的瓶颈是条款的文档频率(DF)的“即时”计算。这是一个动态的聪明主意,所以每次更新语料库(文档集合)时,都要对文档中的每个术语进行一些处理和更新DF(当然,要以持久的方式保存结果) ,又名数据库等。)。
您需要的唯一结构是嵌套字典
{ "term1" : { "DF" : x, "some_doc_id" : tf , "some_other_doc_id" : tf, etc } ,
"term2" : ...
etc..
}
每次“提供”语料库时都会正确更新。
当然,请保留你的语料库基数...
作为业余爱好和工作的一部分,我正在实施一个python - redis支持的小型搜索引擎。你也可以得到一些其他的想法。看看here。
答案 1 :(得分:3)
这是学术上的努力还是你为生产而做?如果您正在实施生产,为什么不使用已有的东西(即http://code.google.com/p/tfidf/)?另一方面,如果你把它作为一个学术练习,我可能仍然会对现有的实现有所了解,看看他们做了什么不同的事情(如果有的话)。
我还建议您使用cProfile
对代码进行分析,以了解费用的位置。