NLP-传统方法记录

平时学习中遇到的一些传统的做法

1、BM25算法

给你一个句子,和一个文档库。如果想找到与这个句子相关的文档,需要怎么做?

  • 直接想法:对句子embedding,对文档库embedding。遍历文档库,计算余弦相似度,再排序。

    • 稍微优化,计算的时候就排序,有点插入排序的感觉。
    • 问题:遍历是 O ( n ) O(n) O(n),插入排序bad case是 O ( n 2 ) O(n^2) O(n2)【每次都要过一遍,所以是1+2+…n】。此外,向量维度大计算余弦相似度也有时间消耗。
  • 先召回一批可能相关的,再利用embedding计算相似度。然后把召回得分与相似度得分加权。此时,可以考虑用BM25算法对文档进行召回。

BM25算法

  • 作用:计算查询与文档的相关度
  • 计算过程:对query中的每个词,计算其与文档的相似度得分,然后加权。
  • 只能考虑到重合词的问题,无法顾及语义的信息(传统模型的通病)
  • 核心公式:
    S c o r e ( q u e r y , d o c ) = ∑ i = 1 n W i R ( q i , d o c ) Score(query,doc)=\sum_{i=1}^{n}W_iR(q_i,doc) Score(query,doc)=i=1nWiR(qi,doc)
    W i W_i Wi是IDF值, q i q_i qi是query中的词
  • 具体原理见:自然语言处理-BM25相关度打分

关于搜索,可以看这篇

深入理解搜索引擎原理

召回后的排序

利用BM25算法召回了一批文档,得到了其embedding的矩阵(每个文档是一个向量)。如何更快计算query与所有文档的相似度呢?
Faiss流程与原理分析
  
  Faiss是Facebook AI团队开源的针对聚类和相似性搜索库,为稠密向量提供高效相似度搜索和聚类,支持十亿级别向量的搜索,是目前最为成熟的近似近邻搜索库。它包含多种搜索任意大小向量集(备注:向量集大小由RAM内存决定)的算法,以及用于算法评估和参数调整的支持代码。Faiss用C++编写,并提供与Numpy完美衔接的Python接口。除此以外,对一些核心算法提供了GPU实现。
还可以参照这篇:Faiss相似性搜索类库

2、AC自动机

对于NER任务,直接的想法就是序列标注问题,bilstm+CRF来解决。模型的优劣是一方面,要想模型有好的表现,大量的标注数据是不可少的。而且就算精度很高,也会存在一些bad case。实际业务中,还需要很多规则。在NER任务中,如果有业务中的关键词库以及时间这种用正则表达式可以解决的,就可以解决一部分问题。

所以说,基于业务词典,就是给你一个词库,如果句子中的词存在于词库中,就提取出来。
自己的想法:

  • 先将关键词库加入分词字典,分词
  • 遍历句子中的词,如果词在词库中,就抽出来。
  • 时间复杂度 O ( n ∗ m ) O(n*m) O(nm),n 是句子长度,m是词库词数。
  • 如果词库很大,时间复杂度就很高

优化的方法,这是一个多模式匹配问题,解决方案是AC自动机算法,将词库构建成树,只需遍历一遍句子(应该是无需分词?)就可以得到结果。

具体用法:Python——利用AC自动机进行关键词提取

你可能感兴趣的:(NLP)