HubbleDotNet 索引分词的测试方法和分词技巧

在中文搜索中,分词技术是一个比较关键的技术,我们往往会遇到查询某个关键字无法匹配到相应文档的问题,这种问题往往都是索引的分词不理想造成的,倒排索引的技术特点决定了如果查询的关键字不在索引的分词中,则无法查出相应的文档。为了帮助使用者分析分词问题,hubbledotnet 专门提供几个存储过程来帮助检查索引分词的情况。

 分词的测试方法
首先要找到要测试的原始文本
我们往往发现某些记录包含有查询关键字,但查不出来,这个时候我们需要先找到这个出问题的记录的原始文本。查找原始文本的方法很多,你可以通过 docid 或者id 或者其他条件来查找。

下面给出一个通过 id 来查找的示例。如果我们发现id = 1 的记录 title 无法匹配出来,我们可以执行

select * from table where id = 1 找到记录的原始文本。

 

找到原始文本后我们有两种方法来查看记录在索引中的分词情况。

 

方法1: SP_TestAnalyzer
SP_TestAnalyzer 这个存储过程用于测试分词器的分词结果,它的作用是在服务器侧执行分词器的 Tokenize 方法。

这个存储过程有两个参数,第一个参数为分词器名字,这里我们输入 ‘PanguSegment’,第二个参数是要测试的句子。

下面我们执行如下语句,看看效果

SP_TestAnalyzer 'PanguSegment', '六方会谈无核化工作组会议将在沈阳召开'

如上图所示,执行后,可以看到分词的结果。从这个分词结果可以看到原始文本的分词有一些问题,比如无核化和工作组这两个词没有分出来,这时如果搜索”工作组”这个词,则无法匹配到这条记录。我们需要把无核化和工作组两个词加入到盘古的字典中再测试,如果分词正确了,重新索引后,问题就可以解决。

 

方法2:SP_FieldAnalyze
SP_FieldAnalyze 这个存储过程是针对指定表的指定字段的分词器来分词

它有4个参数,参数1为表名,参数2为字段名,参数3为要分词的句子,参数4指定是用 Tokenize 函数还是 TokenizedForSqlClient 函数来分词。第4个参数为可选参数,

如果不输入,就是以 Tokenize 函数分词,如果输入 ‘SqlClient’ 就是以 TokenizedForSqlClient 函数来分词

下面我们首先执行默认的情况,即用 Tokenize 函数分词

SP_FieldAnalyze 'VNews', 'Title', '六方会谈无核化工作组会议将在沈阳召开'
这个语句是采用 VNews 表的 Title 字段的分词器来对 '六方会谈无核化工作组会议将在沈阳召开' 这个句子进行分词,我们可以看出,分词的结果和方法1是一样的。

我们加上 SqlClient 参数后来分词看看效果:

SP_FieldAnalyze 'VNews', 'Title', '六方会谈无核化工作组会议将在沈阳召开','SqlClient'

可以看到后面加了 SqlClient 后,分词结果不同了,这是因为 SqlClient 采用了不同的分词参数。对于盘古分词来说,如果调用 SqlClient 来分词,则服务器侧调用的是program/hubbledotnet/default/PanGuSqlClient.xml 这个配置文件来对文本进行分词,如果不加 SqlClient 参数,则是调用program/hubbledotnet/default/PanGu.xml 这个配置文件分词。

SqlClient 的功能主要是帮助进行查询字符串的分词,HubbleCommand 这个类中有一个函数 GetKeywordAnalyzerStringFromServer 就是用于对查询字符串进行分词的,hubble 的示例代码中也是调用的这个函数,这个函数的里面实际上就是调用 SP_FieldAnalyze  这个存储过程加 SqlClient 来分词。当然在实际项目中,使用着并不是必须要调用这个函数来对查询字符串进行分词,使用者可以用自己的程序对查询字符串分词。

分词的技巧
对于搜索来说,查全率和查准率是一对矛盾,为了尽量平衡这对矛盾,我们在索引和查询时可以采用一些技巧。

技巧1.

索引时最大化分词,如果是用盘古分词进行索引,索引时打开多元分词和强制一元分词。但对查询字符串的分词则采用精确分词,这样可以保证查准的情况下获得较大的查全率。

技巧2.

同义词分词。对于同义词的分词,我们不要在索引中分词,而是在查询字符串中增加同义词的分解,这样可以使查询更灵活,并且可以在查询时设置原词和同义词不同的权重以影响得分排名。

技巧3.

全部一元分词,然后通过索引组件来实现匹配,类似 like ‘%xxx%’ 这样的功能。由于索引组件知道单词在原文本中的位置,所以理论上可以实现类似 like ‘%xxx%’ 这样的功能,这种功能对于短文本的搜索比较有效,而且不需要关心中文的分词。hubbledotnet 将在未来的版本中提供这种方式的快速解决方案,目前版本提供了 like ‘*xxx*’ 的功能,但这个功能还不够完善,速度比较慢。

 

时间: 2025-01-21 09:45:01

HubbleDotNet 索引分词的测试方法和分词技巧的相关文章

基于中文分词的SEO软文技巧三:按词找源

通过(基于中文分词的seo软文技巧一:断句)与(基于中文分词的seo软文技巧二:控制词与核心词)两篇教程,相信大家已经对基于中文分词的软文技巧有了一定的了解,今天王克江教您如何按照我们确定的核心词与控制词查找文章素材. 一.分清控制词与核心词的性质 例子: 6.网带主要应用于蔬菜清洗灭菌机 核心词:网带,灭菌机 控制词:应用 修饰词:蔬菜清洗 核心词是产品与实际应用对接的焦点,那么从核心词的应用或者应用原理必然能有相应的体现,控制词和修饰词才是文章的真正来源. 二.seo软文资源查找 一篇高质量

Lucene 3.6.2入门(5) 自定义停用词分词器和同义词分词器

首先是用于显示分词信息的HelloCustomAnalyzer.java package com.jadyer.lucene; import java.io.IOException; import java.io.StringReader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.toke

NLPIR 搜索分词、输入习惯分词

问题描述 NLPIR 搜索分词.输入习惯分词 NLPIR分词技术,上面的这个 搜索分词,用的是哪个方法呢? 也就是我们平常的输入法习惯的分词. 我试了用下面这个方法,但是效果有点差距 [DllImport("NLPIR.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "NLPIR_ParagraphProcess")] private st

solr分词都用那个分词器啊 ak还是mmseg4j?

问题描述 solr分词都用那个分词器啊ak还是mmseg4j,这两个区别在什么地方啊?那个比较好点啊,对中文的

java-如何用Java实现中文无词典分词,类似于fudannlp分词系统,能不能给出代码?

问题描述 如何用Java实现中文无词典分词,类似于fudannlp分词系统,能不能给出代码? 如何用Java实现中文无词典分词,类似于fudannlp分词系统,能不能给出代码? 解决方案 http://www.iteye.com/magazines/102

pynlpir对多行分词-pynlpir中为什么分词器对于多行的文件不能分词

问题描述 pynlpir中为什么分词器对于多行的文件不能分词 问题是这样的:我用了中科院分词器的python版本的api,pynlpir,它可以支持对文件进行分词操作.但是对于单行的文本文件可以分词,对于多行的文本文件不能分词,这是什么情况.这是我下面的调用接口:#对文件进行分词def splitFile(sSrcFileName sDstFileName): if not nlpir.Init(nlpir.PACKAGE_DIR nlpir.UTF8_CODE None): logging.I

ik analyzer分词器-IK Analyzer分词器使用的时候对于一些中文汉字分不出来

问题描述 IK Analyzer分词器使用的时候对于一些中文汉字分不出来 中文分词器 IK Analyzer对单个汉字有的分不出来怎么办??? 解决方案 添加扩展分词器,但不是最终的解决办法

在RowCommand事件中获取索引值示例代码_实用技巧

在RowCommand事件中获取索引值 1.利用e.CommandSource 复制代码 代码如下: protected void lpg_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "ItemCollect") { GridViewRow gvr = (GridViewRow)(((LinkButton)(e.CommandSource)).NamingContainer);

判断php数组是否为索引数组的实现方法_php技巧

HP没有内置判断是否索引数组的方法,简单实现了一个,用法: 复制代码 代码如下: echo is_assoc($array)?'索引数组':'不是索引数组'; is_assoc函数如下: 复制代码 代码如下:     function is_assoc($array) {        if(is_array($array)) {            $keys = array_keys($array);            return $keys != array_keys($keys)