由于工作需要用到对中文进行分词,但碍于中文不同英文,英文只有26个字母组成,中文汉字常见的就有几千个,各种不同形式的组合,而且还有些生僻字,所以中文分词这块一起比较复杂,需要大量的语料库做训练.中科院的ICTCLAS,哈工大的ltp,东北大学的NIU Parser是学术界著名的中文分词器,但由于不开源,想要更好的二次开始很困难,jieba分词是python写成的一个比较有名的中文分词开源库,比较强大,其github地址**在这里**
Jieba
该项目的作者其实挺有意思,对结巴这个词反其道用之,想想还确实比较符合中文分词,jieba分词支持3种模式及可以自定义词典,而且还支持繁体中文的分词,还是比较强大的
采用算法
- 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)
- 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
- 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法
- TopN的关键字提取采用的则是基于 TF-IDF 算法
3种分词模式
- 精确模式: 试图将句子最精确地切开,适合文本分析
- 全模式: 把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义
- 搜索引擎模式: 在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
这里使用的是第一种模式,把文本分解成日常生活中常用的词是一种比较常用的适用场景,而全模式则会把文本所有的词都分开,速度快但存在歧义.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all=True) print("Full Mode: " + "/ ".join(seg_list))
seg_list = jieba.cut("我来到北京清华大学", cut_all=False) print("Default Mode: " + "/ ".join(seg_list))
seg_list = jieba.cut("他来到了网易杭研大厦") print(", ".join(seg_list))
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") print(", ".join(seg_list))
|
自定义词典
在python中import jieba使用时,会引用包里自带的字典,但是允许我们添加自定义的词典,以便包含 jieba 词库里没有的词,jieba也提倡自己添加词典,以便提高具体场景下分词正确率,自带的词典文件在jieba包的dict.txt
词典的格式也很简单: 每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒,在词频省略时使用自动计算的能保证分出该词的词频
常用函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| jieba.load_userdict(file_name)
tags = jieba.analyse.extract_tags(content, topK=topK, withWeight=withWeight)
tags = jieba.analyse.extract_tags(content, topK=topK)
fenci = jieba.lcut(rline,cut_all=True,HMM=False)
fenci = jieba.lcut(rline,cut_all=True,HMM=False)
seg_list = jieba.cut_for_search(rline,HMM=False)
jieba.add_word(word, freq=None, tag=None) jieba.del_word(word)
word = jieba.posseg.cut(rline)
|
商品名称替换为TopK
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| with open(fileone, "r", encoding="GBK") as f: for line in f: line_total = line_total+1 if not line: break rline = re.split("[]", line, 1) rline[0] = re.sub(pattern,"",rline[0]) if (rline[0]): fenci = jieba.lcut(rline[0]) for x in range(len(tags)): if tags[x] in fenci: rline[0] = tags[x] break else: continue line_fmt = rline[0] + "[]" + rline[1] f1.write(line_fmt) else: blk_total = blk_total+1 return fileone,line_total,blk_total
|
参考文章: