[Python] 基於 jieba 的中文分詞總結
阿新 • • 發佈:2021-02-21
[TOC]
## 模組安裝
```
pip install jieba
```
jieba分詞器支援4種分詞模式:
1. 精確模式該模式會試圖將句子最精確地切分開,適合在文字分析時使用。
2. 全模式該模式會將句子中所有可以成詞的詞語都掃描出來,速度也非常快,缺點是不能解決歧義問題,有歧義的詞語也會被掃描出來。
3. 搜尋引擎模式該模式會在精確模式的基礎上對長詞語再進行切分,將更短的詞切分出來。在搜尋引擎中,要求輸入詞語的一部分也能檢索到整個詞語相關的文件,所以該模式適用於搜尋引擎分詞。
4. Paddle模式該模式利用PaddlePaddle深度學習框架,訓練序列標註網路模型實現分詞,同時支援詞性標註。
該模式在4.0及以上版本的jieba分詞器中才能使用。使用該模式需要安裝PaddlePaddle模組,安裝命令為“`pip install paddlepaddle`”。
## 開原始碼
```
https://github.com/fxsjy/jieba
```
## 基本用法
```Python
>>> import jieba
>>> str1 = '我來到了成都的西南交通大學犀浦校區,發現這兒真不錯'
>>> seg_list = jieba.cut(str1, cut_all=True)
>>> print('全模式分詞結果:' + '/'.join(seg_list))
全模式分詞結果:我/來到/了/成都/的/西南/交通/大學/犀/浦/校區/,/發現/這兒/真不/真不錯/不錯
>>> seg_list = jieba.cut(str1, cut_all=False)
>>> print('精確模式分詞結果:' + '/'.join(seg_list))
精確模式分詞結果:我/來到/了/成都/的/西南/交通/大學/犀浦/校區/,/發現/這兒/真不錯
```
## 啟用Paddle
> 這裡有個坑,首先不能用最新的python版本,我從3.9.1降到了3.8.7才可以。
> 另外安裝後使用一直報錯,最終發現需要 `Microsoft Visible C++ 2017 Redistributable 及其以上版本支援`。
```Python
import jieba
import paddle
str1 = '我來到了成都的西南交通大學犀浦校區,發現這兒真不錯'
paddle.enable_static()
jieba.enable_paddle()
seg_list = jieba.cut(str1, use_paddle=True)
print('Paddle模式分詞結果:' + '/'.join(seg_list))
輸出:
Paddle模式分詞結果:我/來到/了/成都/的/西南交通大學犀浦校區,/發現/這兒/真不錯
```
## 詞性標註
```Python
import jieba
import paddle
# 詞性標註分詞器
import jieba.posseg as pseg
str1 = '我來到了成都的西南交通大學犀浦校區,發現這兒真不錯'
paddle.enable_static()
jieba.enable_paddle()
words = pseg.cut(str1,use_paddle=True)
for seg, flag in words:
print('%s %s' % (seg, flag))
輸出:
我 r
來到 v
了 u
成都 LOC
的 u
西南交通大學犀浦校區, ORG
發現 v
這兒 r
真不錯 a
```
> 注意:pseg.cut 和 jieba.cut 返回的物件是不一樣的!
paddle模式詞性標註對應表如下:
paddle模式詞性和專名類別標籤集合如下表,其中詞性標籤 24 個(小寫字母),專名類別標籤 4 個(大寫字母)。
| 標籤 | 含義 | 標籤 | 含義 | 標籤 | 含義 | 標籤 | 含義 |
| ---- | -------- | ---- | -------- | ---- | -------- | ---- | -------- |
| n | 普通名詞 | f | 方位名詞 | s | 處所名詞 | t | 時間 |
| nr | 人名 | ns | 地名 | nt | 機構名 | nw | 作品名 |
| nz | 其他專名 | v | 普通動詞 | vd | 動副詞 | vn | 名動詞 |
| a | 形容詞 | ad | 副形詞 | an | 名形詞 | d | 副詞 |
| m | 數量詞 | q | 量詞 | r | 代詞 | p | 介詞 |
| c | 連詞 | u | 助詞 | xc | 其他虛詞 | w | 標點符號 |
| PER | 人名 | LOC | 地名 | ORG | 機構名 | TIME | 時間 |
## 調整詞典
+ 使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程式中動態修改詞典。
+ 使用 suggest_freq(segment, tune=True) 可調節單個詞語的詞頻,使其能(或不能)被分出來。
## 智慧識別新詞
將jieba.cut()函式的引數HMM設定為True,即可使用基於漢字成詞能力的HMM模型識別新詞,即詞典中不存在的詞。
測試一下,效果一般
## 搜尋引擎模式分詞
```python
import jieba
str1 = '我來到了成都的西南交通大學犀浦校區,發現這兒真不錯'
seg_list = jieba.cut_for_search(str1)
print('搜尋引擎模式分詞結果:' + '/'.join(seg_list))
輸出:
搜尋引擎模式分詞結果:我/來到/了/成都/的/西南/交通/大學/犀浦/校區/,/發現/這兒/真不/不錯/真不錯
```
## 使用自定義詞典
使用者詞典.txt 如下
![](https://img2020.cnblogs.com/blog/2200001/202102/2200001-20210221182839297-874771894.png)
```
import jieba
str = '心靈感應般地驀然回首,才能撞見那一低頭的溫柔;也最是那一低頭的溫柔,似一朵水蓮花不勝涼風的嬌羞;也最是那一抹嬌羞,才能讓兩人攜手共白首。';
seg_list = jieba.cut(str)
print('未載入自定義詞典時的精確模式分詞結果:\n', '/'.join(seg_list))
jieba.load_userdict('使用者詞典.txt')
seg_list = jieba.cut(str)
print('載入自定義詞典時的精確模式分詞結果:\n', '/'.join(seg_list))
jieba.add_word('最是')
seg_list = jieba.cut(str)
print('新增自定義詞時的精確模式分詞結果:\n', '/'.join(seg_list))
jieba.del_word('一低頭')
seg_list = jieba.cut(str)
print('刪除自定義詞時的精確模式分詞結果:\n', '/'.join(seg_list))
```
## 關鍵詞提取
關鍵詞是最能反映文字的主題和意義的詞語。關鍵詞提取就是從指定文字中提取出與該文字的主旨最相關的詞,它可以應用於文件的檢索、分類和摘要自動編寫等。
從文字中提取關鍵詞的方法主要有兩種:
+ 第一種是有監督的學習演算法;
這種方法將關鍵詞的提取視為一個二分類問題,先提取出可能是關鍵詞的候選詞,再對候選詞進行判定,判定結果只有“是關鍵詞”和“不是關鍵詞”兩種,基於這一原理設計一個關鍵詞歸類器的演算法模型,不斷地用文字訓練該模型,使模型更加成熟,直到模型能準確地對新文字提取關鍵詞;
+ 第二種是無監督的學習演算法;
這種方法是對候選詞進行打分,取出打分最高的候選詞作為關鍵詞,常見的打分演算法有TF-IDF和TextRank。jieba模組提供了使用TF-IDF和TextRank演算法提取關鍵詞的函式。
```python
#基於TF-IDF演算法的關鍵詞提取
from jieba import analyse
text = '記者日前從中國科學院南京地質古生物研究所獲悉,該所早期生命研究團隊與美國學者合作,在中國湖北三峽地區的石板灘生物群中,發現了4種形似樹葉的遠古生物。這些“樹葉”實際上是形態奇特的早期動物,它們生活在遠古海洋底部。相關研究成果已發表在古生物學國際專業期刊《古生物學雜誌》上。'
keywords = analyse.extract_tags(text, topK = 10, withWeight = True, allowPOS = ('n', 'v'))
print(keywords)
#基於TextRank演算法的關鍵詞提取
from jieba import analyse
text = '記者日前從中國科學院南京地質古生物研究所獲悉,該所早期生命研究團隊與美國學者合作,在中國湖北三峽地區的石板灘生物群中,發現了4種形似樹葉的遠古生物。這些“樹葉”實際上是形態奇特的早期動物,它們生活在遠古海洋底部。相關研究成果已發表在古生物學國際專業期刊《古生物學雜誌》上。'
keywords = analyse.textrank(text, topK = 10, withWeight = True, allowPOS = ('n', 'v'))
print(keywords)
```
說明:
+ extract_tags()
+ 引數sentence為待提取關鍵詞的文字;
+ 引數topK用於指定需返回的關鍵詞個數,預設值為20;
+ 引數withWeight用於指定是否同時返回權重,預設值為False,表示不返回權重,TF或IDF權重越高,返回的優先順序越高;
+ 引數allowPOS用於指定返回的關鍵詞的詞性,以對返回的關鍵詞進行篩選,預設值為空,表示不進行篩選。
+ textrank()
+ 和extract_tags()函式的引數基本一致,只有引數allowPOS的預設值不同。
+ 由於演算法不同,結果可能會有差異。
## 停用詞過濾
停用詞是指在每個文件中都會大量出現,但是對於NLP沒有太大作用的詞,如“你”“我”“的”“在”及標點符號等。在分詞完畢後將停用詞過濾掉,有助於提高NLP的效率。
···python
import jieba
with open('stopwords.txt', 'r+', encoding = 'utf-8')as fp:
stopwords = fp.read().split('\n')
word_list = []
text = '商務部4月23日釋出的資料顯示,一季度,全國農產品網路零售額達936.8億元,增長31.0%;電商直播超過400萬場。電商給農民帶來了新的機遇。'
seg_list = jieba.cut(text)
for seg in seg_list:
if seg not in stopwords:
word_list.append(seg)
print('啟用停用詞過濾時的分詞結果:\n', '/'.join(word_list))
```
## 詞頻統計
詞頻是NLP中一個很重要的概念,是分詞和關鍵詞提取的依據。在構造分詞詞典時,通常需要為每一個詞設定詞頻。
對分詞結果進行詞頻統計能從客觀上反映一段文字的側重點.
```python
import jieba
text = '蒸饃饃鍋鍋蒸饃饃,饃饃蒸了一鍋鍋,饃饃擱上桌桌,桌桌上面有饃饃。'
with open('stopwords.txt', 'r+', encoding = 'utf-8')as fp:
stopwords = fp.read().split('\n')
word_dict = {}
jieba.suggest_freq(('桌桌'), True)
seg_list = jieba.cut(text)
for seg in seg_list:
if seg not in stopwords:
if seg in word_dict.keys():
word_dict[seg] += 1
else:
word_dict[seg] = 1
print(word_dict)
輸出:
{'蒸': 3, '饃饃': 5, '鍋鍋': 1, '一鍋': 1, '鍋': 1, '擱': 1, '桌桌': 2, '上面'