Python 中文分词 jieba(小白进)

文章目录

  • 0、安装
  • 1、分词
    • 1.1、CUT函数简介
    • 1.2、分词模式
    • 1.3、词性标注
    • 1.4、词语出现的位置
  • 2、词典
    • 2.1、默认词典
    • 2.2、添词和删词
    • 2.3、自定义词典加载
    • 2.4、使单词中的字符连接或拆分
  • 3、[jieba分词原理]
  • 4、其它
    • 4.1、并行分词
    • 4.2、[识别【带空格的词】]
    • 4.3、关键词提取
    • 4.4、[文本相似度分析]
    • 4.5、[中文LDA模型]

0、安装

法1:Anaconda Prompt下输入conda install jieba
法2:Terminal下输入pip3 install jieba

1、分词

1.1、CUT函数简介

cut(sentence, cut_all=False, HMM=True)
返回 生成器,遍历生成器即可获得分词的结果
lcut(sentence)
返回 分词列表
import jieba
sentence = '我爱自然语言处理'
# 创建【Tokenizer.cut 生成器】对象
generator = jieba.cut(sentence)
# 遍历生成器,打印分词结果
words = '/'.join(generator)
print(words)
打印结果
我/爱/自然语言/处理
import jieba
print(jieba.lcut('我爱南海中学'))
打印结果
[‘我’, ‘爱’, ‘南海中学’]

1.2、分词模式

精确模式
精确地切开
模式
所有可能的词语都切出,速度快
搜索引擎模式
在精确模式的基础上,对长词再次切分
import jieba
sentence = '订单数据分析'
print('精准模式:', jieba.lcut(sentence))
print('全模式:', jieba.lcut(sentence, cut_all=True))
print('搜索引擎模式:', jieba.lcut_for_search(sentence))
打印结果
精准模式: [‘订单’, ‘数据分析’]
全模式: [‘订单’, ‘订单数’, ‘单数’, ‘数据’, ‘数据分析’, ‘分析’]
搜索引擎模式: [‘订单’, ‘数据’, ‘分析’, ‘数据分析’]

1.3、词性标注

  • jieba.posseg
import jieba.posseg as jp
sentence = '我爱Python数据分析'
posseg = jp.cut(sentence)
for i in posseg:
    print(i.__dict__)
    # print(i.word, i.flag)
打印结果
{‘word’: ‘我’, ‘flag’: ‘r’}
{‘word’: ‘爱’, ‘flag’: ‘v’}
{‘word’: ‘Python’, ‘flag’: ‘eng’}
{‘word’: ‘数据分析’, ‘flag’: ‘l’}

词性标注表

标注 解释 标注 解释 标注 解释
a 形容词 mq 数量词 tg 时语素
ad 副形词 n 名词 u 助词
ag 形语素 ng 例:义 乳 亭 ud 例:得
an 名形词 nr 人名 ug 例:过
b 区别词 nrfg 也是人名 uj 例:的
c 连词 nrt 也是人名 ul 例:了
d 副词 ns 地名 uv 例:地
df 例:不要 nt 机构团体 uz 例:着
dg 副语素 nz 其他专名 v 动词
e 叹词 o 拟声词 vd 副动词
f 方位词 p 介词 vg 动语素
g 语素 q 量词 vi 例:沉溺于 等同于
h 前接成分 r 代词 vn 名动词
i 成语 rg 例:兹 vq 例:去浄 去过 唸过
j 简称略语 rr 人称代词 x 非语素字
k 后接成分 rz 例:这位 y 语气词
l 习用语 s 处所词 z 状态词
m 数词 t 时间词 zg 例:且 丗 丟

1.4、词语出现的位置

  • jieba.tokenize(sentence)
import jieba
sentence = '订单数据分析'
generator = jieba.tokenize(sentence)
for position in generator:
    print(position)
打印结果
(‘订单’, 0, 2)
(‘数据分析’, 2, 6)

2、词典

2.1、默认词典

import jieba, os, pandas as pd
# 词典所在位置
print(jieba.__file__)
jieba_dict = os.path.dirname(jieba.__file__) + r'\dict.txt'
# 读取字典
df = pd.read_table(jieba_dict, sep=' ', header=None)[[0, 2]]
print(df.head())
# 转字典
dt = dict(df.values)
print(dt.get('暨南大学'))

Python 中文分词 jieba(小白进)_第1张图片

2.2、添词和删词

往词典添词
add_word(word, freq=None, tag=None)
往词典删词,等价于 add_word(word, freq=0)
del_word(word)
import jieba
sentence = '天长地久有时尽,此恨绵绵无绝期'
# 添词
jieba.add_word('时尽', 999, 'nz')
print('添加【时尽】:', jieba.lcut(sentence))
# 删词
jieba.del_word('时尽')
print('删除【时尽】:', jieba.lcut(sentence))
打印结果
添加【时尽】: [‘天长地久’, ‘有’, ‘时尽’, ‘,’, ‘此恨绵绵’, ‘无’, ‘绝期’]
删除【时尽】: [‘天长地久’, ‘有时’, ‘尽’, ‘,’, ‘此恨绵绵’, ‘无’, ‘绝期’]

2.3、自定义词典加载

  1. 新建词典,按照格式【单词 词频 词性】添词,以UTF-8编码保存
  2. 使用函数load_userdict加载词典
import os, jieba
# 创建自定义字典
my_dict = 'my_dict.txt'
with open(my_dict, 'w', encoding='utf-8') as f:
    f.write('慕容紫英 9 nr\n云天河 9 nr\n天河剑 9 nz')
# 加载字典进行测试
sentence = '慕容紫英为云天河打造了天河剑'
print('加载前:', jieba.lcut(sentence))
jieba.load_userdict(my_dict)
print('加载后:', jieba.lcut(sentence))
os.remove(my_dict)
打印结果
加载前: [‘慕容’, ‘紫英为’, ‘云’, ‘天河’, ‘打造’, ‘了’, ‘天河’, ‘剑’]
加载后: [‘慕容紫英’, ‘为’, ‘云天河’, ‘打造’, ‘了’, ‘天河剑’]

2.4、使单词中的字符连接或拆分

  • suggest_freq(segment, tune=False)
import jieba
sentence = '上穷碧落下黄泉,两处茫茫皆不见'
print('修正前:', ' | '.join(jieba.cut(sentence)))
jieba.suggest_freq(('落', '下'), True)
print('修正后:', ' | '.join(jieba.cut(sentence)))
打印结果
修正前: 上穷 | 碧 | 落下 | 黄泉 | , | 两处 | 茫茫 | 皆 | 不见
修正后: 上穷 | 碧落 | 下 | 黄泉 | , | 两处 | 茫茫 | 皆 | 不见

3、jieba分词原理

  1. 基于词典,对句子进行词图扫描,生成所有成词情况所构成的有向无环图Directed Acyclic Graph
  2. 根据DAG,反向计算最大概率路径
  3. 根据路径获取最大概率的分词序列
import jieba
sentence = '中心小学放假'
DAG = jieba.get_DAG(sentence)
print(DAG)
route = {}
jieba.calc(sentence, DAG, route)
print(route)
DAG
{0: [0, 1, 3], 1: [1], 2: [2, 3], 3: [3], 4: [4, 5], 5: [5]}
概率路径
{6: (0, 0), 5: ( -9.4, 5), 4: ( -12.6, 5), 3: ( -20.8, 3), 2: ( -22.5, 3), 1: ( -30.8, 1), 0: ( -29.5, 3)}
  • 词图扫描生成DAG,根据DGA反向计算概率
    概率<1、log(概率)<0,取对数防止下溢,乘法运算转为加法
    详情猛戳→jieba分词原理

4、其它

4.1、并行分词

开启并行分词模式,参数为并发数
jieba.enable_parallel(n)
关闭并行分词模式
jieba.disable_parallel()

4.2、识别【带空格的词】

示例:使【Blade Master】这类中间有空格的词被识别

import jieba, re
sentence = 'Blade Master疾风刺杀Archmage'
jieba.add_word('Blade Master')  # 添词
print('修改前:', jieba.lcut(sentence))
jieba.re_han_default = re.compile('(.+)', re.U)  # 修改格式
print('修改后:', jieba.lcut(sentence))
打印结果
修改前: [‘ Blade’, ’ ', ‘ Master’, ‘疾风’, ‘刺杀’, ‘Archmage’]
修改后: [‘ Blade Master’, ‘疾风’, ‘刺杀’, ‘Archmage’]

4.3、关键词提取

  • 基于TF-IDF:jieba.analyse
  • 基于TextRank:jieba.textrank
import jieba.analyse as ja, jieba
text = '柳梦璃施法破解了狐仙的法术'
jieba.add_word('柳梦璃', tag='nr')
keywords1 = ja.extract_tags(text, allowPOS=('n', 'nr', 'ns', 'nt', 'nz'))
print('基于TF-IDF:', keywords1)
keywords2 = ja.textrank(text, allowPOS=('n', 'nr', 'ns', 'nt', 'nz'))
print('基于TextRank:', keywords2)
打印结果
基于TF-IDF: [‘柳梦璃’, ‘狐仙’, ‘法术’]
基于TextRank: [‘狐仙’, ‘柳梦璃’, ‘法术’]

4.4、文本相似度分析

from jieba import lcut
from gensim.similarities import SparseMatrixSimilarity
from gensim.corpora import Dictionary
from gensim.models import TfidfModel
# 文本集和搜索词
texts = ['吃鸡这里所谓的吃鸡并不是真的吃鸡,也不是谐音词刺激的意思',
         '而是出自策略射击游戏《绝地求生:大逃杀》里的台词',
         '我吃鸡翅,你吃鸡腿']
keyword = '玩过吃鸡?今晚一起吃鸡'
# 1、将【文本集】生成【分词列表】
texts = [lcut(text) for text in texts]
# 2、基于文本集建立【词典】,并获得词典特征数
dictionary = Dictionary(texts)
num_features = len(dictionary.token2id)
# 3.1、基于词典,将【分词列表集】转换成【稀疏向量集】,称作【语料库】
corpus = [dictionary.doc2bow(text) for text in texts]
# 3.2、同理,用【词典】把【搜索词】也转换为【稀疏向量】
kw_vector = dictionary.doc2bow(lcut(keyword))
# 4、创建【TF-IDF模型】,传入【语料库】来训练
tfidf = TfidfModel(corpus)
# 5、用训练好的【TF-IDF模型】处理【被检索文本】和【搜索词】
tf_texts = tfidf[corpus]  # 此处将【语料库】用作【被检索文本】
tf_kw = tfidf[kw_vector]
# 6、相似度计算
sparse_matrix = SparseMatrixSimilarity(tf_texts, num_features)
similarities = sparse_matrix.get_similarities(tf_kw)
for e, s in enumerate(similarities, 1):
    print('kw 与 text%d 相似度为:%.2f' % (e, s))
打印结果
kw 与 text1 相似度为:0.65
kw 与 text2 相似度为:0.00
kw 与 text3 相似度为:0.12

4.5、中文LDA模型

from gensim.corpora import Dictionary
from gensim.models import LdaModel
import jieba.posseg as jp, jieba
# 文本集
texts = [
    '美国教练坦言,没输给中国女排,是输给了郎平' * 99,
    '美国无缘四强,听听主教练的评价' * 99,
    '中国女排晋级世锦赛四强,全面解析主教练郎平的执教艺术' * 99,
    '为什么越来越多的人买MPV,而放弃SUV?跑一趟长途就知道了' * 99,
    '跑了长途才知道,SUV和轿车之间的差距' * 99,
    '家用的轿车买什么好' * 99]
# 分词过滤条件
jieba.add_word('四强', 9, 'n')
flags = ('n', 'nr', 'ns', 'nt', 'eng', 'v', 'd')  # 词性
stopwords = ('没', '就', '知道', '是', '才', '听听', '坦言', '全面', '越来越', '评价', '放弃', '人')
# 分词
words_ls = []
for text in texts:
    words = [w.word for w in jp.cut(text) if w.flag in flags and w.word not in stopwords]
    words_ls.append(words)
# 构造词典
dictionary = Dictionary(words_ls)
# 基于词典,使【词】→【稀疏向量】,并将向量放入列表,形成【稀疏向量集】
corpus = [dictionary.doc2bow(words) for words in words_ls]
# lda模型,num_topics设置主题的个数
lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=2)
# 打印所有主题,每个主题显示5个词
for topic in lda.print_topics(num_words=5):
    print(topic)
# 主题推断
print(lda.inference(corpus)[0])
结果
主题0( 体育):‘0.081*“ 郎平” + 0.080*“ 中国女排” + 0.077*“ 输给” + 0.074*“ 主教练”’
主题1( 汽车):‘0.099*“ 长途” + 0.092*“ SUV” + 0.084*“ ” + 0.074*“ 轿车”’

你可能感兴趣的:(自然语言处理)