中文分词
分词,就是将0维的非格式化文本转为格式化、向量化数据
中文分词(Chinese Word Segmentation) 是将一个汉字序列切分成一个个单独的词。
英文文档中,单词之间是以空格作为自然分界符的,而中文词没有一个形式上的分界符,虽然英文也同样存在短语的划分问题,不过在词这一上,中文分词相比英文要复杂困难的多
'0维的非格式化文本转为格式化'
分词
['0维', '的', '非格式化', '文本', '转为', '格式化']
安装jieba中文分词库
pip install jieba or conda install -c conda-forge jieba
import jieba
import jieba.analyse
中文分词基础步骤
- 载入数据
- 分词
- 分词后的数据转回文本
- 保存分词后的文本为文本文件
# 外部载入 with open('example/text.txt', 'r', encoding='GBK') as f: a = f.read() b = jieba.cut(a) # 返回生成器 b = jieba.lcut(a) # 分词后直接生成列表 c = ' '.join(b) # 分好的词转回字符串 with open('temp/text_cut.txt', 'w', encoding="utf-8")as f: # 提前建好temp文件夹 f.write(c)
增加分词的准确率
- 增加或删除系统词词典
- 一个词错误分为多个词(例如:你好,分为:'你', '好'
- 解决方法:
- 添加自定义词典:jieba.load_userdict()
- 动态增加系统词:jieba.add_word()
- 解决方法:
- 两个词错误分为一个词:(例如:'你,和,我',分为:‘你和我')
- 解决方法:
- 删除系统词:jieba.del_word()
- 调整词频:jieba.suggest_freq(('a','b'), tune=True)
- 解决方法:
- 一个词错误分为多个词(例如:你好,分为:'你', '好'
- 去停用词
- 将不想出现在分词结果内的词删除
注意:修改自定义词典或停用词文本文件时,不要使用记事本修改(保存时会存为UTF-8带BOM格式,导致程序载入出问题)
添加自定义词典
- 当句子中的某个词没有被识别分出时,可以指定自己自定义的词典,以便包含 jieba 词库里没有的词
- 词典文件的内容可以根据项目不断增加。查看初步分词,将分词不正确的词加入自定义词典然后重新再分,直到正确率达标
- 虽然 jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率
词典格式:
- 词中间不能有标点符号
- 一个词占一行;
- 每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。
- file_name 若为路径或二进制方式打开的文件,则文件必须为 UTF-8 编码
词频省略时使用自动计算也能保证分出该词的词频
jieba.load_userdict('data/custom.txt') # 输入路径直接应用自定义词典 jieba.lcut(a)
动态增加或删除词典的词
a2 = '我们中出了一个叛徒' jieba.lcut(a2) #['我们', '中出', '了', '一个', '叛徒'] # 两个词错误的分为1个词,删除词实现正确分词 jieba.del_word('中出') # 删除jieba自带的词(不同于去停用词,不是删除词,而是重新分词) jieba.add_word('中出') # 增加jieba的词,和自定义词典相比它可以动态增加词 jieba.lcut(a2) # 调节词的词频,使其能(或不能)被分出 # tune=True:执行词频调整,默认False不执行 jieba.suggest_freq(('中','出'), tune=True) jieba.lcut(a2) #['我们', '中', '出', '了', '一个', '叛徒'] # 调整的词以字符串形式输入 jieba.suggest_freq('一个叛徒', tune=True) jieba.lcut(a2) #['我们', '中', '出', '了', '一个叛徒']
去停用词
- 与上面相反,当一个字符串不是词,jieba误将其分为词,或者我们不想将某些不重要的词分出来(想删掉某些分出的词)可以自定义停用词词典
- 停用词就是要从分词结果删掉的垃圾无用词
- 词典中的词不会出现在分词结果中
- 停用词词典的内容可以根据项目不断增加
附一个通用停用词词典,涵盖大部分无用字词,可以根据项目需求不断添加累计补充
a = '哎,鹅,听说你超级喜欢小游戏的!你是吗?' b = jieba.lcut(a) 去停用词功能jieba不带,需自行实现。下面是实现 1.先载入停用词 2.1去停用词,第一步,求差集 2.2去停用词第二步:去掉1个字以下的词 # # 1.若停用词表的特殊词载入时被自动转义,可以判断并恢复 stopword = [] with open('temp/stopword.txt', 'r', encoding='UTF-8') as f: for line in f.readlines(): l = line.strip() if l == '\n': l = ' ' if l == '\u3000': l = 'u3000' stopword.append(l) #2.1去停用词,第一步,求差集 x = np.array(b) # 将分好的词列表转为数组 y = np.array(stopword) # 将停用词转为数组 # 目的:将分词数组内停用词数组有的值删除 np.in1d(x, y) # np.inid(x, y) x的元素是否包含于y z = x[~np.in1d(x, y)] # 非运算,在x内且不在y内的词 # 2.2第二步:去掉1个字以下的词 # k = [] # for i in z: # # print(len(i)) # if len(i) > 1: # k.append(i) # k k = [i for i in z if len(i) > 1] k