读改变未来的九大算法笔记07_搜索引擎

Posted 躺柒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读改变未来的九大算法笔记07_搜索引擎相关的知识,希望对你有一定的参考价值。

互联网搜索引擎的索引和一本书的索引有着相同的工作原理

1. 车库轶事

1.1. 1939年

1.1.1. 戴夫·休利特(Dave Hewlett)

1.1.1.1. 惠普(Hewlett-Packard)

1.2. 1976年

1.2.1. 蒂夫·乔布斯(Steve Jobs)和史蒂夫·沃兹尼亚克(Steve Wozniak)

1.2.1.1. 从一间卧室开始的,空间很快就不够用了,于是他们转移到了车库

1.3. 1998年

1.3.1. 佩奇和布林

1.3.1.1. 谷歌

1.3.1.1.1. 门洛帕克车库

2. 互联网搜索历史

2.1. 1945年

2.1.1. 超链接

2.1.1.1. 美国工程师范内瓦·布什(Vannevar Bush)

2.1.1.2. 论文《诚若所思》(As We May Think)

2.1.1.3. 一台被称作麦麦克斯(memex)的机器

2.1.1.3.1. 允许“关联索引……任何被选中的东西都能立即自动选择另一个东西”
2.1.1.3.2. 一种早期的超链接

2.2. 1994年

2.2.1. Infoseek

2.2.2. Lycos

2.3. 1995年

2.3.1. AltaVista

2.4. 1999年

2.4.1. AltaVista递交的美国专利文件《索引的限制搜索》(“Constrained searching of an index”)中描述了元词把戏

3. 两大主要任务

3.1. 匹配(matching)

3.2. 排名(ranking)

4. 匹配算法

4.1. AltaVista:互联网级别的第一种匹配算法

4.1.1. 20世纪90年代中期,AltaVista是搜索引擎的王者

4.1.2. 有史以来第一次,有一个搜索引擎能完全索引互联网上每个页面的全部文本

4.2. 有效匹配只是高效搜索引擎的一大挑战

4.3. 索引

4.3.1. 是所有搜索引擎背后最基础的思想

4.3.2. 是计算机科学中最古老的有用思想

4.3.3. 互联网搜索引擎的索引和一本书的索引有着相同的工作原理

4.3.3.1. “书页”现在成了万维网上的网页

4.3.3.2. 搜索引擎则给互联网上的每个网页分配了一个不同的页码

4.3.4. 索引不仅应该存储页码,还要存储信息在页面内的位置

5. 排名和邻度

5.1. 查询词彼此相邻的网页比那些查询词相距很远的网页相关度更高

5.2. 搜索引擎在不断地使用和邻度有关的信息,以提高搜索排名

5.3. “NEAR”(邻近)关键词

5.3.1. NEAR查询

5.4. 搜索引擎的生死由其排名的质量决定,而通过利用网页结构,排名质量能够得到大幅提升

6. 元词把戏

6.1. Metaword Trick

6.2. 创建一份索引时,囊括所有元词是件很简单的事

6.3. 标题查询和其他取决于网页结构的“结构查询”类似于NEAR查询

7. 排名算法

7.1. PageRank

7.1.1. 一种对网页排名的算法

7.1.2. 主要发明者拉里·佩奇的排名算法

7.1.3. 学术会议论文《解析大规模超文本网络搜索引擎》(The Anatomy of a Large-Scale Hypertextual Web Search Engine)

7.1.4. 核心思想

7.1.4.1. 权威性网页通过超链接向其他网页传输权重

7.3. 超链接

7.3.1. 网页上的一个短语,当你点击它时,你将被带到另一个网页

7.3.2. 一个网页的链入链接数可能成为该网页“有用性”或“权威性”的指标

7.3.3. 人们可以滥用超链接把戏,人为地提高自己网页的排名

7.3.3.1. 搜索引擎称这种滥用为网络垃圾Web Spam

7.3.4. 一个有许多链入链接的网页应该有高排名

7.4. 权重

7.4.1. 来自高权重网页的链接排名要比来自低权重网页链接的排名高

7.4.2. 所有网页的初始权重值(Authority Score)都是1

7.4.2.1. 如果一个网页有链入链接,在计算该网页权重时就要加入指向其网页的权重

7.4.2.2. 如果X和Y网页链接Z网页,那么Z网页的权重就是X网页和Y网页权重相加的值

7.4.3. 和来自低权重网页的链入链接相比,一个来自高权重网页的链入链接应该更能证明一个网页的排名

7.5. 随机访问者

7.5.1. 超链接很有可能形成“循环”(cycle)

7.5.1.1. 随机访问者解决这个“鸡生蛋还是蛋生鸡”的问题

7.5.1.2. 不管超链接有没有形成循环,随机访问者把戏都能完美地运作

7.5.2. 关键点

7.5.2.1. 每次访问一个网页时,都有一个固定的重新访问概率(大概是15%),让访问者不从已有的超链接中挑选一个并点击

7.5.2.2. 网页的访问者权重值(Surfer Authority Score)

7.5.2.2.1. 一名随机访问者访问该网页的时间比例

7.5.3. 一个有许多链入链接的网页被访问的概率较大

7.5.4. 和一个来自不知名网页的链接相比,访问者更有可能继续点击一个来自知名网页的链入链接

7.5.5. 每个网页链入链接的质量和数量都会被纳入考虑范围

7.6. 搜索引擎并非通过模拟随机访问者来计算PageRank值:它们使用像随机访问者模拟一样给出相同答案的数学技巧,但计算成本要低很多

7.6.1. 商业搜索引擎中用来判定排名的算法要比PageRank这类基于链接的排名算法多得多

读编程与类型系统笔记05_函数类型

1. 策略模式

1.1. 在运行时从一组算法中选择某个算法

1.1.1. 封装一组算法

1.1.2. 在运行时使用其中一个算法

1.2. 把算法与使用算法的组件解耦

1.3. 面向对象实现

1.3.1. 惯例实现

1.3.2. IStrategy接口

1.3.3. ConcreteStrategy1类

1.3.4. ConcreteStrategy2类

1.3.5. 通过IStrategy接口使用算法的Context类

1.3.6. 常见原因

1.3.6.1. 依赖接口的方法

1.3.6.2. 设计模式在20世纪90年代流行起来

1.3.6.3. 当时并不是所有主流编程语言都支持一等函数

1.4. 函数式实现

1.4.1. Context类

1.4.2. concreteStrategy1()函数

1.4.3. concreteStrategy2()函数

1.4.4. 更简洁的实现

2. 函数的类型

2.1. 函数的签名

2.2. 函数的实参类型和返回类型决定了函数的类型

2.3. 两个函数接受相同的实参,并返回相同的类型

2.3.1. 函数具有相同的类型

3. 一等函数

3.1. 将函数赋值给变量,并像处理类型系统中的其他值一样处理它们

3.2. 一等公民

3.2.1. 赋予它们与其他值相同的权利

3.2.2. 有类型

3.2.3. 可被赋值给变量

3.2.4. 可作为实参传递

3.2.5. 可被检查是否有效

3.2.6. 在兼容的情况下可被转换为其他类型

4. 状态机

4.1. 有一组状态,以及状态之间的转移

4.2. 以给定状态(也叫作开始状态)开始;如果满足特定条件,就能转移到另外一个状态

4.3. 经典的状态机

4.3.1. 将状态集合定义为一个枚举

4.3.2. 跟踪当前的状态

4.3.3. 使用覆盖所有可能状态的switch语句来获得所希望的行为

4.3.4. 使用switch语句的状态机

4.3.4.1. 缺点

4.3.4.1.1. 状态没有与想要在每种状态下运行的逻辑联系在一起
4.3.4.1.2. 状态和转移作为一个单独的枚举进行维护,有不同步的风险

4.4. 使用函数的状态机

4.4.1. 状态完全是由一个函数来表示

4.4.2. 不需要单独跟踪状态

4.4.2.1. 状态与处理逻辑保持同步

4.4.2.2. 去掉了枚举

4.4.2.3. 去掉状态属性

4.4.2.4. 去掉处理转交给合适方法的switch语句

4.4.3. 更简洁的实现

4.4.3.1. 缺点:每种状态关联更多信息要显式声明可能的状态和转移

4.5. 使用和类型的状态机

4.5.1. 把每种状态表示为一个单独的类型

4.5.2. 整个状态机表示为可能状态的一个和类型

4.5.3. 把状态机分解到类型安全的组件中

4.5.4. 比依赖函数的实现更长

4.5.4.1. 优点:允许我们在每种状态中添加属性和成员,把它们组合在一起

4.6. 不使用switch语句的状态机

5. 延迟计算

5.1. 可以传递函数而不是传递实际的值,并在需要值的时候调用这些函数

5.2. 纯粹的面向对象结构可以实现,但是代码比函数式多得多

5.3. 许多函数式编程语言共有的特征

5.3.1. 所有内容都是尽可能晚计算的

5.4. lambda

5.4.1. 匿名函数

5.4.2. 一次性函数

5.4.2.1. 只会引用这种函数一次,所以为其命名就成了多余的工作

6. 立即计算

6.1. 立即得到并传递值,即使我们在以后决定丢弃该值

6.2. 命令式编程语言(如TypeScript、Java、C#和C++)

7. 一阶函数

7.1. 普通函数

7.2. 接受一个或多个非函数实参并返回一个非函数类型的“标准”函数

8. 高阶函数

8.1. 定义:把所有接受或返回其他函数的函数

8.1.1. 二阶函数

8.1.1.1. 接受一个一阶函数作为实参或者返回一个一阶函数的函数

8.1.2. 三阶函数

8.1.2.1. 接受二阶函数作为实参或者返回二阶函数的函数

8.2. 基础算法

8.2.1. map()

8.2.1.1. 给定某个类型的值的一个集合

8.2.1.2. 对其中每个值调用一个函数

8.2.1.3. 返回结果集合

8.2.1.4. 自制map

8.2.1.4.1. 一个T数组和一个函数作为实参
8.2.1.4.2. 该实参函数接受项目T作为实参,并返回U类型的一个值
8.2.1.4.3. 函数把结果添加到一个U数组中

8.2.1.5. C# System.Linq Select()

8.2.1.6. Java java.util.stream map()

8.2.2. filter()

8.2.2.1. 给定一个数据项集合和一个条件

8.2.2.2. 过滤掉不满足该条件的数据项

8.2.2.3. 返回满足该条件的数据项集合

8.2.2.4. 自制filter

8.2.2.4.1. 输入数组的类型为T
8.2.2.4.2. 过滤函数接受T作为实参,并返回boolean结果
8.2.2.4.2.1. 谓词

8.2.2.4.2.1.1. 接受一个实参并返回一个boolean的函数

8.2.2.4.3. 返回过滤后的输出

8.2.2.5. C# System.Linq Where()

8.2.2.6. Java java.util.stream filter()

8.2.3. reduce()

8.2.3.1. 将所有集合项合并为一个值

8.2.3.1.1. 创建一个初始值
8.2.3.1.2. 遍历集合并把每个数据项与累积项合并,不断累积结果
8.2.3.1.3. 遍历完集合后返回累积结果

8.2.3.2. 自制reduce

8.2.3.2.1. 泛型函数
8.2.3.2.1.1. 实参为T数组
8.2.3.2.1.2. 实参T类型的一个初始值

8.2.3.2.1.2.1. 需要处理输入数组为空的情况

8.2.3.2.1.3. 实参一个接受两个T类型的实参并返回T类型的结果

8.2.3.3. C# System.Linq Aggregate()

8.2.3.4. Java java.util.stream reduce()

8.2.3.5. 没有幺半群时

8.2.3.5.1. 考虑初始值是什么
8.2.3.5.2. 在哪个方向上进行缩减

8.3. 抽象代数

8.3.1. 处理集合以及集合上的操作

8.3.2. T值集合上的一个操作

8.3.2.1. 类型T的一个操作接受两个T作为实参,并返回另一个T,即(T, T) => T

8.3.3. 单位元

8.3.3.1. T的一个元素id

8.3.3.2. 操作op(x, id) == op(id, x) == x

8.3.3.3. id与其他任何元素合并起来,并不会改变其他元素

8.3.3.3.1. 操作是加法时,单位元是0
8.3.3.3.2. 操作是乘法时,单位元是1
8.3.3.3.3. 操作为字符串连接时,单位元是“”(空字符串)

8.3.4. 相关性

8.3.4.1. 操作的一个属性

8.3.4.2. 对元素序列应用操作的顺序并不重要,因为最终结果是相同的

8.3.4.3. op(x, op(y, z)) == op(op(x, y), z)

8.3.4.3.1. 加法
8.3.4.3.2. 乘法
8.3.4.3.3. 减法
8.3.4.3.4. 连接两个字符串的首字母

8.3.5. 幺半群(monoid)

8.3.5.1. 有一个单位元

8.3.5.2. 具有相关性

8.3.5.3. 不要求提供初始值

8.3.5.3.1. 在集合为空时默认使用单位元

8.3.6. 半群(semigroup)

8.3.6.1. 没有单位元

8.3.6.1.1. 把初始值放到第一个元素的左边或者最后一个元素的右边很重要

8.3.6.2. 具有相关性

以上是关于读改变未来的九大算法笔记07_搜索引擎的主要内容,如果未能解决你的问题,请参考以下文章

读Java性能权威指南(第2版)笔记23_ 性能分析工具

读编程与类型系统笔记05_函数类型

读编程与类型系统笔记07_子类型

读SQL进阶教程笔记07_EXISTS谓词

读Java性能权威指南(第2版)笔记07_即时编译器上

读Java实战(第二版)笔记02_行为参数化Lambda表达式