前提:没有最好的分词器,只有最适合于某个领域的分词器。
讨论搜索一般会考虑 "输入某个关键字会搜索到哪些商品?" 我们逆向思维 从"商品应该被哪些词搜索到?" 入手,研究商品应该被分成什么词? 然后分析各种分词器,最后选择一款适合我们的分词器。
1,商品的理想分词结果
1.1,问题分析
商品应该被哪些词搜索到? 我们知道商品名称在建索引时(index) 最终会分词成一个个的词源 (token) ,用户输入的关键字在查询时 (query) 也会分解成一个个的token,最终在这两者之间进行匹配得到搜索结果。那么这个问题等同于 "商品应该分成哪些词"?
举个例子:
商品名称 | ADIDAS 阿迪达斯 女式篮球鞋G20917 亮白 |
期望被什么词搜索到 | adidas、阿迪达斯、女、女式、篮球鞋、鞋、篮球、球鞋 |
期望分词结果 | adidas、阿迪达斯、女、女式、鞋、篮球、篮球鞋、球鞋、g20917、亮、白 |
期望被搜索到并不代表优先展示,
mmseg4j :是基于正向最大匹配原则
最大匹配原则:按从左至右正向最大匹配和从右到左反向最大匹配,当两种分词结果不一致时,按最少切分原则,取切分词数最少的一种,如果两种分词结果切分的词数一样,取反向最大匹配作为分词的结果。
比如 : 篮球鞋 (如果词库中没有 篮球鞋)
商品名称 | 篮球鞋 |
引入自定义词 | 鞋、篮球、球鞋 |
正向最大匹配原则 | 篮球、鞋 |
反向最大匹配原则 | 球鞋、蓝 |
最大匹配原则(最终结果) | 蓝、球鞋 |
粗粒度、细粒度
比如:篮球鞋
粗粒度:篮球鞋
细粒度:蓝、球鞋 | 篮球、鞋 | 蓝、球、鞋
粒度越粗,分词结果越漂亮,但是搜索 "鞋" 搜不出来 “篮球鞋” 是必然的。
粒度越细,搜索 “鞋” 可以搜索出 “篮球鞋”,分词结果很 “不漂亮”。带来的问题是,搜索精度不高,即搜 “篮” 都可能搜出 “篮球鞋”。
2,各种主流分词器的比较
2.1 mmseg4j 分词主要有3模式,simple、complex以及max-word 三种分词方法。
simple、complex 都是基于"正向最大匹配原则" 分词
max-word 实际上就是在complex 基础上实现最多分词
正向最大匹配原则是:按从左到右最大匹配
2.2 中科院分词
2.3 IKAnalyzer 分词
ikanalyzer 采用的算法是:"正向迭代最细粒度切分算法" 多字处理器分析模式。
解释:从左向右按照最细粒度匹配,在扫描文章的过程中,使用迭代匹配,一次扫描即可搜索出所有交叉词元
但是由此带来的问题是,分词过细,搜索精度不够?
ikanalyzer 的解决办法 是 在query 时,进行最大匹配,弥补查询精度问题
实例:
商品名称 | ADIDAS 阿迪达斯 女式篮球鞋 G20917 亮白 | 搜索“鞋” |
引入词库 | [ adidas,阿迪达斯,女,女式,篮球,球鞋,篮球鞋,鞋] | ----- |
Mmseg4j complex模式 | adidas | 阿迪达斯 | 女式 | 篮球鞋 | g20917 | 亮 | 白 | 无结果 |
Mmseg4j max-word模式 | adidas | 阿 | 迪 | 达 | 斯 | 女式 | 篮球 | 球鞋 | g20917 | 亮 | 白 | 无结果 |
中科院分词 | adidas | 阿迪达斯 | 女式 | 篮球鞋 | g20917 | 亮 | 白 | 无结果 |
IKAnalyzer分词 | adidas | 阿迪达斯 | 女式 | 女 | 篮球鞋 | 篮球 | 球鞋 | 鞋 | g20917 | g | 20917 | 亮白 | 白 | 有结果 |
结论:电商搜索的分词算法是:最大匹配原则 算法 加 ikanalyzer 的 正向迭代最细粒度切分算法相结合。
索引分词采用最细粒度 搜索分词采用最大匹配
最后向大家推荐《Java面试进阶指南》 https://xiaozhuanlan.com/javainterview?rel=8186804788