工作中有很多工作调度和资源匹配的场景,比如客服,技术支持或工单分派:带有文本描述的工单被录入系统,模糊匹配资源库中的人力资源,然后被分配给最适合的人处理。在一些场景中,工单的执行结果和评价也会被记录,作为工单分派信息的一部分被保留。
由于场景复杂而且缺少标准化的问题描述,很多这类匹配问题仍然依赖人工,造成匹配时间延迟,匹配资源基于个人喜好和习惯而非基于可量化的标准。另外由于工单和资源的数据量巨大,一般的数据库查询很难满足实时查询需求。
为了解决查询性能和文本模糊匹配的问题,在案例中尝试使用了工业级实时分布式搜索引擎ElasticSearch,并结合元启发式算法simulated annealing根据历史数据寻找各个搜索键值的权重提升匹配准确度。
ElasticSearch简介
参考ES简介,这里不再赘述,仅做摘要:
ES=elaticsearch简写, 是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
Elasticsearch使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。
全文索引就是把内容根据词的意义进行分词,然后分别创建索引,例如”你们的激情是因为什么事情来的” 可能会被分词成:“你们“,”激情“,“什么事情“,”来“ 等token,这样当你搜索“你们” 或者 “激情” 都会把这句搜出来。
特点和优势
1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。
2)实时分析的分布式搜索引擎,负载再平衡和路由在大多数情况下自动完成。
3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试)
4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。
算法相关:
算法分为两大部分:Elasticsearch 文本匹配和推荐算法,以及搜索参数空间的退火算法。
文本匹配:
文本匹配使用elasticsearch6 自带reverse indexing 和TF-IDF功能:
coord(query, doc):文档(doc)里含有的查询(query)里的关键词(term)个数。coord(q,d) = 关键词并集/查询关键词总数
queryNorm(query):查询标准化得分。 q u e r y N o r m = 1 s u m O f S q u a r e d W e i g h t s queryNorm = \cfrac{1}{\sqrt{sumOfSquaredWeights}} queryNorm=sumOfSquaredWeights1,其中 s u m O f S q u a r e d W e i g h t s = q u e r y B o o s t 2 ⋅ ∑ term in query ( i d f ( t e r m ) ⋅ t e r m B o o s t ) 2 sumOfSquaredWeights = queryBoost^2 \cdot \sum_{\text{term in query}} \big( idf(term) \cdot termBoost \big)^2 sumOfSquaredWeights=queryBoost2⋅∑term in query(idf(term)⋅termBoost)2
norm(term, doc):字段标准化得分。norm(t,d) = lengthNorm * 所有字段加权权重的乘积(field boost)
tf(\text{term in doc}):term frequency,关键词term 在对应文档doc中的出现频率得分。 t f ( t in d ) = f r e q u e n c y tf(\text{t in d})=\sqrt{frequency} tf(t in d)=frequency。
idf(term): inverse document frequency, i d f ( t ) = 1 + l o g ( n u m D o c s d o c F r e q + 1 ) idf(t)=1+log(\cfrac{numDocs}{docFreq + 1}) idf(t)=1+log(docFreq+1