jieba 库
jieba 库的原理分析
jieba库可用于将中文的一段语句分解为单词,通常用于解析中文语句的含义。例如外国人需要学习中文而中文语句是一直连续的文字组合。例如"我们在学习Python办公自动化"这句话,外国人在理解这句话的含义时,首先需要将这句话正确地分解为一个个单词,即"我们""在""学习""Python""办公""自动化",如单词分解错误就无法理解这句话的含义,例如"我""们在"。
将一段文字分解为一个个单词的原理是库中已经建立了"词典","词典"收集了汉语中的所有词语,当需要对一段文字进行分词时,会将文字的所有内容和词典进行匹配,当匹配成功时即得到一个单词。但还是会在有歧义的问题,例如"路上行人行路上",代码可能会将其分词为"路上""行""人行路""上",但实际的分词应该为"路上""行人""行""路上",而jieba库会使用概率最大化来决定选择哪个词。因此在建立"词典"时还需对每个词设置使用概率,概率最大的词表示使用率最高。由于一段文字中每个词的概率不同,因此jieba库中还设置了最优化算法,即选择一段文字中概率最大的词。
综上所述,jieba库分词不能保证所有的分词都是正确的,读者在后面的学习过程中可能会发现分词错误的情况。关于jieba库的安装已经在8.5.3小节进行了演示,读者可按照如图8-4所示的命令进行安装。
iieba 库的解析
在8.6节介绍的Pyinstaller库是使用命令的形式来运行代码的,但是并没有使用代码,在iieba库中将使用代码的形式实现分词功能。
接下来对jieba库做一个简单的分析。使用pip工具下载、安装完jieba库后,打开iieba库安装目录(可通过命令pip show jieba返回的Location获取到安装目录地址)后
其中最为关键的是__init_-.py文件,包含用于创建分词对象的类Tokenizer,类Tokenizer包含大量与分词相关的方法。analyse文件夹中是用于设计算法以实现分析词语的相关代码。finalseg文件夹中是用于词完成后处理的相关代码。lac_small文件夹中是用于创建词法分析模型和模型数据读取器的相关代码。main_-·py文件可以实现使用命令的形式运行jieba库中函数的功能(与Pyinstaller库的使用方法相同)dict.txt文件是iieba库中的词典,用于保存所有的词语。
init.py文件中的类Tokenizer包含处理分词的方法。本书第6保细介绍了__init__.py文件的组成和原理,读者需要进入此文件中观察代码文件的组成,获取关键函数和类。
类Tokenizer的简洁定义:
Elass Tokenizer(object):#位于库jieba\ init .py中definit__(self,dictionary=DEFAULT DICT):...#初始化类def gen pfdict(f):...
def initialize(self,dictionary=None):...#检查初始化
def check initialized(self):...
def calc(self,sentence,DAG,route):...#计算分词def get DAG(self,sentence):...def cut(self,sentence,cut_all=False,HMM=True, use paddle=False):..#精确模式分词,返回一个分词对象
def cut_for_search(self,sentence,H=True):...#搜索引擎模式分词,返回一个分词对象def lcut(self,*args,**kwargs):...#精确模式分词,返回一个列表
def lcut_for_search(self,*args,**kwargs):...#搜索引擎模式分词,返回一个列表
def get dict_file(self):...#获取词典def load userdict(self,):...#加载个性化词典,提高分词正确率
def add word(self,word,freq=None,tag=None):...#向词典中添加单词def del word(self,word):...#删除一个单词
def suggest freq(self,segment,tune=False):...#调节单词的频率def tokenize(self,unicode sentence, mode="default",HMM=True):#对一个句子进行标记并生成元组
def set dictionary(self,dictionary path):...#设置分词依赖的词典
这里仅列举类名和方法名,以便于读者快速掌握类Tokenizer的使用方法,而对于方法的代码实现,读者并不需要过于关心,在此后的所有章节中均按照该形式列举类的定义。
jieba 库的使用
jieba库中提供了3种分词模式,即精确模式、全模式和搜索引擎模式。
精确模式
精确模式指对句子进行精确的切分,是文本分析中较为常用的一种模式。其使用形式如下:
python
cut(sentence,cut all=False,HMM=True,use_paddle=False)
参数sentence:需要分词的中文句子,值的数据类型为字符串类型。
参数cut_all:参数值的数据类型为布尔值类型,值为False表示使用精确模式,值为True表示使用全模式。
参数HMM:是否使用隐马尔可夫模型(一种优化模型算法)。
示例代码:
python
import jieba
s = '我们在学习Python办公自动化'
jb_a = jieba.Tokenizer() #类Tokenizer所包含的处理分词的方法
result = jb_a.cut(sentence = s) #精确模式
print(result,list(result))
第3行代码使用iieba库中的类Tokenizer初始化一个分词对象jb_a。第4行代码使用了分词对象中的cut()方法,并对第2行代码中的字符串内容进行了精确模式分词。第5行代码输出结果,由于cut()方法分词后会返回一种Python内部数据,因此可以使用list()函数将该数据
转换为列表类型数据。
输出结果:
python
<generator object Tokenizer.cut at 0x0000022B1C26EF80> ['我们', '在', '学习', 'Python', '办公自动化']
执行代码后的输出结果如图8-21所示,标注框中的红色字为分词过程所产生的信息,用于告诉当前用N行分词的状态、消耗的时间(寻找最优化分词的过程需要消耗大量的时间,因此通过消耗时间可以对比不圆最优化算法的性能)等。蓝色字为分词后的内容,转换为列表数据后表明jieba库将'我们在学习Python办公动化'分词为了'我们'在'学习''Python'办公自动化。
全模式
全模式指把句子中所有可以成词的词语都扫描出来,这种分词模式虽然速度快,但不能解决歧义问题。将cut()方法中的参数cut_all的值设置为True即可使用全模式。
示例代码:
python
import jieba
s = '我们在学习Python办公自动化'
jb_a = jieba.Tokenizer()
result = jb_a.cut(sentence = s,cut_all=True)#全模式
print(list(result))
代码执行结果:
python
['我们', '在', '学习', 'Python', '办公', '办公自动化', '自动', '自动化']
结果中每个可以作为一个单词的文字都将展示出来。
搜索引擎模式
搜索引擎模式指在精确模式基础上,对长词再次切分,适用于搜索引警分词。其使用形式如下:
python
cut for search(sentence,HMM=True)
参数sentence:需要分词的中文句子,值的数据类型为字符串类型。
参数HMM:是否使用隐马尔可夫模型。
示例代码:
python
import jieba
s = '我们在学习Python办公自动化'
jb_a = jieba.Tokenizer()
result = jb_a.cut_for_search(sentence = s)#搜索引擎模式
print(list(result))
第4行代码使用cut_for_search()对第2行代码中的文字进行搜索引擎模式分词,分词后的结果如下,表明在精确模式的基础上再次对"办公自动化"进行分词。
python
['我们', '在', '学习', 'Python', '办公', '自动', '自动化', '办公自动化']
添加新词
除了U上3种分词模式,由于社会还会不断地创造出新的间语,因此为子满是当前社会对分司的需求,还可以使用add-word()方法向词典中添加新词(添加的词语不是永久的:仪当前代码中有效)。其使用形式如下:
python
add word(word, freq=None, tag=None)
参数word:需要添加到词典中的词语。示例代码:
python
import jieba
s = '我们在学习Python办公自动化'
jb_a = jieba.Tokenizer()
jb_a.add_word('Python办公自动化')#添加新词
result = jb_a.cut(sentence = s)
print(list(result))
第4行代码使用add_word()方法将单词"Python办公自动化"添加到词典中。
第5行代码使用cut()方法进行精确模式分词。
执行代码后的输出结果如下,可以看出"Python办公自动化"并没有分开,而是作为一个词。
python
['我们', '在', '学习', 'Python办公自动化']
在__init--.py文件中对类Tokenizer的使用进行简化,并重新对该类中的方法进行赋值,代码如下:
python
dt = Tokenizer()get FREQ=lambda k,d=None:dt.FREQ.get(k,d)add word = dt.add wordcut =dt.cut
lcut = dt.lcut
cut for search=dt.cut for search
lcut for search =dt.lcut for search
del word = dt.del wordget dict file= dt.get dict file
也可以直接使用iieba.cut()、jieba.cut_for_search()和jieba.add_word()实现以上介绍的4个功能(8.7.4小节的代码中有此种用法)。
小项目案例:实现判断评论为好评或差评
项目描述
为了自动识别例如抖音的某个视频、微博的某个文案、淘宝的某个商品的评论为好评或差评,需要设计一个可以自动判断用户评论好坏的代码程序。
项目任务
任务1:使用jieba库将用户的评论分词为一个个单词,并建立一套好评、差评词库,例如在以下代码中,列表good中为好评词语,列表bad中为差评词语。
任务2:将用户评论分词后的单词分别与列表good、bad进行匹配,并统计好评词语和差评词语的个数
项目实现代码:
python
import jieba
good = ['好评','好看']
bad = ['差评','垃圾']
s_1 = '衣服好看,显得皮肤白'
s_2 = '尺寸不差评分必须高'
s_3 = '差评买过最垃圾的东西'
def get_value(s):
good_value = bad_value = 0
result = list(jieba.cut(sentence=s))
print(result)
for r in result:
if r in good:
good_value += 1
if r in bad:
bad_value += 1
print('好评词语个数:',good_value,'差评词语个数:',bad_value)
if good_value > bad_value:
print('此条评论为好评')
elif good_value == bad_value:
print('此条评论暂无法判断')
else:
print('此条评论为差评')
get_value(s_1)
get_value(s_2)
get_value(s_3)
第2、3行代码中的good和bad分别保存好评词语和差评词语。在实际开发中的词语可能会远远多于以上代码中的词语,读者在实际开发中可以自行增加。
第4~6行代码中为3条待分析的评论。
第7~22行代码创建了一个用于分析评论的函数get_value()。其中第8行代码中的good_value和 badvalue用于统计好评词语和差评词语的个数。第9行代码使用iieba.cut()方法将评论解析为单词。第11~16代码使用for循环依次判断解析后的词语中是否有好评词语或差评词语,如果有好评词语则good_value值加I如果有差评词语则bad_value值加1。第17~22行代码用于判断good_value和bad_value的大小,如果好评词语的个数大于差评词语的个数,则表明评论为好评;如果个数相同则暂时无法判断评论是好评还是差评;如果好评词语的个数小于差评词语的个数,则表明评论为差评。
执行代码后的输出结果如图8-22所示,解析后的第1条评论为好评、第2条评论暂时无法判断、第3条评论为差评,解析后的结果基本是正确。本小节的代码仅用于演示效果,对于实际中广泛的、真实的评论来说,需要完全分辨出好评或差评是一件较为困难的事情目前的常用方法是结合人工智能深度学习算法并解析每条评论的语义,但仍然只能是尽可能提高识别的正确率。