1. 程式人生 > >Python 中文分詞 jieba(小白進)

Python 中文分詞 jieba(小白進)

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('暨南大學'))

這裡寫圖片描述

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)))
列印結果
修正前: 上窮 | 碧 | 落下 | 黃泉 | , | 兩處 | 茫茫 | 皆 | 不見
修正後: 上窮 | 碧落 | 下 | 黃泉 | , | 兩處 | 茫茫 | 皆 | 不見
  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()

示例:使【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: [‘狐仙’, ‘柳夢璃’, ‘法術’]
from gensim import corpora, models, similarities
import jieba
# 文字集和搜尋詞
text1 = '吃雞這裡所謂的吃雞並不是真的吃雞,也不是我們常用的諧音詞刺激的意思'
text2 = '而是出自策略射擊遊戲《絕地求生:大逃殺》裡的臺詞'
text3 = '我吃雞翅,你吃雞腿'
texts = [text1, text2, text3]
keyword = '玩過吃雞嗎?今晚一起來吃雞'
# 1、將【文字集】生成【分詞列表】
texts = [jieba.lcut(text) for text in texts]
# 2、基於文字集建立【詞典】,並提取詞典特徵數
dictionary = corpora.Dictionary(texts)
feature_cnt = len(dictionary.token2id.keys())
# 3、基於詞典,將【分詞列表集】轉換成【語料庫】(存放稀疏向量的列表)
corpus = [dictionary.doc2bow(text) for text in texts]
# 4、使用【TF-IDF模型】處理語料庫
tfidf = models.TfidfModel(corpus)
# 5、同理,用【詞典】把【搜尋詞】也轉換為【稀疏向量】
kw_vector = dictionary.doc2bow(jieba.lcut(keyword))
# 6、對【稀疏向量集】建立【索引】
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=feature_cnt)
# 7、相似度計算
sim = index[tfidf[kw_vector]]
for i in range(len(sim)):
    print('keyword 與 text%d 相似度為:%.2f' % (i+1, sim[i]))
列印結果
keyword 與 text1 相似度為:0.62
keyword 與 text2 相似度為:0.00
keyword 與 text3 相似度為:0.12
from gensim import corpora, models
import jieba.posseg as jp, jieba
# 文字集
texts = [
    '美國教練坦言,沒輸給中國女排,是輸給了郎平',
    '美國無緣四強,聽聽主教練的評價',
    '中國女排晉級世錦賽四強,全面解析主教練郎平的執教藝術',
    '為什麼越來越多的人買MPV,而放棄SUV?跑一趟長途就知道了',
    '跑了長途才知道,SUV和轎車之間的差距',
    '家用的轎車買什麼好']
# 分詞過濾條件
jieba.add_word('四強', 9, 'n')
flags = ('n', 'nr', 'ns', 'nt', 'eng', 'v', 'd')  # 詞性
stopwords = ('沒', '就', '知道', '是', '才', '聽聽', '坦言', '全面', '越來越', '評價', '放棄', '人')  # 停詞
# 分詞
words_ls = []
for text in texts:
    words = [word.word for word in jp.cut(text) if word.flag in flags and word.word not in stopwords]
    words_ls.append(words)
# 構造詞典
dictionary = corpora.Dictionary(words_ls)
# 基於詞典,使【詞】→【稀疏向量】,並將向量放入列表,形成【稀疏向量集】
corpus = [dictionary.doc2bow(words) for words in words_ls]
# lda模型,num_topics設定主題的個數
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=2)
# 列印所有主題,每個主題顯示4個詞
for topic in lda.print_topics(num_words=4):
    print(topic)
# 主題推斷
print(lda.inference(corpus))
結果
主題0(體育):‘0.081*“郎平” + 0.080*“中國女排” + 0.077*“輸給” + 0.074*“主教練”’
主題1(汽車):‘0.099*“長途” + 0.092*“SUV” + 0.084*“” + 0.074*“轎車”’