- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在开发一个使用 TF-IDF 和余弦相似度的小型搜索引擎。添加页面时,我会建立一个倒排索引以保持不同页面中的词频。我删除了停用词和更常见的词,以及复数/动词/等等。被阻止。
我的倒排索引是这样的:
map< string, map<int, float> > index
[
word_a => [ id_doc=>frequency, id_doc2=>frequency2, ... ],
word_b => [ id_doc->frequency, id_doc2=>frequency2, ... ],
...
]
有了这个数据结构,我可以用 word_a.size()
得到 idf 权重。给定一个查询,程序会遍历关键字并对文档进行评分。
我不太了解数据结构,我的问题是:
如何存储 500 Mo 倒排索引以便在搜索时加载它?目前,我使用 boost 来序列化索引:
ofstream ofs_index("index.sr", ios::binary);
boost::archive::bynary_oarchive oa(ofs_index);
oa << index;
然后我在搜索时加载它:
ifstream ifs_index("index.sr", ios::binary);
boost::archive::bynary_iarchive ia(ifs_index);
ia >> index;
但是它非常慢,加载需要 sometines 10 秒。
我不知道 map
对于倒排索引是否足够有效。
提前感谢您的帮助!
最佳答案
答案在很大程度上取决于您是否需要支持与机器 RAM 相当或更大的数据,以及在您的典型用例中您可能会访问所有索引数据还是只访问其中的一小部分。
如果您确定您的数据适合您的机器内存,您可以尝试优化您现在使用的基于 map 的结构。将数据存储在 map 中应该可以提供相当快的访问,但是当您将数据从磁盘加载到内存中时,总会有一些初始开销。此外,如果您只使用索引的一小部分,这种方法可能会非常浪费,因为您总是读取和写入整个索引,并将所有索引保存在内存中。
下面我列出了一些您可以尝试的建议,但在您花太多时间在其中任何一个之前,请确保您实际测量了哪些改进了负载和运行时间,哪些没有。如果不分析您使用的实际数据的实际工作代码,这些只是可能完全错误的猜测。
map
被实现为一棵树(通常是黑-红树)。在许多情况下,hash_map
可以为您提供更好的性能以及更好的内存使用(例如更少的分配和更少的碎片)。float
来存储频率,但也许您可以仅将出现次数存储为 map 值中的 unsigned short
和单独的 map 存储每个文档的所有单词数(也称为短)。使用这两个数字,您可以重新计算频率,但在将数据保存到磁盘时使用更少的磁盘空间,这可能会导致更快的加载时间。如果您的数据可能会增长到超出您机器 RAM 的大小,我建议您使用内存映射文件来存储数据。这种方法可能需要重新建模您的数据结构,并使用自定义 STL 分配器或使用完全自定义的数据结构而不是 std::map
,但如果做得好,它可能会将您的性能提高一个数量级。特别是,这种方法使您不必一次将整个结构加载到内存中,因此您的启动时间将显着缩短,但代价是当您第一次接触结构的不同部分时,与随时间分布的磁盘访问相关的轻微延迟时间。这个主题非常广泛,需要对代码进行更深入的更改,而不仅仅是调整 map ,但如果您计划处理大量数据,您当然应该看看 mmap
和 friend 。
关于c++ - 在 C++ 中存储、加载和使用倒排索引的最佳方式 (~500 Mo),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22590287/
我想在 android 中扫描黑底白字条码。我使用过 zxing,它允许我只扫描白底黑字。我如何扫描和倒置条形码或使用哪个库?感谢您的帮助。 最佳答案 如果您仍在引用 journeyapps 嵌入式
所以我在 youtube 上观看了一些介绍性类(class)以学习 OpenGL 的基础知识并学习了诸如制作三角形和简单相机类等内容。我一直想尝试制作体素引擎,这显然是第一个我想做的是一个我最终可以复
这个问题在这里已经有了答案: Div with cut out edges, border and transparent background (6 个答案) 关闭 8 年前。
我有一张图片,我正在查看用 HTML 创建的小型网站的基本定制。 我知道您可以对图像进行倒 Angular 处理,如 this question here 中所示,这给出了 45 度切割。 我希望每个
我必须在 iOS 上创建一个自定义形状(倒 T)边框的 Uiview。我附上下面的截图。我进行了很多研究,找到了一种使用 here 中的 UIBezierPath 的方法. 但我不知道如何将我的 Vi
我是一名优秀的程序员,十分优秀!