Python和tfidf算法,如何加速?
我正在用Python在一个网页应用中实现tf-idf算法,但运行得非常慢。基本上,我做了以下几件事:
1) 创建了两个字典:
- 第一个字典:键是文档的ID,值是这个文档中所有找到的单词的列表(包括重复的单词)
- 第二个字典:键是文档的ID,值是这个文档中唯一单词的集合
现在,有用户请求获取文档d的tfidf结果。我做的步骤是:
2) 遍历第二个字典中文档d的唯一单词,对于每个唯一单词w,我会:
2.1) 计算tf分数(w在文档d中出现的次数:遍历第一个字典中该文档的单词列表)
2.2) 计算df分数(有多少文档包含w:遍历所有文档的单词集合(第二个字典),检查w是否在其中)。我使用集合是因为检查一个集合中是否包含某个单词比检查列表要快。
步骤2.2非常慢。例如,如果有1000个文档,而某个文档有2313个唯一单词,输出结果大约需要5分钟。
有没有其他方法可以让步骤2.2更快?字典在遍历时真的那么慢吗?
2 个回答
你是在做学术研究还是为了实际应用呢?如果是为了实际应用,为什么不直接用一些现成的东西呢?比如说这个链接提供的工具(http://code.google.com/p/tfidf/)?另一方面,如果你是在做学术练习,我建议你看看现有的实现,看看他们有什么不同的做法(如果有的话)。
我还建议你使用cProfile
来分析你的代码,看看哪些地方耗费了比较多的资源。
好吧,你需要重新考虑和设计一下你存储数据的方式,换句话说,就是要实现一个“传统”的“倒排索引”。
你现在的瓶颈在于实时计算文档频率(DF)这个过程。要让这个过程变得灵活,每次你更新你的文档集合(就是你存放的文件)时,都要进行一些处理,更新每个文档中每个词的DF(当然,结果要保存到一个持久的地方,比如数据库等等)。
你只需要一个嵌套字典的结构,像这样:
{ "term1" : { "DF" : x, "some_doc_id" : tf , "some_other_doc_id" : tf, etc } ,
"term2" : ...
etc..
}
每次你“喂”你的文档集合时,都要好好更新它。
当然,你还要在某个地方记录你的文档总数...
作为我的一个爱好和工作的一部分,我正在实现一个基于Python和Redis的小型搜索引擎。你也许能从中获得一些其他的想法。可以看看 这里。