開源中文分詞工具探析(七):LTP
LTP是哈工大開源的一套中文語言處理系統,涵蓋了基本功能:分詞、詞性標註、命名實體識別、依存句法分析、語義角色標註、語義依存分析等。
【開源中文分詞工具探析】系列:
1. 前言
同THULAC一樣,LTP也是基於結構化感知器(Structured Perceptron, SP),以最大熵準則建模標註序列\(Y\)在輸入序列\(X\)的情況下的score函式:
\[ S(Y,X) = \sum_s \alpha_s \Phi_s(Y,X) \]
其中,\(\Phi_s(Y,X)\)為本地特徵函式。中文分詞問題等價於給定\(X\)序列,求解score函式最大值對應的\(Y\)序列:
\[ \mathop{\arg \max}_Y S(Y,X) \]
2. 分解
以下原始碼分析基於版本3.4.0。
分詞流程
分詞流程與其他分詞器別無二致,先提取字元特徵,計算特徵權重值,然後Viterbi解碼。程式碼詳見__ltp_dll_segmentor_wrapper::segment()
:
int segment(const char *str, std::vector<std::string> &words) { ltp::framework::ViterbiFeatureContext ctx; ltp::framework::ViterbiScoreMatrix scm; ltp::framework::ViterbiDecoder decoder; ltp::segmentor::Instance inst; int ret = preprocessor.preprocess(str, inst.raw_forms, inst.forms, inst.chartypes); if (-1 == ret || 0 == ret) { words.clear(); return 0; } ltp::segmentor::SegmentationConstrain con; con.regist(&(inst.chartypes)); build_lexicon_match_state(lexicons, &inst); extract_features(inst, model, &ctx, false); calculate_scores(inst, (*model), ctx, true, &scm); // allocate a new decoder so that the segmentor support multithreaded // decoding. this modification was committed by niuox decoder.decode(scm, con, inst.predict_tagsidx); build_words(inst.raw_forms, inst.predict_tagsidx, words); return words.size(); }
訓練模型
模型檔案cws.model
包含了類別、特徵、權重、內部詞典(internal lexicon)等。我用Java 重寫了模型解析,程式碼如下:
DataInputStream is = new DataInputStream(new FileInputStream(path)); char[] octws = readCharArray(is, 128); // 1. read label SmartMap label = readSmartMap(is); int[] entries = readIntArray(is, label.numEntries); // 2. read feature Space char[] space = readCharArray(is, 16); int offset = readInt(is); int sz = readInt(is); SmartMap[] dicts = new SmartMap[sz]; for (int i = 0; i < sz; i++) { dicts[i] = readSmartMap(is); } // 3. read param char[] param = readCharArray(is, 16); int dim = readInt(is); double[] w = readDoubleArray(is, dim); double[] wSum = readDoubleArray(is, dim); int lastTimestamp = readInt(is); // 4. read internal lexicon SmartMap internalLexicon = readSmartMap(is); // read char array private static char[] readCharArray(DataInputStream is, int length) throws IOException { char[] chars = new char[length]; for (int i = 0; i < length; i++) { chars[i] = (char) is.read(); } return chars; } // read int array private static int[] readIntArray(DataInputStream is, int length) throws IOException { byte[] bytes = new byte[4 * length]; is.read(bytes); IntBuffer intBuffer = ByteBuffer.wrap(bytes) .order(ByteOrder.LITTLE_ENDIAN) .asIntBuffer(); int[] array = new int[length]; intBuffer.get(array); return array; }
LTP共用到了15類特徵,故sz
為15;特徵是採用Map表示,LTP稱之為SmartMap,看程式碼本質上是一個HashMap。分詞工具測評結果表明,LTP分詞速度較THULAC要慢。究其原因,THULAC採用雙陣列Trie來表示模型,特徵檢索速度要優於LTP。
特徵
LTP所用到的特徵大致可分為以下幾類:
- unigram字元特徵 ch[-2], ch[-1], ch[0], ch[1], ch[2]
- bigram字元特徵 ch[-2]ch[-1], ch[-1]ch[0],ch[0]ch[1],ch[1]ch[2]
- 字元型別特徵 ct[-1], ct[0], ct[1]
- 詞典屬性特徵 ch[0]是否為詞典開始字元、中間字元、結束字元
原始碼見extractor.cpp
:
Extractor::Extractor() {
// delimit feature templates
templates.push_back(new Template("1={c-2}"));
templates.push_back(new Template("2={c-1}"));
templates.push_back(new Template("3={c-0}"));
templates.push_back(new Template("4={c+1}"));
templates.push_back(new Template("5={c+2}"));
templates.push_back(new Template("6={c-2}-{c-1}"));
templates.push_back(new Template("7={c-1}-{c-0}"));
templates.push_back(new Template("8={c-0}-{c+1}"));
templates.push_back(new Template("9={c+1}-{c+2}"));
templates.push_back(new Template("14={ct-1}"));
templates.push_back(new Template("15={ct-0}"));
templates.push_back(new Template("16={ct+1}"));
templates.push_back(new Template("17={lex1}"));
templates.push_back(new Template("18={lex2}"));
templates.push_back(new Template("19={lex3}"));
}
#define TYPE(x) (strutils::to_str(inst.chartypes[(x)]&0x07))
data.set("c-2", (idx - 2 < 0 ? BOS : inst.forms[idx - 2]));
data.set("c-1", (idx - 1 < 0 ? BOS : inst.forms[idx - 1]));
data.set("c-0", inst.forms[idx]);
data.set("c+1", (idx + 1 >= len ? EOS : inst.forms[idx + 1]));
data.set("c+2", (idx + 2 >= len ? EOS : inst.forms[idx + 2]));
data.set("ct-1", (idx - 1 < 0 ? BOT : TYPE(idx - 1)));
data.set("ct-0", TYPE(idx));
data.set("ct+1", (idx + 1 >= len ? EOT : TYPE(idx + 1)));
data.set("lex1", strutils::to_str(inst.lexicon_match_state[idx] & 0x0f));
data.set("lex2", strutils::to_str((inst.lexicon_match_state[idx] >> 4) & 0x0f));
data.set("lex3", strutils::to_str((inst.lexicon_match_state[idx] >> 8) & 0x0f));
#undef TYPE
相關推薦
開源中文分詞工具探析(七):LTP
LTP是哈工大開源的一套中文語言處理系統,涵蓋了基本功能:分詞、詞性標註、命名實體識別、依存句法分析、語義角色標註、語義依存分析等。 【開源中文分詞工具探析】系列: 1. 前言 同THULAC一樣,LTP也是基於結構化感知器(Structured Perceptron, SP),以最大熵準則建模標註序列
開源中文分詞工具探析(六):Stanford CoreNLP
inf git deb seq 效果 analysis stream fix sps CoreNLP是由斯坦福大學開源的一套Java NLP工具,提供諸如:詞性標註(part-of-speech (POS) tagger)、命名實體識別(named entity recog
開源中文分詞工具探析(四):THULAC
THULAC是一款相當不錯的中文分詞工具,準確率高、分詞速度蠻快的;並且在工程上做了很多優化,比如:用DAT儲存訓練特徵(壓縮訓練模型),加入了標點符號的特徵(提高分詞準確率)等。 【開源中文分詞工具探析】系列: 1. 前言 THULAC所採用的分詞模型為結構化感知器(Structured Percep
開源中文分詞工具探析(五):FNLP
FNLP是由Fudan NLP實驗室的邱錫鵬老師開源的一套Java寫就的中文NLP工具包,提供諸如分詞、詞性標註、文字分類、依存句法分析等功能。 【開源中文分詞工具探析】系列: 1. 前言 類似於THULAC,FNLP也是採用線性模型(linear model)分詞。較於對數線性模型(log-linea
開源中文分詞工具探析(三):Ansj
Ansj是由孫健(ansjsun)開源的一箇中文分詞器,為ICTLAS的Java版本,也採用了Bigram + HMM分詞模型(可參考我之前寫的文章):在Bigram分詞的基礎上,識別未登入詞,以提高分詞準確度。雖然基本分詞原理與ICTLAS的一樣,但是Ansj做了一些工程上的優化,比如:用DAT高效地實現檢
中文分詞工具探析(一):ICTCLAS (NLPIR)
【開源中文分詞工具探析】系列: 1. 前言 ICTCLAS是張華平老師推出的中文分詞系統,於2009年更名為NLPIR。ICTCLAS是中文分詞界元老級工具了,作者開放出了free版本的原始碼(1.0整理版本在此). 作者在論文[1] 中宣稱ICTCLAS是基於HHMM(Hierarchical Hid
中文分詞工具探析(二):Jieba
【開源中文分詞工具探析】系列: 1. 前言 Jieba是由fxsjy大神開源的一款中文分詞工具,一款屬於工業界的分詞工具——模型易用簡單、程式碼清晰可讀,推薦有志學習NLP或Python的讀一下原始碼。與採用分詞模型Bigram + HMM 的ICTCLAS 相類似,Jieba採用的是Unigram +
北大開源全新中文分詞工具包:準確率遠超THULAC、結巴分詞
選自GitHub,作者:羅睿軒、許晶晶、孫栩,機器之心編輯。 最近,北大開源了一箇中文分詞工具包,它在多個分詞資料集上都有非常高的分詞準確率。其中廣泛使用的結巴分詞誤差率高達 18.55% 和 20.42,而北大的 pkuseg 只有 3.25% 與 4.32%。 pkuseg 是由北京
在PyCharm(Python整合開發環境)中安裝jieba中文分詞工具包
PyCharm IDE中,可以直接引入各種工具包。jieba中文分詞工具包安裝非常方便。 1、開啟Pycharm,點選左上角 >>File >>Settings。 2、在settings介面中點選Project :***(專案名稱) >
PyNLPIR python中文分詞工具
命名 hub 兩個 工具 ict mage ret wid tty 官網:https://pynlpir.readthedocs.io/en/latest/ github:https://github.com/tsroten/pynlpir NLPIR分詞系
7個優秀的開源中文分詞庫推薦
中文分詞是中文文字處理的基礎步驟,也是中文人機自然語言互動的基礎模組。由於中文句子中沒有詞的界限,因此在進行中文自然語言處理時,通常需要先進行分詞。 縱觀整個開源領域,陸陸續續做中文分詞的也有不少,不過目前仍在維護的且質量較高的並不多。下面整理了一些個人認為比較優秀的中文分詞庫,以供大家
Hanlp等七種優秀的開源中文分詞庫推薦
中文分詞是中文文字處理的基礎步驟,也是中文人機自然語言互動的基礎模組。由於中文句子中沒有詞的界限,因此在進行中文自然語言處理時,通常需要先進行分詞。 縱觀整個開源領域,陸陸續續做中文分詞的也有不少,不過目前仍在維護的且質量較高的並不多。下面整理了一些個人認為比較優秀的中文分
10大Java開源中文分詞器的使用方法和分詞效果對比
原文地址:http://my.oschina.net/apdplat/blog/412921 本文的目標有兩個: 1、學會使用10大Java開源中文分詞器 2、對比分析10 大Java開源中文分詞器的分詞效果 本文給出了10大Java開源中文分詞的使用方法以及分詞
【NLP】11大Java開源中文分詞器的使用方法和分詞效果對比
本文的目標有兩個: 1、學會使用11大Java開源中文分詞器 2、對比分析11大Java開源中文分詞器的分詞效果 本文給出了11大Java開源中文分詞的使用方法以及分詞結果對比程式碼,至於效果哪個好,那要用的人結合自己的應用場景自己來判斷。 11大Java開源中文分詞器,不同的分詞器
Solr與開源中文分詞(ansj)整合
1. ansj分詞原始碼及jar包下載地址 原始碼: https://github.com/NLPchina/ansj_seg jar包: http://maven.nlpcn.org/org/ansj/ http://maven.nlpcn.org/org/nlpcn/n
中文分詞工具thulac4j釋出
1. 介紹 thulac4j是THULAC的Java 8工程化實現,具有分詞速度快、準、強的特點;支援 自定義詞典 繁體轉簡體 停用詞過濾 若想在專案中使用thulac4j,可新增依賴: <dependency> <groupId>io.github.yizhiru</g
乾貨 | 史上最全中文分詞工具整理
作者 | fendouai 一.中文分詞 分詞服務介面列表 二.準確率評測: THULAC:與代表性分詞軟體的效能對比 我們選擇LTP-3.2.0 、ICTCLAS(2015版) 、jieba(C++版)等國內具代表性的分詞軟體與THULAC做效能
中文分詞工具
THULAC 四款python中中文分詞的嘗試。嘗試的有:jieba、SnowNLP(MIT)、pynlpir(大資料搜尋挖掘實驗室(北京市海量語言資訊處理與雲端計算應用工程技術研究中心))、thulac(清華大學自然語言處理與社會人文計算實驗室) 四款都
python中文分詞工具:結巴分詞jieba
結巴分詞jieba特點 支援三種分詞模式: 精確模式,試圖將句子最精確地切開,適合文字分析; 全模式,把句子中所有的可以成詞的詞語都掃描出來, 速度非常快,但是不能解決歧義; 搜尋引擎模式,在精確模式的基礎上,對長詞再次切分,提
jieba.NET是jieba中文分詞的.NET版本(C#實現)。
jieba.NET是jieba中文分詞的.NET版本(C#實現)。 當前版本為0.38.2,基於jieba 0.38,提供與jieba一致的功能與介面,以後可能會在jieba基礎上提供其它擴充套件功能。關於jieba的實現思路,可以看看這篇wiki裡提到的資料。 如果