# 2.1.处理文本的机器

## 1. NLP基础

* 语料库：Corpus
* 词库：Lexicon
* 向量空间/向量空间模型
* 位向量语言模型
* 超空间（**后续需要详细理解**）

### 1.1. 定义

    **自然语言处理**——是计算机科学和人工智能（AI）的一个研究领域，它关注自然语言的处理。这种处理通常包括将自然语言转换成计算机能够用于理解这个世界的数据（数字），同时，这种对世界的理解有时被用于生成能够体现这种理解的自然语言文本（即自然语言生成）。

    **自然语言处理系统**——通常被称为“流水线”（pipeline），这是因为该系统往往包括多个处理环节，其中自然语言从“流水线”一端输入，处理后结果从另一头输出。

    **经典心智计算理论**——这种经典NLP模式匹配方法是建立在心智计算理论（CTM）的基础上的，CTM假设类人NLP可以通过一系列处理的有限逻辑规则集来完成。神经科学和NLP的进步导致心智“连接主义”理论的发展，允许并行流水线同时处理自然语言，就像神经网络一样。

### 1.2. 应用

    NLP应用表格：

| 搜索   | Web    | 文档     | 自动补全  |
| ---- | ------ | ------ | ----- |
| 编辑   | 拼写     | 语法     | 风格    |
| 对话   | 聊天机器人  | 助手     | 行程安排  |
| 写作   | 索引     | 用语索引   | 目录    |
| 电子邮件 | 垃圾邮件过滤 | 分类     | 优先级排序 |
| 文本挖掘 | 摘要     | 知识提取   | 医学诊断  |
| 法律   | 法律断案   | 先例搜索   | 传票分类  |
| 新闻   | 事件检测   | 真相核查   | 标题排字  |
| 归属   | 剽窃检测   | 文学取证   | 风格指导  |
| 情感分析 | 团队士气监控 | 产品评论分类 | 客户关怀  |
| 行为预测 | 金融     | 选举预测   | 营销    |
| 创作   | 电影脚本   | 诗歌     | 歌词    |

### 1.3. 计算机“眼中”的语言

    正则表达式使用一类特殊的正则语法（Regular Grammar，又称为**锁语言**）的形式语言语法。**注意**：Python和Posix（Unix）应用环境中的正则表达式并不是真正的正则语法。使用正则语法匹配搜索并且设计机器人答复相关内容是一种形式化的方式，处理这种语言的机器可以看作是一个形式化的数学对象——**有限状态机**（FSM）或**确定性有限自动机**（DFA）。下图是有限状态机在自动机类型中的位置：

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-6c6618ee305c598aecf0f88dd94307b5c6ef7bf5%2F2021-10-17-15-01-39.png?alt=media)

    形式语言的形式数学解释：

* 大多数（如果不是所有）编程语言都来自上下文无关语言这一类。
* 上下文无关语言使用上下文无关语法进行高效的解析。
* 正则语言也可以有效地进行解析，并广泛用于字符串匹配的计算中。
* 字符串匹配应用程序基本不需要上下文无关的表达能力。
* 有许多类型的形式语言，按复杂性从高到低排序：
  * 递归可枚举的
  * 上下文有关的
  * 上下文无关的
  * 正则

    对自然语言则是下边这种解释：

* 不是正则的
* 不是上下文无关的
* 用任何形式语法都无法定义

### 1.4. 词袋模型

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-c3d59be1dc5d8c6ff3b2f3985a0fe73c76185962%2F2021-10-17-15-17-04.png?alt=media)

### 1.5. 超空间

    高维词向量之间的距离使用**余弦距离**。

    我们需为消息创建一些降维的向量空间模型，回答以下问题：

* 这条消息有多大可能成为一个被提问的问题？
* 这条消息有多大可能是和人有关的？
* 这条消息有多大可能是关于我自己的？
* 这条消息听起来愤怒或高兴的程度有多高？
* 这个问题是否需要我做出回复？

### 1.6. 词序/语法

    词的顺序很重要，那些在词序列（句子）中控制词序的规则被称为语言的语法（Grammar，也称文法）；不论使用形式化编程语言，还是非形式化编程语言，语句若要表达事物之间的逻辑关系，词序和语法都十分重要——所以计算机语言才会依赖严格的词法和句法规则分析器的原因。

### 1.7. 聊天机器人

    聊天机器人的4个处理阶段：

1. **解析**：从自然语言文本中提取特征、结构化数值数据。
2. **分析**：通过对文本的情感、语法合法度、语义大粪，生成和组合特征。
3. **生成**：使用模板、搜索或语言模型生成可能的回复。
4. **执行**：根据对话历史和目标，规划相应语句，并选择回复。

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-df0723e7b26aca4593045e92d639deaf4c2f2acf%2F2021-10-17-15-42-21.png?alt=media)

### 1.8. 深度处理

    深度学习是通过在传统的两层机器学习模型架构（特征提取+建模）中添加额外的处理层来创建更复杂的模型和行为。

    NLP流水线中的示例层：

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-fea5799ca7b27a0214deb483da3258c30b333938%2F2021-10-17-15-46-28.png?alt=media)

* [开源项目ChatterBot](https://github.com/gunthercox/ChatterBot)
* [开源项目Will](https://github.com/skoczen/will)

### 1.9. 自然语言智商

    衡量机器人系统能力的一种常见方法是：根据系统行为的复杂性和所需的人类监督程度这两个维度来衡量。NLP系统的二维智商展示：

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-dff84db1b81bedcf49335d0d9684f09f3b88f037%2F2021-10-17-15-59-24.png?alt=media)

    聊天机器人需要所有的NLP工具：

* 特征提取（产生一个向量空间模型）。
* 通过信息提取回答事实型问题。
* 通过语义搜索从自然语言文本或对话的历史记录中学习。
* 通过自然语言生成来构成有意义的新语句。

## 2. 词汇表——分词

* 词干还原（Stemming）

> 词是什么？ 如何将文本切分成词？

    当需要调整分词器以便从具体应用的文本中提取更多或不一样的信息时，进行学习。

### 2.1. 词干还原

    **词干还原**指的是将某个词的不同曲折变化形式（如`flower`和`flowers`）统统**打包**到同一个桶或类别中。

### 2.2. 分词器构建词汇表

    NLP中，分词是NLP流水线的第一步：

* **分词Tokenization**：也称切词，是一种特殊的文档切分（Segmentation）过程。
* **文档切分**：可以将文档分成段落、将段落分成句子、将句子分成短语、将短语分成词条（通常是词）。

    编译计算机语言的分词器分**扫描器**（Scanner）和**词法分析器**（Lexer），某种计算机语言的词汇表可构成**词库**（Lexicon）。等价模块：

| 自然语言             | 编译型计算机语言    |
| ---------------- | ----------- |
| 分词器              | 扫描器、或称词法分析器 |
| 词汇表              | 词库          |
| 分析器              | 编译器         |
| 词条、词项、词或`n-gram` | 标识符或终结符     |

    使用分词技术可构建每个词的数值向量表示——这些向量称为**独热向量**（One-Hot Vector），这些独热向量构成的序列能够以向量序列（数字构成的表格）的方式完美捕捉原始文本。独热向量类似如下格式：

```python
array([
    [0,0,0,1,0,0,0,0,0,0],
    [0,1,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,1,0,0,0],
    [0,0,0,0,0,0,0,1,0,0],
    [0,0,1,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,1],
    [0,0,0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,1,0],
    [1,0,0,0,0,0,0,0,0,0]
])
```

    独热向量很稀疏，每个行向量中只有一个**非零值**，每一行的向量对应一个独立的词。上述表格的每一行都是一个二值的行向量，这就是该向量称为独热向量的原因——该一行的元素中，`1`意味着打开或热，`0`意味着关闭或者缺失，这样一个向量就可以表示某个词。独热方式可以将一个词语向量化，而且保证了没有任何信息的丢失，计算机就可以理解这些数值了，但是——整个向量表格十分大，哪怕一个小的文档，计算量都是百万级的，所以需要针对它进行**降维**处理。——存储所有`0`并试图记住所有文档中的词序意义不大，我们处理文档的本质是将语义压缩，将它压缩成单个向量而不是一张宽表（高维矩阵）。

    **方法一**：忽略词的顺序和语法，将它们混合在一个**袋子**中，每个句子或短文对应一个袋子呢？——把所有独热向量加一起，而不是一次一个**放回**，这样就会得到一个**词袋向量**。——这个向量也称为词频向量，它只计算了词的**频率**（Frequency）。

    **方法二**：若正在执行关键词搜索，可以对这些独热词向量执行OR处理，从而得到一个二值的词袋向量。

#### 2.2.1. 点积

    点积也称为内积（Inner Product）——两个向量（每个向量中的元素个数）或矩阵（第一个的行和第二个的列）**内部维度**必须一致，这样才能相乘。

    点积也称为标积（Scalar Product），因为输出结果是一个单独的标量值，它有别于叉积（Cross Product）概念，后者输出不是标量值而是一个向量。

    点积通过计算重合词条的数量来**计算句子之间的相似度**。

#### 2.2.2. 度量词袋之间重合度

    如果能够度量两个向量词袋之间的重合度，就可以很好估计它们所用词的相似程度，这也是它们语义上重合度的估计。——**词之间的重合度可以作为句子相似度的一种衡量方法**，您可以构造您的第一个向量空间模型（VSM）。

#### 2.2.3. 标点符号

1. 正则表达式的工作机理
2. 改进的用于分词的正则表达式
   1. spaCy：精确、灵活、快速（Python实现）
   2. Stanford CoreNLP——更精确，不够灵活和快速（Java 8）
   3. NLTK——NLP竞赛和对比标配，流行（Python实现）
3. 缩略语

#### 2.2.4. 词汇表扩展到`n-gram`

**1.n-gram**

    `n-gram`是一个最多包含n个元素的序列，它是从字符串中提取而成；`n-gram`不一定要求像复合词一样有特定的含义，而仅仅要求出现频率足够高以引起**词条计数器**的注意。如果特征向量维度超过所有文档总长度，特征提取过程就不会达到预期的目的。

**2.停用词**

    任何一种语言中，停用词（Stop Word）表示出现频率非常高的常见词，但对短语含义而言，这个词语承载的实质性信息内容却很少。——传统做法中，NLP流水线会剔除停用词，以便减小从文本中提取信息时的计算压力，如何设计**停用词过滤器**依赖具体的应用，而词汇表的大小决定NLP流水线所有后续步骤的计算复杂性和内存开销。

    为了得到相对**标准**的停用词表，可参考NLTK，它提供了最普遍的停用词表。

#### 2.2.5. 词汇表归一化

**1.大小写转换**

    两个单词只有大小写形式不同时，大小写转换会用来把不同大小写形式统一处理，将这种不统一的大小写形式统一化称为**大小写归一化**（Case Normlization），或**大小写转换**（Case Folding）。

1. 但是别忘了：某些单词大小写也表示不同的使用场景，如`docker`和`Docker`。
2. 大小写归一化有可能干扰一些高级分词器，这些分词器可以将驼峰式大小写（Camel Case）的单词进行分割。

    更好的解决方法是只将句首大写字母转成小写，其他单词仍然保持原有形式；另外对不存在大小写概念的语言来说，大小写归一化没有任何作用。为了让模型能够处理那些出现古怪大小写形式的文本，大小写归一化可以减少对机器学习流水线的过拟合情况，而且大小写归一化对搜索引擎尤其有用。

**2.词干还原**

    另外一种常用词汇表归一化是消除词的复数形式、所有格的词尾甚至不同的动词形式带来的意义上的微小差别——这种识别词的不同形式背后的公共词干的归一化方法称为**词干还原**（Stemming）。

    它在限制信息或意义损失的同时，会尽可能减小词汇表的规模，在机器学习中称为**降维**。

* [Snowball](https://snowballstem.org/)
* Porter（未找到官方站点）

**3.词形归并**

    如果知道词义之间可以相互关联、那么可能就能够将一些词关联起来，即使它们的拼写完全不一样。——这种更粗放的将词归一化成语义词根即**词元**（Lemma）的方式称为**词形归并**（Lemmatization）。

    有可能出现这样的词，经过词形归并处理之后，可能会改变词义，甚至得到完全相反的词：这种称为**刻意欺骗**，通过精心构造难以处理的输入，有意使机器学习流水线产生错误响应。

    词形归并是潜在的比词干还原和大小写归一化更具精确性的词的归一化方法；有些词形归并工具除拼写之外还使用词的词性（Part of Speech，POS）标签提高精确率，POS代表了该词在短语或句中的语法角色。

**4.使用场景**

    词干还原、词形归并、大小写转换都将显著降低搜索结果的正确率（Precision）和精确率（Accuracy）。

> 除非文本数量有限，否则就避免使用词干还原和词形归并，此处的归一化是我们的底线。由于目前NLP数据集很大，所以上述归一化方法已经很少见了，还有一种情况就是使用了大量术语、或来自科学、技术、文学的极小子领域。

### 2.3. 情感

    无论哪种NLP，每个词条都包含了一些信息，这些信息中重要部分就是词的情感，——度量短语或者文本块情感的任务称为**情感分析**（Sentiment Analysis）。

    有两种情感分析方法：

* 基于规则的算法，规则由人来撰写。——这种方式使用了用户设计的规则（启发式规则）来度量文本的情感。
* 基于机器学习的模型，模型是机器从数据中学习而得到。——这种方式基于机器学习的方法利用一系列标注语句或者文档来训练机器学习模型以产生规则（如朴素贝叶斯机器学习算法）。

    下边是两种典型的情感分析方法：

* [VADER](https://github.com/cjhutto/vaderSentiment)：一个基于规则的情感分析器
* 朴素贝叶斯

## 3. 词中数学

* **词袋**——词出现频率或词频向量。
* `n-gram`**袋**——词对（2-gram）、三元组（3-gram）等计数。
* TF-IDF向量——更好地表示词的重要度的得分。

> TF-IDF表示词项频率（Term Frequency）$$\times$$ 逆文档频率（Inverse Document Frequency），词项频率是指每个词在某篇文档中的出现次数，而逆文档频率指的是文档集合中的文档总数除以某个词出现的文档总数。

    它们都基于概率，因此都是统计模型。

### 3.1. 词袋

> 之前使用每个词的独热向量，然后将这些向量用二进制OR运算组合以创建文本的向量表示。

    另一种更有用的向量表示：它计算词在给定文本中的出现次数或频率（假设一个词在文档中出现的次数越多，那么该词对文档的意义和贡献度越大），——这种依赖简单规则的算法可能会出错或误导用户。

    TF（Term Frequency）称为词项频率——它表示某个词在给定文档中出现的次数，也可以将某个词出现的频率除以文档中词项的总数从而得到归一化的词项频率结果。

    为什么使用归一化的词频？如`dog`在A中出现3次，B中出现100次，使用没有归一化的词频会觉得`dog`对B更重要，但如果A是一封写给兽医的信（30个词），而B是《战争与和平》（580,000）个词，那么情况和上述情况相反，所以最终应该是：

$$TF('dog',document\_A) = 3/30 = 0.1$$

$$TF('dog',document\_B) = 100/580 000 = 0.00017$$

    因此，原始词频一般不用来描述文档，取而代之是**归一化词项频率**。

### 3.2. 向量化

    基于文本的内容转换成了数值，那么就是一个数学问题了，接下来使用数学手段来计算——但不使用频率字典描述文档，而是构造词频向量。计算方法：

1. 计算归一化词项频率。
2. 将所有向量都转换到标准长度或维度上。

    我们期望每个文档向量同一维上的元素值代表同一个词；在每篇文档中找到独立词，然后将这些词集合求并集后从中再找到每个独立词。——词汇表中这些词集合通常称为词库（Lexicon），最终将文档转换成向量。

#### 3.2.1. 向量空间

    向量是线性代数或向量代数的主要组成部分，它是一个有序的数值列表，或者说这些数值是向量空间中的坐标。它描述了空间中的一个位置，或者它也可以用来确定空间中一个特定方向和大小或距离。空间（Space）是所有可能出现在这个空间中的向量的集合，所以（x,y）位于二维空间，(x,y,z)位于三维空间。

    二维空间向量图示如下：

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-a2e32b534bfd07b77f9fafaa509f41b1ef50b103%2F2021-10-17-20-08-25.png?alt=media)

    对自然语言文档向量空间而言，向量空间的维数是整个语料库中出现的不同词的数量，——自然语言向量空间维度通常高于三维，所以无法使用图示，但如果是二维空间则可直接像上边的图示一样，直接使用图示法呈现：

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-3dcfd5e0015acf42237f0537c79055949df1dd67%2F2021-10-17-20-11-13.png?alt=media)

> **注意**：欧几里得距离对词频向量来说并不是计算距离的好方法！

    高维向量的工作方式和低维向量工作方式是一致的，只是单纯地不太容易可视化。如果两个向量方向相似，则二者就“相似”，它们可能有相似大小（长度），意味着两个词频向量所对应的文档长度基本相等。这种情况一般使用余弦距离计算（欧几里得距离**点积**，取值范围位于`[-1,1]`）：

$$A \cdot B = |A||B| \times \cos{\theta}$$

![](https://3776797973-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MkW0vdxiACBavm67CgB%2Fuploads%2Fgit-blob-e68700a5ba2bd242bd1186ad1f44e94d0db31aa8%2F2021-10-17-20-18-16.png?alt=media)

    归一化的点积（Normalized Dot Product）输出就像余弦函数一样，取值`[-1,1]`，它也是这两个向量夹角余弦值：

1. 相似度为1则表示两个向量方向完全相同，所以——计算时两个向量点积除以每个向量的模的计算可以在点积之前或之后进行。
2. 相似度为0表示两个向量之间没有共享任何分量，二者是正交的，在所有维度上都相互垂直（两篇文档没有公共词才会出现）。
3. 相似度为-1表示两个向量是反相似（Anti-Similar）的，即完全相反（词频向量不会出现这种情况，频率不可能为负数）。

### 3.3. 齐普夫定律

    *齐普夫定律（Zipf's Law）指出，在给定的自然语言语料库中，任何一个词的频率与它在频率表中的排名成反比。*

    反比例：排序列表中某一项的出现频率与其在排序列表中的排名成反比。——一种现象：对一个足够大的样本，出现次数排名第一的词在语料库中的出现次数是排名第二的词的两倍，是排名第四的词的4倍。因此，给定一个大型语料库，可以用上述数字来粗略统计给定词出现在该语料库的任何给定文档中的可能性。

### 3.4. 主题建模

    逆文档频率（IDF），在齐普夫定律下打开了一扇新窗户。

> 如果一个词项在某篇文档中出现很多次，但是却很少出现在语料库的其他文档中，那么就可以假设它对当前文档十分重要。

$$IDF = \log(\frac{document\_{total}}{document\_w + 1})$$

* $$document\_total$$：语料库的文档总数
* $$document\_w$$：包含词条$$w$$的文档数
* `+1`的目的是为了避免分母为0

#### 3.4.1. 回到齐普夫

    用例子说明，如果有人在100万份文档中搜索`cat`和`dog`两个词语：

| 关键词 | 出现次数 | 原生IDF          | 计算后                |
| --- | ---- | -------------- | ------------------ |
| cat | 1    | 1 000 000 / 1  | 6 = log(1 000 000) |
| dog | 10   | 1 000 000 / 10 | 5 = log(100 000)   |

    由于数据量差距太大，所以需要对此进行尺度缩放，使用`log`函数计算，所以现在根据在语言中出现的次数对前边的$$TF$$进行加权，最终整理公式如下：

$$TF(w,d) = \frac{词条w在文档d中出现次数}{文档d的长度}$$

$$IDF(w,D) = \log{\frac{文档数}{包含w的文档数量}}$$

$$TF-IDF(w,d,D) = TF(w,d) \times IDF(w,D)$$

    一个词在文档中出现次数越多，在文档中的TF就会越高，同时若包含该词的文档数增加，则该词的IDF将下降，二者方向相反。

#### 3.4.2. 相关度排序

    如果两个向量的余弦相似度很高，那么它们被认为是相似的，最小化余弦相似度就可以找到两个相似向量：

$$\cos\theta = \frac{A \cdot B}{|A||B|}$$

> 提示：在前面的代码中，我们去掉了词库中没有找到的键，以避免零除错误。但是更好的方法是，每次计算IDF时分母都加1，这样可以确保分母不为0。事实上，这种称为加法平滑（拉普拉斯平滑）的方法通常会改进基于TFIDF关键词搜索的搜索结果。

#### 3.4.3. TF-IDF变种

    其他TF-IDF归一化方法（不用全理解）

| 方案         | 定义                                                                                                                                                                             |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| None       | $$w\_{ij} = f\_{ij}$$                                                                                                                                                          |
| TF-IDF     | $$w\_{ij} = \log(f\_{ij}) \times \log{(\frac{N}{n\_j})}$$                                                                                                                      |
| TF-ICF     | $$w\_{ij} = \log(f\_{ij}) \times \log{(\frac{N}{f\_j})}$$                                                                                                                      |
| Okapi BM25 | $$w\_{ij} = \frac{f\_{ij}}{0.5 + 1.5 \times \frac{f\_j}{\frac{f\_j}{j}} + f\_{ij}} \log{\frac{N - n\_j + 0.5}{f\_{ij} + 0.5}}$$                                                |
| ATC        | $$w\_{ij} = \frac{(0.5 + 0.5 \times \frac{f\_{ij}}{\max\_f}) \log{\frac{N}{n\_j}}}{\sqrt{\sum\_{i=1}^N\[(0.5 + 0.5 \times \frac{f\_{ij}}{\max\_f}) \log{\frac{N}{n\_j}}]^2}}$$ |
| LTU        | $$w\_{ij} = \frac{(\log(f\_{ij}) + 1.0) \log{\frac{N}{n\_j}}}{0.8 + 0.2 \times f\_j \times \frac{j}{f\_j}}$$                                                                   |
| MI         | $$w\_{ij} = \log \frac{P(t\_{ij} \rvert c\_j)}{P(t\_{ij})P(c\_j)}$$                                                                                                            |
| PosMI      | $$w\_{ij} = \max(0, MI)$$                                                                                                                                                      |
| T-Test     | $$w\_{ij} = \frac{P(t\_{ij} \rvert c\_j) - P(t\_{ij})P(c\_j)}{\sqrt{P(t\_{ij})P(c\_j)}}$$                                                                                      |
| $$x^2$$    | 参考`James Richard Curran`的`From Distributional to Semantic Similarity`的4.3.5节                                                                                                   |
| Lin98a     | $$w\_{ij} = \frac{f\_{ij} \times f}{f\_i \times f\_j}$$                                                                                                                        |
| Lin98b     | $$w\_{ij} = -1 \times \log \frac{n\_j}{N}$$                                                                                                                                    |
| Cref94     | $$w\_{ij} = \frac{\log f\_{ij} + 1}{\log n\_j + 1}$$                                                                                                                           |

> 直接使用TF-IDF余弦距离对查询结果进行排序的一种代替方法为`Okapi BM25`以及最新变体`BM25F`。

#### 3.4.4. Okapi BM25

**（暂略，后续查资料处理）**

    除了计算TF-IDF余弦相似度，还对相似度进行了归一化和平滑处理，他们还忽略了查询文档中词项的重复出现，从而有效地将查询向量的词频简化为1。

## 4. 小结

* 词的意义和意图可以被机器破译。
* 一个智能的NLP流水线可以处理歧义。
* **聊天机器人**是一种语义搜索引擎。
* `n-gram`分词功能可以保留文档中的一些词序信息。
* 归一化以及词干还原将词分组，可提高搜索引擎的召回率，但降低了正确率。
* 停用词可能包含有用的信息，去掉停用词不一定很好。
* 任何秒级响应的Web级搜索引擎，背后都具有TF-IDF词项文档矩阵支撑。
* 词项频率必须根据逆文档频率加权，以确保最重要、最有意义的词得到应该的权重。
* TF-IDF词项-文档矩阵的行可以表示单个词含义的向量，从而创建向量空间模型。
* 余弦距离即向量之间重合度，可以将归一化向量的元素相乘后再乘积相加，它是大多数自然语言向量计算相似度的方法。
