十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
一、前言

我們提供的服務(wù)有:成都做網(wǎng)站、成都網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、宿城ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的宿城網(wǎng)站制作公司
分詞,我想是大多數(shù)大前端開(kāi)發(fā)人員,都不會(huì)接觸到的一個(gè)概念。這個(gè)不影響我們了解它,畢竟我們要多方向發(fā)展。今天就來(lái)簡(jiǎn)單介紹一些分詞,我盡量用簡(jiǎn)介的語(yǔ)言來(lái)描述這個(gè)概念,并且最后再提供一個(gè)解決方案,希望對(duì)你有幫助。
分詞簡(jiǎn)單來(lái)講就是把一句話,按照詞義,切分成一個(gè)個(gè)單獨(dú)的詞。這么說(shuō)可能沒(méi)什么感覺(jué),先看看它適用的場(chǎng)景,分詞是文本挖掘的基礎(chǔ),通常會(huì)用于自然語(yǔ)言處理、分詞搜索、推薦等等領(lǐng)域。
二、分詞的原理和算法
2.1 什么是分詞
先理解一下分詞的概念。
分詞就是將連續(xù)的字序列,按照一定的規(guī)范重新組合成詞序列的過(guò)程。在英文中,單詞之間會(huì)以空格作為分割符,將詞與詞之間進(jìn)行分割,但是對(duì)于中文,沒(méi)有一個(gè)顯式的分割符。
正是因?yàn)槿狈@種顯式的分割符,導(dǎo)致我們對(duì)中文中的詞,進(jìn)行分割的時(shí)候會(huì)出現(xiàn)很多的偏差。
2.2 分詞的算法
中文分詞有難度,不過(guò)也有成熟的解決方案?,F(xiàn)有的分詞算法,大概可分為三類:
1. 基于字符串匹配的分詞算法
這種分詞方法,又叫機(jī)械分詞算法,它會(huì)提前維護(hù)一個(gè)大的字典,然后將句子和字典中的詞進(jìn)行匹配,若匹配成功,則可以進(jìn)行分詞處理。
當(dāng)然,它實(shí)際上會(huì)更復(fù)雜一些,因?yàn)楫?dāng)字典足夠大的時(shí)候,就又涉及到不同的匹配算法,這里就不展開(kāi)講了。通常會(huì)基于 Trie 樹(shù)結(jié)構(gòu),來(lái)實(shí)現(xiàn)高效的詞圖掃描。
2. 基于理解的分詞算法
這種分詞方法,通過(guò)讓計(jì)算機(jī),模擬人對(duì)句子的理解,達(dá)到識(shí)別詞組的效果。其基本思想是在分詞的同時(shí)進(jìn)行句法、語(yǔ)義的分析,利用句法和語(yǔ)義信息來(lái)處理歧義現(xiàn)象。
它通常會(huì)包含三部分:分詞子系統(tǒng)、句法語(yǔ)義子系統(tǒng)、總控部分。在總控部分的協(xié)調(diào)下,分詞子系統(tǒng)可以獲得有關(guān)詞、句子等的句法和語(yǔ)義信息,來(lái)對(duì)分詞歧義進(jìn)行判斷,即它模擬了人對(duì)句子的理解過(guò)程。由于漢語(yǔ)語(yǔ)言知識(shí)的籠統(tǒng)、復(fù)雜性,難以將各種語(yǔ)言信息組織成機(jī)器可直接讀取的形式,因此目前基于理解的分詞系統(tǒng)還處在試驗(yàn)階段。
3. 基于統(tǒng)計(jì)的分詞算法
這種方法會(huì)給出大量已經(jīng)分詞的文本,利用統(tǒng)計(jì)機(jī)器學(xué)習(xí)模型,學(xué)習(xí)詞語(yǔ)切分的規(guī)律(稱為訓(xùn)練),從而實(shí)現(xiàn)對(duì)未知文本的切分。
隨著大規(guī)模語(yǔ)料庫(kù)的建立,統(tǒng)計(jì)機(jī)器學(xué)習(xí)方法的研究和發(fā)展,基于統(tǒng)計(jì)的中文分詞方法漸漸成為了主流方法。
2.3 分詞的訴求
雖然分詞的算法,講解起來(lái)很簡(jiǎn)單,但是從現(xiàn)有的經(jīng)驗(yàn)來(lái)看,幾乎是不存在通用且效果非常好的分詞系統(tǒng)。
每個(gè)領(lǐng)域,都有其獨(dú)特的詞匯,這很難通過(guò)有限的訓(xùn)練數(shù)據(jù),捕捉到所有的語(yǔ)言特征。例如:通過(guò)人民日?qǐng)?bào)訓(xùn)練的分詞系統(tǒng),在網(wǎng)絡(luò)玄幻小說(shuō)上,分詞的效果就不會(huì)好。
這是必然的,在分詞系統(tǒng)中,沒(méi)有銀彈。
不同的場(chǎng)景,對(duì)分詞的要求也差異很大,通??梢詮膬蓚€(gè)維度進(jìn)行區(qū)分:分詞速度、分詞準(zhǔn)確性。
例如分詞搜索,對(duì)速度要求就高于準(zhǔn)確性的要求。而一些問(wèn)答系統(tǒng)中,則需要對(duì)文本實(shí)現(xiàn)較深的理解,要求準(zhǔn)確性高于速度要求。
不同的領(lǐng)域,不同的使用場(chǎng)景,對(duì)分詞的要求是不同的,所以我們不能片面的去理解分詞的準(zhǔn)確率。并且隨著新詞的增加,訓(xùn)練數(shù)據(jù)的變化,分詞的準(zhǔn)確率也是在波動(dòng)的。這也就是,現(xiàn)在吹噓分詞準(zhǔn)確率的公司越來(lái)越少的原因。
2.4 分詞的解決方案
分詞是可以解決實(shí)際問(wèn)題的功能,經(jīng)過(guò)這么長(zhǎng)時(shí)間的反復(fù)迭代更新,市面上一家產(chǎn)生了一批有特色的分詞系統(tǒng)。例如:IK、Jieba、Ansj、Hanlp、Stanford分詞 等等。
有興趣可以一個(gè)個(gè)了解,接下來(lái)就其中的一個(gè)開(kāi)源庫(kù) Jieba,進(jìn)行講解。
三、jieba
3.1 jieba 的優(yōu)點(diǎn)
jieba 是開(kāi)源的,號(hào)稱是 Python 中,最好的中文分詞組件。并且是基于 MIT 的協(xié)議,使用起來(lái)無(wú)后顧之憂。
jieba 使用起來(lái)也非常的簡(jiǎn)單,幾行代碼就可以實(shí)現(xiàn)分詞調(diào)用和詞性標(biāo)注,而且速度還不錯(cuò)。
它內(nèi)部維護(hù)了一個(gè)詞典,是根據(jù)人民日?qǐng)?bào)分析獲得,在超出詞典之外的新詞,會(huì)基于 HMM 模型進(jìn)行識(shí)別。
它提供三種分詞模式:精準(zhǔn)模式、全模式、搜索模式。全模式是找到所有可能的詞語(yǔ),搜索模式是在精確模式的基礎(chǔ)上對(duì)長(zhǎng)詞進(jìn)行切分,提高分割率。
在分詞的速度上,精確模式能達(dá)到 400KB/s,全模式下能達(dá)到 1.5MB/s。同時(shí)除了 Python 版本之外,還有不同的人基于 Python 版的 jieba ,擴(kuò)展出多種語(yǔ)言實(shí)現(xiàn),包括:JavaScript、Java、Golang、R、PHP 等。
jieba 的使用
jieba 的代碼對(duì) Python 2/3 均兼容,在使用之前,需要通過(guò)命令 pip install jieba 或者 pip3 install jieba 進(jìn)行安裝。
具體 Api,就不展開(kāi)講了,有興趣可以去查看 Github 上的文檔(文末有地址)。
這里提供一個(gè)簡(jiǎn)單的代碼示例,來(lái)感受一下 jieba 的方便與強(qiáng)大。
- # encoding=utf-8
- import jieba
- seg_list = jieba.cut("我來(lái)到北京清華大學(xué)", cut_all=True)
- print("Full Mode: " + "/ ".join(seg_list)) # 全模式
- seg_list = jieba.cut("我來(lái)到北京清華大學(xué)", cut_all=False)
- print("Default Mode: " + "/ ".join(seg_list)) # 精確模式
- seg_list = jieba.cut("他來(lái)到了網(wǎng)易杭研大廈") # 默認(rèn)是精確模式
- print(", ".join(seg_list))
- seg_list = jieba.cut_for_search("小明碩士畢業(yè)于中國(guó)科學(xué)院計(jì)算所,后在日本京都大學(xué)深造") # 搜索引擎模式
- print(", ".join(seg_list))
輸出的結(jié)果:
【全模式】: 我/ 來(lái)到/ 北京/ 清華/ 清華大學(xué)/ 華大/ 大學(xué)
【精確模式】: 我/ 來(lái)到/ 北京/ 清華大學(xué)
【新詞識(shí)別】:他, 來(lái)到, 了, 網(wǎng)易, 杭研, 大廈 (此處,“杭研”并沒(méi)有在詞典中,但是也被Viterbi算法識(shí)別出來(lái)了)
【搜索引擎模式】: 小明, 碩士, 畢業(yè), 于, 中國(guó), 科學(xué), 學(xué)院, 科學(xué)院, 中國(guó)科學(xué)院, 計(jì)算, 計(jì)算所, 后, 在, 日本, 京都, 大學(xué), 日本京都大學(xué), 深造
前面也提到,jieba 自身維護(hù)了一個(gè)詞組的字典,如果自身需求上,有專有名詞需要拆分,還可以通過(guò) jieba.Tokenizer(dictionary=DEFAULT_DICT) 載入一個(gè)自定義字典。
3.2 jieba 的分詞算法
匹配的算法,說(shuō)起來(lái)就復(fù)雜了,這里就簡(jiǎn)單介紹一下 jiaba 分詞匹配的原理。
首先,jieba 分詞已經(jīng)自帶了一個(gè) dict.txt 的詞典,里面有 2w 多個(gè)詞條,包括出現(xiàn)的次數(shù)和詞性,這是作者自己基于人民日?qǐng)?bào)為主的資料,訓(xùn)練的出來(lái)的。
jieba 會(huì)先將這個(gè)詞典中的數(shù)據(jù),放到一個(gè) Trie 樹(shù)中,Trie 樹(shù)是有名的前綴樹(shù),當(dāng)一個(gè)詞語(yǔ)的前面幾個(gè)字一樣的時(shí)候,就標(biāo)識(shí)他們具有相同的前綴,就可以使用 Trie 數(shù)來(lái)存儲(chǔ),具有查找速度快的優(yōu)勢(shì)。
其次,在需要對(duì)句子進(jìn)行分詞的時(shí)候,再根據(jù)前面生成的 Trie 數(shù),生成有向無(wú)環(huán)圖(DAG),這一步的意義在于,消除分詞中的歧義,提高切分準(zhǔn)確度,找出這句話中,所有可能的詞。
到這一步,基本上就完成了,所有字典中記錄的詞,進(jìn)行分詞的過(guò)程。
但是如果你把 dict.txt 這個(gè)字典刪除,jieba 依然可以進(jìn)行分詞,只是拆分出來(lái)的詞,大部分的長(zhǎng)度為 2。這是因?yàn)?,?duì)于未在字典中收錄的詞,基于隱馬爾科夫模型(HMM)來(lái)預(yù)測(cè)分詞,使用的是 Viterbi 算法。
HMM 模型中,將中文詞匯按照 BEMS 四個(gè)狀態(tài)來(lái)標(biāo)記, B 是開(kāi)始 begin 位置, E 是 end, 是結(jié)束位置, M 是 middle, 是中間位置, S 是 singgle, 單獨(dú)成詞的位置, 沒(méi)有前, 也沒(méi)有后. 也就是說(shuō), 他采用了狀態(tài)為(B,E,M,S)這四種狀態(tài)來(lái)標(biāo)記中文詞語(yǔ), 比如北京可以標(biāo)注為 BE, 即 北/B 京/E, 表示北是開(kāi)始位置, 京是結(jié)束位置, 中華民族可以標(biāo)注為 BMME , 就是開(kāi)始, 中間, 中間, 結(jié)束.
作者通過(guò)對(duì)大量語(yǔ)料的訓(xùn)練,得到了 finalseg 目錄下的訓(xùn)練結(jié)果,有興趣可以自行研究。
到這里基本上就清晰了,jieba 分詞的過(guò)程主要有以下三步:
加載 dict.txt 字典,生成 Trie 樹(shù)。
對(duì)待分詞的句子,通過(guò) Trie 樹(shù),生成 DAG 圖,匹配出所有可能的詞。
再使用 HMM 模型,將字典中未收錄的詞,匹配出來(lái)。
這就是 jieba 分詞的執(zhí)行過(guò)程。
四、jieba(Java or Android)
4.1 Java 版的 jieba
jieba 發(fā)展到現(xiàn)在,已經(jīng)支持眾多的版本。Java 版并非原作者開(kāi)編寫(xiě),而是 hanban 參考原作者的分詞原理,進(jìn)行開(kāi)發(fā)的。
不過(guò) Java 版并沒(méi)有原版 Python 版本那么強(qiáng)大,做了部分閹割,例如關(guān)鍵詞提取就沒(méi)有實(shí)現(xiàn)。
有興趣可以直接去看 Github : https://github.com/huaban/jieba-analysis/
1. 引入依賴(穩(wěn)定版)
com.huaban jieba-analysis 1.0.2
2. 如何使用
- @Test
- public void testDemo() {
- JiebaSegmenter segmenter = new JiebaSegmenter();
- String[] sentences =
- new String[] {"這是一個(gè)伸手不見(jiàn)五指的黑夜。我叫孫悟空,我愛(ài)北京,我愛(ài)Python和C++。", "我不喜歡日本和服。", "雷猴回歸人間。",
- "工信處女干事每月經(jīng)過(guò)下屬科室都要親口交代24口交換機(jī)等技術(shù)性器件的安裝工作", "結(jié)果婚的和尚未結(jié)過(guò)婚的"};
- for (String sentence : sentences) {
- System.out.println(segmenter.process(sentence, SegMode.INDEX).toString());
- }
- }
3. 性能評(píng)估
作者在測(cè)試機(jī)上進(jìn)行測(cè)試,配置為:
- Processor 2 Intel(R) Pentium(R) CPU G620 @ 2.60GHz
- Memory:8GB
測(cè)試結(jié)果還算理想,單線程,對(duì)測(cè)試文本逐行分詞,并循環(huán)調(diào)用上萬(wàn)次的效率分析。
- 循環(huán)調(diào)用一萬(wàn)次
- 第一次測(cè)試結(jié)果:
- time elapsed:12373, rate:2486.986533kb/s, words:917319.94/s
- 第二次測(cè)試結(jié)果:
- time elapsed:12284, rate:2505.005241kb/s, words:923966.10/s
- 第三次測(cè)試結(jié)果:
- time elapsed:12336, rate:2494.445880kb/s, words:920071.30/s
- 循環(huán)調(diào)用2萬(wàn)次
- 第一次測(cè)試結(jié)果:
- time elapsed:22237, rate:2767.593144kb/s, words:1020821.12/s
- 第二次測(cè)試結(jié)果:
- time elapsed:22435, rate:2743.167762kb/s, words:1011811.87/s
- 第三次測(cè)試結(jié)果:
- time elapsed:22102, rate:2784.497726kb/s, words:1027056.34/s
- 統(tǒng)計(jì)結(jié)果:詞典加載時(shí)間1.8s左右,分詞效率每秒2Mb多,近100萬(wàn)詞。
- 2 Processor Intel(R) Core(TM) i3-2100 CPU @ 3.10GHz
- 12G 測(cè)試效果
- time elapsed:19597, rate:3140.428063kb/s, words:1158340.52/s
- time elapsed:20122, rate:3058.491639kb/s, words:1128118.44/s
4.2 在 Android 下使用 jieba
jieba(Java)版本,本身也是自帶詞典的,所以在 Android 下引入,會(huì)增大 Apk 的體積。同時(shí)因?yàn)樵O(shè)備的配置,還會(huì)影響到分詞的效率。
不過(guò)如果非要使用在 Android 設(shè)備上,例如對(duì)搜索詞進(jìn)行一個(gè)預(yù)處理,也是可以的。Apk 增大的問(wèn)題,其實(shí)可以通過(guò)安裝后下載詞典的方式規(guī)避。
jieba(java) 使用 maven 管理,所以需要 Gradle 簡(jiǎn)單配置一下,讓其支持。
1. 配置 build.gradle
- repositories {
- google()
- jcenter()
- mavenCentral()
- }
2. 引入依賴
- implementation 'com.huaban:jieba-analysis:1.0.2'
引入之后,使用細(xì)節(jié)就沒(méi)什么好說(shuō)的了,和 Java 版本無(wú)差別。
參考:
https://github.com/fxsjy/jieba
https://github.com/huaban/jieba-analysis/
https://blog.csdn.net/John_xyz/article/details/54645527
http://www.infoq.com/cn/articles/nlp-word-segmentation
【本文為專欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)聯(lián)系作者獲取授權(quán)】