好的...这是一个广泛的主题。实际上,elasticsearch 正是为此而做的。但是谷歌也是。从 elasticSearch 到 google 搜索存在技术差距。
如果您进行个人实施,它仍然是可能的……但是要像 elasticsearch 一样高效,还有很多工作要做。快速回答是:使用弹性搜索。
您可能很好奇,或者出于某种原因您可能需要自己编写它。那么它是如何工作的:
TFIDF 和余弦距离
正如您首先指定的那样,您将标记化
然后你将标记化的文本表示为向量,然后测量文本和搜索词之间的角距离。
想象你的语言中只有 3 个单词“foo, bar, bird”
所以带有“foo bar bird”的文本可以用vector3 [1,1,1]表示
带有
的文本
A) "foo foo foo foo bird" 将是 [4,0,1]
另一个
B) "foo bar" [1,1,0]
如果您搜索由 [0,1,0] 表示的“bar”,您将寻找具有最小角距离的文本,如果您计算搜索和 BI 之间的角距离,则认为这是 90 °低于A。
实际上,语言超过 3 个单词,因此您将在更多维度的向量中计算距离,因为 1 个世界 = 1 个维度 :)
TFIDF 代表词频逆文档频率。
这通过该单词在所有文档中的频率的倒数来评估文档中单词的频率。它的作用是指出文档中的重要单词。
让我们解释一下:
- “that, in a the”等词无处不在,因此它们并不重要
- 在您的所有文本中,“语料库”一词的频率为我不知道 0.0001%
- 在特定文本中被引用 5 次,其频率为 0.1%
- 那么它在语料库中非常罕见,但在您的文本中比较重要
- 因此,当您搜索“语料库”时,您想要首先获得它出现 4 次的文本。
- 因此,您将获得一个相对出现频率的向量,而不是出现次数的向量,例如 [0.2,1,0.0005]
https://en.wikipedia.org/wiki/Tf%E2%80%93idf
最后我给你一个小惊喜:这就是背后的原因
elasticsearch中的评分https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html
此外,elasticsearch 还将为您提供复制可扩展性、分布以及您梦寐以求的任何东西。
仍然有理由不使用弹性搜索:
- 研究目的
- 您实际上编写了另一个搜索引擎,例如 duckduck go(为什么不)
- 你很好奇
缩放和分布部分
在https://en.wikipedia.org/wiki/Apache_Lucene之前阅读lucene
它很大程度上取决于要索引的文本量和单词。
如果它代表 1M 的文本,您不需要分发它。
如果你索引像维基百科这样的大东西,你将需要一个分布式倒排索引(维基百科使用弹性搜索作为搜索框)
foo 在文本 A、B、C、R 中
所以我会分区我的索引
我将使用带有单词作为键的分布式缓存和指向向量的指针列表作为值。我会将值存储在内存映射文件中。
搜索引擎是必须快速的东西,所以如果你自己做这件事,你会减少外部库。你将使用 c++
在 google,他们最终会遇到向量占用大量空间以致需要将它们存储在多台机器中的情况,因此他们发明了 GFS,这是一个分布式文件系统。
多维向量之间的余弦距离计算非常耗时,所以我将在 GPU 中进行计算,因为 GPU 对矩阵和向量的浮点运算非常有效。
实际上,要重新实现所有这些期望你有充分的理由这样做有点疯狂,例如一个非常好的商业模式:)
我可能会使用 kubernetes docker 和 mesos 来虚拟化我的所有组件。如果需要大容量,我会寻找类似于 GFS 的东西。
https://en.wikipedia.org/wiki/Comparison_of_distributed_file_systems
您需要取回文本,因此我将使用任何可扩展为任何语言的 NIO 网络服务器。我将使用 nginx 来提供静态页面以及 netty 或 vertx 之类的东西来获取搜索,然后构建文本链接的答案(这取决于你想在一秒钟内服务多少用户)
如果我打算索引比维基百科更大的东西,所有这些。如果我打算发明比 elasticsearch 更好的东西(艰巨的任务祝你好运)
例如 wikipedia,这少于 1T 的文本。
终于
如果您在一周内使用 elasticsearch 完成,则可能需要 2 周并投入生产。如果您自己做,您将需要至少 1 名高级开发人员和一名数据科学家、一名架构师,并且需要一年或更长时间,具体取决于您要索引的文本量。我忍不住问自己“这是为了什么”。
实际上,如果您阅读了 lucene 的代码源,您将确切地知道您需要什么。他们做到了,lucene是elasticsearch的引擎。
Twitter 正在使用 Lucene 进行实时搜索