WEBUS2.0 In Action - 搜索操作指南 - (3)

本文详细介绍了WEBUS2.0搜索系统的内部工作原理,包括查询分析、索引读取、结果集合并、评分、排序及过滤等关键步骤,并提供了一些内置组件的具体实现细节。

上一篇:WEBUS2.0 In Action - 搜索操作指南(2) | 下一篇:WEBUS2.0 In Action - 搜索操作指南(4)


3. 评分机制 (Webus.Search.IHitScorer)


IndexSearcher在完成搜索之后会利用Webus.Search.IHitScorer来对结果进行评分.


复制代码

namespace Webus.Search
{
    public interface IHitsScorer
    {
        void Score(Hits hits, Query query);
    }
}

复制代码

在进行评分时, 我们主要参考结果集hits, 同时也要参考用于搜索的query对象, 从而可以根据用户的原始查询需求来设定每个结果的权重.


IHitScorer.Score方法由IndexSearcher自动调用, 分数信息将保存在HitDoc.Score字段中:


复制代码

public class HitDoc
{
    //...
    public float Score { get; set; }
    //...
}

复制代码

WEBUS2.0 SDK包含一个默认评分器: Webus.Search.DefaultScorer, 它对一个结果进行两次评分, 第一次根据基本属性评分, 规则如下:



分数1 = Log10(文档关键词匹配个数 + 1) * query权重 (query.Boost) * 文档权重 (doc.Boost)


然后它会进行第二次评分, 这次主要考量关键词的前后相关性:


复制代码

分数2 = 
foreach(var hit in hits)
{
    foreach(var pos in hit.Positions)
    {
        如果前后挨着的两个匹配 (pos) 满足如下条件, 则加分:
        a. 分别来自于两个不同的子查询
        b. 在文档位置上彼此前后相连
    }
}

复制代码

最后的分数 = 分数1 + 分数2.


这套规则综合考量了索引和搜索过程中所有的重要变量:



1. 文档权重 - Document.Boost
2. 查询权重 - Query.Boost
3. 匹配数目的多寡 - Log10(hit.Positions.Count)
4. 匹配的相关性


因此能够较好的反应结果相关性, 是比较理想的评分器. 当然, 在实际运用中, 我们随时可以创造自己的个性化评分器, 只要实现IHitScorer接口即可. 


4. 排序 (Webus.Search.IHitSorter)


排序发生在评分之后. IndexSearcher利用IHitSorter来完成排序操作:


复制代码

namespace Webus.Search
{
    public interface IHitsSorter : IComparer<HitDoc>
    {
        void Sort(Hits hits);
    }
}

复制代码

排序只需传入结果集hits即可. WEBUS2.0 SDK中内置了多种排序器:


DocIdSorter - 根据DocId的大小进行升序或降序排序. 通常我们也用这个排序器来实现对时间排序. 因为一般情况下, DocId大的文档时间靠后, DocId小的文档时间靠前. 



public DocIdSorter(bool ascending) { ... }


FieldSorter - 根据指定Field的值进行升序或降序排序. 注意这个排序器会遍历结果集中指定Field的值, 因此当数据量非常大时会存在一定的性能瓶颈.



public FieldSorter(string fieldname, bool ascending, ISearcher searcher) {...}


ScoreSorter - 顾名思义, 根据评分来排序, 同样也支持升序和降序两种方式



public ScoreSorter(bool ascending) {...}


5. 过滤器 (Webus.Search.IHitFiler)


过滤发生在排序之后, 由过滤器 IHitFilter 来完成. 


复制代码

namespace Webus.Search
{
    public interface IHitsFilter
    {
        void Filter(Hits hits);
    }
}

复制代码

过滤器的职责非常明确, 就是裁剪结果集大小. 这个处理步骤虽然最后发生, 其实非常实用. 比如结果分页, 比如去重都靠它来实现. 在WEBUS2.0 SDK中, 包含了如下过滤器:


PageFilter - 分页过滤器



//index - 起始记录位置
//count - 要显示的记录条数
public PageFilter(int index, int count) {...}


UniqueFilter - 去重过滤器



//fieldName - 将根据指定的字段的值来去重
public UniqueFilter(string fieldName) {...}


FieldFilter - 字段过滤器



public FieldFilter(string fieldname, object minValue, object maxValue) {...}


指定字段的最大值, 最小值进行过滤. 注意, 此过滤器同样也需要遍历结果集中指定字段的值, 因此在结果数目巨大的情况下会存在性能问题. 


小结


WEBUS的搜索过程遵循着这样一条线进行:


分析查询对象Query, 生成子查询 -> 读取索引, 执行子查询 -> 合并结果集 -> 评分 -> 排序 -> 过滤 -> 返回结果


SDK的灵活之处就在于每个环节都提供了接口, 能够进行二次开发. 当然, 一般情况下我们只需要对评分及其之后的步骤进行二次开发即可满足大部分应用需求, 估计绝少有人会劳神费力的去开发前面的步骤 :). 虽然我们的实现可能不是最优化, 但是一定具备很强的普适性, 这也是WEBUS2.0的价值所在. 我衷心的希望有人能够利用WEBUS2.0 SDK来解决问题, 这也是对我们努力的宝贵肯定!


相关信息及WEBUS2.0 SDK下载:继续我的代码,分享我的快乐 - WEBUS2.0


访问我们的站点: www.gdtsearch.com

根据原作 https://pan.quark.cn/s/459657bcfd45 的源码改编 Classic-ML-Methods-Algo 引言 建立这个项目,是为了梳理和总结传统机器学习(Machine Learning)方法(methods)或者算法(algo),和各位同仁相互学习交流. 现在的深度学习本质上来自于传统的神经网络模型,很大程度上是传统机器学习的延续,同时也在不少时候需要结合传统方法来实现. 任何机器学习方法基本的流程结构都是通用的;使用的评价方法也基本通用;使用的一些数学知识也是通用的. 本文在梳理传统机器学习方法算法的同时也会顺便补充这些流程,数学上的知识以供参考. 机器学习 机器学习是人工智能(Artificial Intelligence)的一个分支,也是实现人工智能最重要的手段.区别于传统的基于规则(rule-based)的算法,机器学习可以从数据中获取知识,从而实现规定的任务[Ian Goodfellow and Yoshua Bengio and Aaron Courville的Deep Learning].这些知识可以分为四种: 总结(summarization) 预测(prediction) 估计(estimation) 假想验证(hypothesis testing) 机器学习主要关心的是预测[Varian在Big Data : New Tricks for Econometrics],预测的可以是连续性的输出变量,分类,聚类或者物品之间的有趣关联. 机器学习分类 根据数据配置(setting,是否有标签,可以是连续的也可以是离散的)和任务目标,我们可以将机器学习方法分为四种: 无监督(unsupervised) 训练数据没有给定...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值