python在數據挖掘領域的使用愈來愈普遍。想要使用python作文本分析,分詞是必不可少的一個環節在python的第三方包裏,jieba應該算得上是分詞領域的佼佼者。html
GitHub地址:https://github.com/fxsjy/jiebapython
安裝方法git
# 全自動安裝: easy_install jieba 或者 pip install jieba / pip3 install jieba # 半自動安裝: 先下載 http://pypi.python.org/pypi/jieba/ ,解壓後運行 python setup.py install # 手動安裝: 將 jieba 目錄放置於當前目錄或者 site-packages 目錄
主要算法github
特色正則表達式
支持三種分詞模式:算法
支持繁體分詞app
支持自定義詞典ide
MIT 受權協議函數
主要功能工具
咱們用到的主要是前4個功能,下面就每一個功能具體詳述
5個方法:
注意:待分詞的字符串能夠是 unicode 或 UTF-8 字符串、GBK 字符串。注意:不建議直接輸入 GBK 字符串,可能沒法預料地錯誤解碼成 UTF-8
示例代碼
# encoding=utf-8 import jieba # 精確模式:試圖將句子最精確地切開,適合文本分析; seg_list = jieba.cut("我來到北京清華大學", cut_all=False) print("精確模式:", "/ ".join(seg_list)) # 精確模式: 我/ 來到/ 北京/ 清華大學 # 默認是精確模式 seg_list = jieba.cut("他來到了網易杭研大廈") print("默認模式:", "/ ".join(seg_list)) # 默認模式: 他/ 來到/ 了/ 網易/ 杭研/ 大廈 # 全模式:把句子中全部的能夠成詞的詞語都掃描出來, 速度很是快,可是不能解決歧義問題; seg_list = jieba.cut("我來到北京清華大學", cut_all=True) print("全模式:", "/ ".join(seg_list)) # 全模式: 我/ 來到/ 北京/ 清華/ 清華大學/ 華大/ 大學 # 搜索引擎模式:在精確模式的基礎上,對長詞再次切分,提升召回率,適合用於搜索引擎分詞。 seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在日本京都大學深造") print("搜索引擎模式:", "/ ".join(seg_list)) # 搜索引擎模式: 小明/ 碩士/ 畢業/ 於/ 中國/ 科學/ 學院/ 科學院/ 中國科學院/ 計算/ 計算所/ ,/ 後/ 在/ 日本/ 京都/ 大學/ 日本京都大學/ 深造
開發者能夠指定本身自定義的詞典,以便包含 jieba 詞庫裏沒有的詞。雖然 jieba 有新詞識別能力,可是自行添加新詞能夠保證更高的正確率
用法:
jieba.load_userdict(file_name) # file_name 爲文件類對象或自定義詞典的路徑 # 詞典格式和 dict.txt 同樣,一個詞佔一行;每一行分三部分:詞語、詞頻(可省略)、詞性(可省略),用空格隔開,順序不可顛倒。file_name 若爲路徑或二進制方式打開的文件,則文件必須爲 UTF-8 編碼。 # 詞頻省略時使用自動計算的能保證分出該詞的詞頻。
舉例:
首先添加一個userdict.txt
雲計算 5 李小福 2 nr 創新辦 3 i easy_install 3 eng 好用 300 韓玉賞鑑 3 nz 八一雙鹿 3 nz 臺中 凱特琳 nz Edu Trust認證 2000
而後分詞
#encoding=utf-8 from __future__ import print_function, unicode_literals import sys sys.path.append("../") import jieba jieba.load_userdict("userdict.txt") import jieba.posseg as pseg # 使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中動態修改詞典。 jieba.add_word('石墨烯') jieba.add_word('凱特琳') jieba.del_word('自定義詞') test_sent = ( "李小福是創新辦主任也是雲計算方面的專家; 什麼是八一雙鹿\n" "例如我輸入一個帶「韓玉賞鑑」的標題,在自定義詞庫中也增長了此詞爲N類\n" "「臺中」正確應該不會被切開。mac上可分出「石墨烯」;此時又能夠分出來凱特琳了。" ) words = jieba.cut(test_sent) print('/'.join(words)) print("="*40) result = pseg.cut(test_sent) for w in result: print(w.word, "/", w.flag, ", ", end=' ') print("\n" + "="*40) terms = jieba.cut('easy_install is great') print('/'.join(terms)) terms = jieba.cut('python 的正則表達式是好用的') print('/'.join(terms)) print("="*40) # test frequency tune testlist = [ ('今每天氣不錯', ('今天', '天氣')), ('若是放到post中將出錯。', ('中', '將')), ('咱們中出了一個叛徒', ('中', '出')), ] for sent, seg in testlist: print('/'.join(jieba.cut(sent, HMM=False))) word = ''.join(seg) print('%s Before: %s, After: %s' % (word, jieba.get_FREQ(word), jieba.suggest_freq(seg, True))) print('/'.join(jieba.cut(sent, HMM=False))) print("-"*40)
在構建VSM向量空間模型過程或者把文本轉換成數學形式計算中,會須要運用到關鍵詞提取的技術
基本方法:
jieba.analyse.extract_tags(sentence, topKtopK=20, withWeight=False, allowPOS=()) ''' 1. sentence 爲待提取的文本 2. topK 爲返回幾個 TF/IDF 權重最大的關鍵詞,默認值爲 20 3. withWeight 爲是否一併返回關鍵詞權重值,默認值爲 False 4. allowPOS 僅包括指定詞性的詞,默認值爲空,即不篩選 '''
舉例
乾清宮 3 太和殿 1 午門 1
#encoding=utf-8 import jieba import jieba.analyse #導入自定義詞典 jieba.load_userdict("dict_baidu.txt") #精確模式 text = "故宮的著名景點包括乾清宮、太和殿和午門等。其中乾清宮很是精美,午門是紫禁城的正門,午門居中向陽。" seg_list = jieba.cut(text, cut_all=False) print(u"分詞結果:") print("/".join(seg_list)) #獲取關鍵詞 tags = jieba.analyse.extract_tags(text, topK=3) print(u"關鍵詞:") print(" ".join(tags)) ''' 分詞結果: 故宮/的/著名景點/包括/乾清宮/、/太和殿/和/午門/等/。/其中/乾清宮/很是/精美/,/午門/是/紫禁城/的/正門/,/午門/居中/向陽/。 關鍵詞: 午門 乾清宮 著名景點 ''' # 輸出結果以下,其中"午門"出現3次、"乾清宮"出現2次、"著名景點"出現1次,按照順序輸出提取的關鍵詞。若是topK=5,則輸出:"午門 乾清宮 著名景點 太和殿 向陽"。
在信息檢索中,爲節省存儲空間和提升搜索效率,在處理天然語言數據(或文本)以前或以後會自動過濾掉某些字或詞,這些字或詞即被稱爲Stop Words(停用詞)。這些停用詞都是人工輸入、非自動化生成的,生成後的停用詞會造成一個停用詞表。可是,並無一個明確的停用詞表可以適用於全部的工具。甚至有一些工具是明確地避免使用停用詞來支持短語搜索的。
#encoding=utf-8 import jieba #去除停用詞 stopwords = {}.fromkeys(['的', '包括', '等', '是']) text = "故宮的著名景點包括乾清宮、太和殿和午門等。其中乾清宮很是精美,午門是紫禁城的正門。" segs = jieba.cut(text, cut_all=False) final = '' for seg in segs: seg = seg.encode('utf-8') if seg not in stopwords: final += seg print final #輸出:故宮著名景點乾清宮、太和殿和午門。其中乾清宮很是精美,午門紫禁城正門。 seg_list = jieba.cut(final, cut_all=False) print "/ ".join(seg_list) #輸出:故宮/ 著名景點/ 乾清宮/ 、/ 太和殿/ 和/ 午門/ 。/ 其中/ 乾清宮/ 很是/ 精美/ ,/ 午門/ 紫禁城/ 正門/ 。
標註句子分詞後每一個詞的詞性,採用和 ictclas 兼容的標記法。
# 新建自定義分詞器 jieba.posseg.POSTokenizer(tokenizer=None) # tokenizer 參數可指定內部使用的 jieba.Tokenizer分詞器。jieba.posseg.dt 爲默認詞性標註分詞器。
用法示例
import jieba.posseg as pseg words = pseg.cut("我愛北京天安門") for word, flag in words: print('%s %s' % (word, flag)) ''' 我 r 愛 v 北京 ns 天安門 ns '''
關於詞性標註的詳細說明能夠查看一篇很是好的文章:http://www.hankcs.com/nlp/part-of-speech-tagging.html
將目標文本按行分隔後,把各行文本分配到多個 Python 進程並行分詞,而後歸併結果,從而得到分詞速度的可觀提高(基於 python 自帶的 multiprocessing 模塊,目前暫不支持 Windows)
用法
jieba.enable_parallel(4) # 開啓並行分詞模式,參數爲並行進程數 jieba.disable_parallel() # 關閉並行分詞模式
舉例
import sys import time sys.path.append("../../") import jieba jieba.enable_parallel() url = sys.argv[1] content = open(url,"rb").read() t1 = time.time() words = "/ ".join(jieba.cut(content)) t2 = time.time() tm_cost = t2-t1 log_f = open("1.log","wb") log_f.write(words.encode('utf-8')) print('speed %s bytes/second' % (len(content)/tm_cost)) # 實驗結果:在 4 核 3.4GHz Linux 機器上,對金庸全集進行精確分詞,得到了 1MB/s 的速度,是單進程版的 3.3 倍。
注意:並行分詞僅支持默認分詞器 jieba.dt 和 jieba.posseg.dt。
注意:輸入參數只接受 unicode
默認模式
result = jieba.tokenize(u'永和服裝飾品有限公司') for tk in result: print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2])) ''' word 永和 start: 0 end:2 word 服裝 start: 2 end:4 word 飾品 start: 4 end:6 word 有限公司 start: 6 end:10 '''
搜索模式
result = jieba.tokenize(u'永和服裝飾品有限公司', mode='search') for tk in result: print("word %s\t\t start: %d \t\t end:%d" % (tk[0],tk[1],tk[2])) ''' word 永和 start: 0 end:2 word 服裝 start: 2 end:4 word 飾品 start: 4 end:6 word 有限 start: 6 end:8 word 公司 start: 8 end:10 word 有限公司 start: 6 end:10 '''
用於中文關鍵字的搜索引擎
舉例
# -*- coding: UTF-8 -*- # from __future__ import unicode_literals import sys, os sys.path.append("../") from whoosh.index import create_in, open_dir from whoosh.fields import * from whoosh.qparser import QueryParser from jieba.analyse.analyzer import ChineseAnalyzer # 導入中文分詞工具 analyzer = ChineseAnalyzer() # 建立搜索引擎 schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT(stored=True, analyzer=analyzer)) if not os.path.exists("tmp"): os.mkdir("tmp") ix = create_in("tmp", schema=schema, indexname='indexname') #temp 爲索引建立的地址,indexname爲索引名稱 # ix = open_dir("tmp") # for read only writer = ix.writer() # 添加內容,相似於引擎搜索的庫 writer.add_document( title="document1", path="/a", content="This is the first document we’ve added!" ) writer.add_document( title="document2", path="/b", content="The second one 你 中文測試中文 is even more interesting! 吃水果" ) writer.add_document( title="document3", path="/c", content="買水果真後來世博園。" ) writer.add_document( title="document4", path="/c", content="工信處女幹事每個月通過下屬科室都要親口交代24口交換機等技術性器件的安裝工做" ) writer.add_document( title="document4", path="/c", content="咱倆交換一下吧。" ) writer.commit() ################ 以上爲創建索引的過程 ############## searcher = ix.searcher() parser = QueryParser("content", schema=ix.schema) for keyword in ("水果世博園", "你", "first", "中文", "交換機", "交換"): print("result of ", keyword) q = parser.parse(keyword) # 搜索的關鍵字 results = searcher.search(q) for hit in results: print(hit.highlights("content")) print("=" * 10) for t in analyzer("個人好朋友是李明;我愛北京天安門;IBM和Microsoft; I have a dream. this is intetesting and interested me a lot"): print(t.text)
格式
python -m jieba [options] news.txt > cut_result.txt # >後面是輸出的文件,若是不指定則默認爲標準輸出 ''' options參數: -h, --help 顯示此幫助信息並退出 -d [DELIM], --delimiter [DELIM] 使用 DELIM 分隔詞語,而不是用默認的' / '。 若不指定 DELIM,則使用一個空格分隔。 -p [DELIM], --pos [DELIM] 啓用詞性標註;若是指定 DELIM,詞語和詞性之間 用它分隔,不然用 _ 分隔 -D DICT, --dict DICT 使用 DICT 代替默認詞典 -u USER_DICT, --user-dict USER_DICT 使用 USER_DICT 做爲附加詞典,與默認詞典或自定義詞典配合使用 -a, --cut-all 全模式分詞(不支持詞性標註) -n, --no-hmm 不使用隱含馬爾可夫模型 -q, --quiet 不輸出載入信息到 STDERR -V, --version 顯示版本信息並退出 '''
其餘詞典
佔用內存較小的詞典文件 https://github.com/fxsjy/jieba/raw/master/extra_dict/dict.txt.small
支持繁體分詞更好的詞典文件 https://github.com/fxsjy/jieba/raw/master/extra_dict/dict.txt.big
下載你所須要的詞典,而後覆蓋 jieba/dict.txt 便可;或者用 jieba.set_dictionary('data/dict.txt.big')
常見問題
模型的數據是如何生成的?
詳見: https://github.com/fxsjy/jieba/issues/7
2. 「臺中」老是被切成「臺 中」?(以及相似狀況)
P(臺中) < P(臺)×P(中),「臺中」詞頻不夠致使其成詞機率較低
解決方法:強制調高詞頻
jieba.add_word('臺中') 或者 jieba.suggest_freq('臺中', True)
3. 「今每天氣 不錯」應該被切成「今天 天氣 不錯」?(以及相似狀況)
解決方法:強制調低詞頻
jieba.suggest_freq(('今天', '天氣'), True)
或者直接刪除該詞 jieba.del_word('今每天氣')
4. 切出了詞典中沒有的詞語,效果不理想?
解決方法:關閉新詞發現
jieba.cut('豐田太省了', HMM=False) jieba.cut('咱們中出了一個叛徒', HMM=False)