2022-01-15

示例文章:Google 搜索的即时自动补全功能究竟是如何“工作”的?

Google 搜索自动补全功能的强大,相信不少朋友都能感受到,它帮助我们更快地“补全”我们所要输入的搜索关键字。那么,它怎么知道我们要输入什么内容?它又是如何工作的?在这篇文章里,我们一起来看看。

使用自动补全

Google
image

搜索的自动补全功能可以在 Google 搜索应用的大多数位置使用,包括 Google 主页、适用于 IOS 和 Android 的 Google 应用,我们只需要在 Google 搜索框上开始键入关键字,就可以看到联想词了。
image

在上图示例中,我们可以看到,输入关键字 juej,Google 搜索会联想到“掘金”、“掘金小册”、“绝句”等等,好处就是,我们无须输入完整的关键字即可轻松完成针对这些 topics 的搜索。

谷歌搜索的自动补全功能对于使用移动设备的用户来说特别有用,用户可以轻松在难以键入的小屏幕上完成搜索。当然,对于移动设备用户和台式机用户而言,这都节省了大量的时间。根据 Google 官方报告,自动补全功能可以减少大约 25% 的打字,累积起来,预计每天可以节省 200 多年的打字时间。是的,每天!

注意,本文所提到的“联想词”与“预测”,是同一个意思。

基于“预测”而非“建议”

Google 官方将自动补全功能称之为“预测”,而不是“建议”,为什么呢?其实是有充分理由的。自动补全功能是为了帮助用户完成他们打算进行的搜索,而不是建议用户要执行什么搜索。

那么,Google 是如何确定这些“预测”的?其实,Google 会根据趋势搜索 trends 给到我们这些“预测”。简单来说,哪个热门、哪个搜索频率高,就更可能推给我们。当然,这也与我们当前所处的位置以及我们的搜索历史相关。

另外,这些“预测”也会随着我们键入的关键字的变更而更改。例如,当我们把键入的关键字从 juej 更改为 juex 时,与“掘金”相关的预测会“消失”,同时,与“觉醒”、“决心”相关联的词会出现。

image

为什么看不到某些联想词?

如果我们在输入某个关键字时看不到联想词,那么表明 Google 的算法可能检测到:

•这个关键字不是热门字词;•搜索的字词太新了,我们可能需要等待几天或几周才能看到联想词;•这是一个侮辱性或敏感字词,这个搜索字词违反了 Google 的相关政策。更加详细的情况,可以了解 Google 搜索自动补全政策。

为什么会看到某些不当的联想词?

Google 拥有专门设计的系统,可以自动捕获不适当的预测结果而不显示出来。然而,Google 每天需要处理数十亿次搜索,这意味着 Google 每天会显示数十亿甚至上百亿条预测。再好的系统,也可能存在缺陷,不正确的预测也可能随时会出现。

我们作为 Google 搜索的用户,如果认定某条预测违反了相关的搜索自动补全政策,可以进行举报反馈,点击右下角“举报不当的联想查询”并勾选相关选项即可。

image

如何实现自动补全算法?

目前,Google 官方似乎并没有公开搜索自动补全的算法实现,但是业界在这方面已经有了不少研究。

一个好的自动补全器必须是快速的,并且在用户键入下一个字符后立即更新联想词列表。自动补全器的核心是一个函数,它接受输入的前缀,并搜索以给定前缀开头的词汇或语句列表。通常来说,只需要返回少量的数目即可。

接下来,我们先从一个简单且低效的实现开始,并在此基础上逐步构建更高效的方法。

词汇表实现

一个简单粗暴的实现方式是:顺序查找词汇表,依次检查每个词汇,看它是否以给定的前缀开头。

但是,此方法需要将前缀与每个词汇进行匹配检查,若词汇量较少,这种方式可能勉强行得通。但是,如果词汇量规模较大,效率就太低了。

一个更好的实现方式是:让词汇按字典顺序排序。借助二分搜索算法,可以快速搜索有序词汇表中的前缀。由于二分搜索的每一步都会将搜索的范围减半,因此,总的搜索时间与词汇表中单词数量的对数成正比,即时间复杂度是 O(log N)。二分搜索的性能很好,但有没有更好的实现呢?当然有,往下看。

前缀树实现

通常来说,许多词汇都以相同的前缀开头,比如 neednested 都以 ne 开头,seedspeed 都以 s 开头。要是为每个单词分别存储公共前缀似乎很浪费。

image

前缀树是一种利用公共前缀来加速补全速度的数据结构。前缀树在节点树中排列一组单词,单词沿着从根节点到叶子节点的路径存储,树的层次对应于前缀的字母位置。

前缀的补全是顺着前缀定义的路径来查找的。例如,在上图的前缀树中,前缀 ne 对应于从子节点取左边缘 N 和唯一边缘 E 的路径。然后可以通过继续遍历从 E 节点可以达到的所有叶节点来生成补全列表。在图中,ne 的补全可以是两个分支:-ed-sted。如果在数中找不到由前缀定义的路径,则说明词汇表中不包含以该前缀开头的单词。

有限状态自动机(DFA)实现

前缀树可以有效处理公共前缀,但是,对于其他共享词部分,仍会分别存储在每个分支中。比如,后缀 edingtion 在英文单词中特别常见。在上一个例子中,ed 分别存放在了每一个分支上。

有没有一种方法可以更加节省存储空间呢?有的,那就是 DFA。

<center style="color: rgb(0, 0, 0); font-family: "Microsoft YaHei"; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;">
image

</center>

在上面的例子中,单词 neednestedseedspeed 仅由 9 个节点组成,而上一张图中的前缀树包含了 17 个节点。

可以看出,最小化前缀树 DFA 可以在很大程度上减少数据结构的大小。即使词汇量很大,最小化 DFA 通常也适合在内存中存储,避免昂贵的磁盘访问是实现快速自动补全的关键。

一些扩展

上面介绍了如何利用合理的数据结构实现基本的自动补全功能。这些数据结构可以通过多种方式进行扩展,从而改善用户体验。

通常,满足特定前缀的词汇可能很多,而用户界面上能够显示的却不多,我们更希望能显示最常搜索或者最有价值的词汇。这通常可以通过为词汇表中的每个单词增加一个代表单词值的权重 weight,并且按照权重高低来排序自动补全列表。

•对于排序后的词汇表来说,在词汇表每个元素上增加 weight 属性并不难;•对于前缀树来说,将 weight 存储在叶子节点中,也是很简单的一个实现;•对于 DFA 来说,则较为复杂。因为一个叶子节点可以通过多条路径到达。一种解决方案是将权重关联到路径而不是叶子节点。

目前有不少开源库都提供了这个功能,比如主流的搜索引擎框架 Elasticsearch、Solr 等,基于此,我们可以实现高效而强大的自动补全功能。

推荐阅读

阿里又一个 20k+ stars 开源项目诞生,恭喜 fastjson!刷掉 90% 候选人的互联网大厂海量数据面试题(附题解 + 方法总结)好用!期待已久的文本块功能究竟如何在 Java 13 中发挥作用?2019 GitHub 开源贡献排行榜新鲜出炉!微软谷歌领头,阿里跻身前 12!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 如何看待现在的科学发展,下一步会是如何呢? 谈论科学本身就太大了,即使没有绝对的本质区别,但是形形色色的现象和应用...
    Obj_Arr阅读 332评论 0 0
  • 3种工作学习方法 一、番茄工作法 是一种时间管理法, 具体做法是设定25分钟的时长,在这25分钟内集中注意力去...
    c936738fe8f4阅读 221评论 0 0
  • 每天诵读一篇文章 最近在尝试每天诵读一篇文章。 有时候的默诵,有时候是在行走的路上出声诵读。 最近的诵读包括《卖炭...
    人生的磨刀石阅读 86评论 0 2
  • 《中庸》个人解读 提到《中庸》,很多人脑海中涌现的第一个词汇很可能是孔夫子所说的“过犹不及”,认为中庸之道讲究的是...
    言之以文阅读 242评论 0 0
  • 1.今天12个多小时到弘丹老师线上工作坊。 2.我发现了很!久以前买的一本考研词汇书和考研长难句练习册~。原来这么...
    尼古拉斯邶阅读 76评论 0 0