zoukankan      html  css  js  c++  java
  • Go语言 中文分词技术使用技巧(一)

    分词技术就是搜索引擎针对用户提交查询的关键词串进行的查询处理后根据用户的关键词串用各种匹配方法进行分词的一种技术。

    中文分词(Chinese Word Segmentation)指的是将一个汉字序列(句子)切分成一个一个的单独的词,分词就是将连续的字序列按照一定的规则重新组合成词序列的过程。

    现在分词方法大致有三种:基于字符串配置的分词方法、基于理解的分词方法和基于统计的分词方法。

    今天为大家分享一个国内使用人数最多的中文分词工具GoJieba,源代码地址:GoJieba ,官方文档:GoJieba官方文档

    官方介绍

    • 支持多种分词方式,包括: 最大概率模式, HMM新词发现模式, 搜索引擎模式, 全模式
    • 核心算法底层由C++实现,性能高效。
    • 无缝集成到 Bleve 到进行搜索引擎的中文分词功能。
    • 字典路径可配置,NewJieba(...string), NewExtractor(...string) 可变形参,当参数为空时使用默认词典(推荐方式)

    模式扩展

    • 精确模式:将句子精确切开,适合文本字符分析
    • 全模式:把短语中所有的可以组成词语的部分扫描出来,速度非常快,会有歧义
    • 搜索引擎模式:精确模式基础上,对长词再次切分,提升引擎召回率,适用于搜索引擎分词

    主要算法

    • 前缀词典实现高效的词图扫描,生成句子中汉字所有可能出现成词情况所构成的有向无环图(DAG)
    • 采用动态规划查找最大概率路径,找出基于词频最大切分组合
    • 对于未登录词,采用汉字成词能力的HMM模型,采用Viterbi算法计算
    • 基于Viterbi算法做词性标注
    • 基于TF-IDFTextRank模型抽取关键词

    编码实现

    package main
    
    import (
    	"fmt"
    	"github.com/yanyiwu/gojieba"
    	"strings"
    )
    
    func main() {
    
    	var seg = gojieba.NewJieba()
    	defer seg.Free()
    	var useHmm = true
    	var separator = "|"
    
    	var resWords []string
    	var sentence = "万里长城万里长"
    
    	resWords = seg.CutAll(sentence)
    	fmt.Printf("%s	全模式:%s 
    ", sentence, strings.Join(resWords, separator))
    
    	resWords = seg.Cut(sentence, useHmm)
    	fmt.Printf("%s	精确模式:%s 
    ", sentence, strings.Join(resWords, separator))
    
    	var addWord = "万里长"
    	seg.AddWord(addWord)
    	fmt.Printf("添加新词:%s
    ", addWord)
    
    	resWords = seg.Cut(sentence, useHmm)
    	fmt.Printf("%s	精确模式:%s 
    ", sentence, strings.Join(resWords, separator))
    
    	sentence = "北京鲜花速递"
    	resWords = seg.Cut(sentence, useHmm)
    	fmt.Printf("%s	新词识别:%s 
    ", sentence, strings.Join(resWords, separator))
    
    	sentence = "北京鲜花速递"
    	resWords = seg.CutForSearch(sentence, useHmm)
    	fmt.Println(sentence, "	搜索引擎模式:", strings.Join(resWords, separator))
    
    	sentence = "北京市朝阳公园"
    	resWords = seg.Tag(sentence)
    	fmt.Println(sentence, "	词性标注:", strings.Join(resWords, separator))
    
    	sentence = "鲁迅先生"
    	resWords = seg.CutForSearch(sentence, !useHmm)
    	fmt.Println(sentence, "	搜索引擎模式:", strings.Join(resWords, separator))
    
    	words := seg.Tokenize(sentence, gojieba.SearchMode, !useHmm)
    	fmt.Println(sentence, "	Tokenize Search Mode 搜索引擎模式:", words)
    
    	words = seg.Tokenize(sentence, gojieba.DefaultMode, !useHmm)
    	fmt.Println(sentence, "	Tokenize Default Mode搜索引擎模式:", words)
    
    	word2 := seg.ExtractWithWeight(sentence, 5)
    	fmt.Println(sentence, "	Extract:", word2)
    
    	return
    }
    

    运行结果

    go build -o gojieba 
    
    time ./gojieba 
    
    万里长城万里长  全模式:万里|万里长城|里长|长城|万里|里长 
    万里长城万里长  精确模式:万里长城|万里|长 
    添加新词:万里长
    万里长城万里长  精确模式:万里长城|万里长 
    北京鲜花速递    新词识别:北京|鲜花|速递 
    北京鲜花速递    搜索引擎模式: 北京|鲜花|速递
    北京市朝阳公园  词性标注: 北京市/ns|朝阳/ns|公园/n
    鲁迅先生        搜索引擎模式: 鲁迅|先生
    鲁迅先生        Tokenize Search Mode 搜索引擎模式: [{鲁迅 0 6} {先生 6 12}]
    鲁迅先生        Tokenize Default Mode搜索引擎模式: [{鲁迅 0 6} {先生 6 12}]
    鲁迅先生        Extract: [{鲁迅 8.20023407859} {先生 5.56404756434}]
    
    real    0m1.746s
    user    0m1.622s
    sys     0m0.124s

    性能评测

    语言 源码 耗时
    C++版本 CppJieba 7.5 s
    Golang版本 GoJieba 9.11 s
    Python版本 Jieba 88.7 s

    计算分词过程的耗时,不包括加载词典耗时,CppJieba性能是GoJieba的1.2倍。CppJieba性能详见jieba-performance-comparison,GoJieba由于是C++开发的CppJieba,性能方面仅次于CppJieba,如果追求性能还是可以考虑的。

  • 相关阅读:
    mybatis中 无效的比较: invalid comparison: java.util.Date and java.lang.String
    java中日期的加减,比较,以及与String的互相转换
    Java中文件上传下载 --使用Minio
    Dubbo SPI 源码深入分析
    新建Maven项目 发布服务 注册到zookeeper
    Dubbo SPI 源码分析
    思维方法
    JDK 和 Dubbo SPI 的入门浅析Demo
    Dubbo不用注册中心实现远程调用的简单用法demo
    解决linux系统下tar解压文件报错问题
  • 原文地址:https://www.cnblogs.com/guichenglin/p/12718424.html
Copyright © 2011-2022 走看看