搜索拼写检查
一、拼写检查的目的
拼写检查功能,能在搜索时,提供一个较好用户体验,所以,主流的搜索引擎都有这个功能。
那么什么是拼写检查,其实很好理解,就是你输入的搜索词,可能是你输错了,也有可能在它的检索库里面根本不存在这个词,但是这时候它能给你返回,相似或相近的结果来帮助你校正。
举个例子,假如你在百度里面输入在在线电瓶,可能它的索引库里面就没有,但是它有可能返回在线电影,在线电视,在线观看等等一些词,这些,就用到拼写检查的功能了。如下图:
二、搜索拼写检查现状
solr搜索系统提供了基本的关键词提示功能,所以常用的正确关键词基本上均可得到较为准确的搜索智能提示。
但是用户输入时会由于各种原因导致的输入错误或是关键词太多,从而搜索系统无法直接利用关键词查找返回用户想要的提示词,这降低了系统的用户体验。
为此需要开发拼写检查模块,即使用户输入错误,也可以根据用户输入进行纠错,从而返回提示词。
经过分析,发现导致出错的主要在于以下几种原因:
-
- 中文拼音混合输入,如:“北京dongwuyuan”。索引中没有中文拼音混合的索引,所以此类关键词基本上无法得到提示词。
- 关键词太长,如:“峨眉山 青城山”。若分开搜索则可以返回结果
- 同音词错误,如:“每国”。用户本意是“美国”。
- 中文或者拼音中带拼音缩写,如:“东方mz”。本意为“东方明珠”。
因此需要分析不同的输入,进行拼写纠错。
三、现有拼写检查方法
开发前先学习了解现有的可用的拼写检查方案,发现主要有两部分:
1、solr自带封装好的拼写检查功能
solr作为全文搜索引擎提供了不少具有使用功能的组件,拼写检查也是其中一部分,但是自带的拼写检查组件只能进行拼音纠错提示,并且成功率不高,约为35%;
solr自带拼写检查不支持中文纠错。因为拼写检查控件原理是首先利用QueryConverter类的convert方法对原始查询的q进行元词分词,得到数个Term,然后分别对各个Term
进行拼写检查,最后返回每个Term的拼写检查结果。
但是自带控件的QueryConverter类实现类SpellingQueryConverter对非ASCII字符支持的不好,比如中文字符串经过分词后会转换为单个中文字符数组,然后对每个中文字符
分别作为Term调用Lucene的接口进行拼写检查,但是lucene的接口拼写检查时检查Term字符串内容的长度,长度小于给定值(默认为4)是不进行拼写检查,直接返回空值。
所以自带拼写检查控件不支持中文拼写检查,需要自行改动并实现相关类才可以使用。
2、lucene提供的拼写检查接口
lucene提供了拼写检查功能接口,开发者可以根据系统需求自由定制,很是方便。
其中包括SpellChecker、DirectSpellChecker、WordBreakSpellChecker等三个类提供的三种拼写检查方式:
SpellChecker类接口的使用需重建索引(根据已有文本或已有索引的一个字段),其拼音检错成功率为69%左右,中文成功率为20%左右;
DirectSpellChecker类提供的拼写检查无需重建索引,可直接使用现存索引,拼音成功率为83%,中文为54%;
WordBreakSpellChecker类暂未测试。
注:
此处测试的元数据是通过分析日志的来的关键词,并且这些关键词是直接搜索无法返回提示词的那部分。
将其中的纯拼音关键词与其他词分开存储分析,拼音关键词总个数即为C1,其他即为C2。
在一次调用lucene接口进行拼写检查中可以返回纠错结果的记为成功一次,无法返回的记为失败。
拼音成功率=拼音成功次数/C1
中文成功率=中文成功次数/C2
四、拼写检查设计方案
基本思路
考虑到搜索系统的模块化,及现有资源的重复利用,此次仿照solr自带拼写检查方案,通过封装Lucene接口实现一个支持中文的solr拼写检查控件,将其直接集成到solr系统中。
这样可以直接利用已有的索引资源,不需要重新建立索引。
1、编写一个类,实现QueryConverter类,功能类似于SpellingQueryConverter类,但是需要支持中文。
该类主要用于分析原始查询字符串,根据特殊字符(如空格等)将原始字符串分为多个元词词组,并且跳过AND/NOT/OR等修饰符号
后续拼写检查就是面向这些元词词组分别进行的。
2、编写一个类,功能类似于DirectSolrSpellChecker,其中封装了lucene的DirectSpellChecker类提供的拼写检查接口。
思路如下:
首先对查询关键词q进行分析,判断q是纯拼音、纯中文还是中英文混合(去除特殊字符),
然后根据用户的不同输入采取不同的拼写检查策略,分为以下三种情况:
a,若是纯拼音则直接调用Lucene的检错接口进行纠错,返回的结果作为拼写检查结果;(纯拼音检错)
b,若是纯中文则先判断是否是同音词错误,即将中文转换为拼音,查看索引中是否有该拼音的索引,
若有则返回该拼音索引对应的中文作为同音词拼写检查结果;(同音词检错)
若不是同音词,则调用Lucene接口进行纠错,返回的结果作为拼写检查结果;(纯中文检错)
c,若是中英文混合,先将其转换为全拼音,调用Lucene接口纠错,若有结果返回,则将结果对应的中文字符串作为拼写检查结果;
(中文拼音混合检错,中文和拼音均拼写正确,此处可解决大部分由混合输入引起的问题)
需要判断拼写检查的返回结果与原始词汇的相似性,通过计算编辑距离判断。
五、测试
拼写检查模块的主要功能是对用户输入的错误关键词进行纠正,并返回纠正后的建议词。
错误测试关键词分以下几种情况:
检错情况 | 正确关键词 | 输入的错误关键词 |
---|---|---|
Case 1 : 纯拼音 | beijing | beijink |
Case 2 : 同音词 |
美国 |
每国 |
Case 3 : 纯中文 | 北京 | 北精、北进 |
Case 4 : 中文拼音混合(拼写正确) | 北京 | 北jing、bei京 |
Case 5 : 中文拼音混合(拼写错误) | 北京 | 北jink |