中文分詞入門之字標注法4

http://www.52nlp.cn/%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AD%97%E6%A0%87%E6%B3%A8%E6%B3%954

上一節主要介紹的是利用最大熵工具包來做字標注中文分詞,這一節我們直奔主題,借用條件隨機場工具“CRF++: Yet Another CRF toolkit”來完成字標注中文分詞的全過程。

關于條件隨機場(CRF)的背景知識,推薦參考閱讀一些經典的文獻:《條件隨機場文獻閱讀指南》,另外再額外推薦一個tutorial:《Classical Probabilistic Models and Conditional Random Fields》, 這份關于CRF的文檔分別從概率模型(NB,HMM,ME, CRF)之間的關系以及概率圖模型背景來介紹條件隨機場,比較清晰:

While a Hidden Markov Model is a sequential extension to the Nave Bayes Model, Conditional Random Fields can be understood as a sequential extension to the Maximum Entropy Model.

如果這些還不夠過癮,推薦課程圖譜上收錄的Coursera創始人之一Daphne Koller的“概率圖模型公開課”,相信拿下這門課之后,對于上述概率模型,會有一種“一覽眾山小”的感覺。

不過我們還是要從安裝CRF++工具包說起,在Linux或者Mac OS系統下,下載C++源代碼安裝包(這里用的是?CRF++-0.58.tar.gz?)之后,依然是 “configure & make & (sudo) make install”,安裝完畢之后,可以cd python進入到其同樣用SWIG生成的Python工具包下,安裝python包:python setup.py build & (sudo) python setup.py install。安裝完畢之后,可以在python解釋器下測試,是否能成功import CRFPP,如果ok,則準備工作就緒。

上一節我們利用最大熵模型工具包里自帶的詞性標注工具進行的中文分詞,稍微有些曲折,這一節我們依然利用CRF++ example里的樣例進行測試,不過好處是,CRF++ example里有個seg目錄,這個seg目錄對應的是一個日文分詞的樣例,正好可以套用到我們的中文分詞中來。在安裝包目錄下,cd example, cd seg目錄后,有4個文件:

exec.sh(執行腳本)
template(特征模板)
test.data(測試集)
train.data(訓練集)

有了這4個文件,我們可以做得事情就比較簡單,只要按測試集,訓練集的格式準備數據就可以了,特征模板和執行腳本可以套用,不過這里簡單解讀一下這幾個CRF++文件。首先來看訓練集:

1
2
3
4
5
6
7
8
9
10
毎 k ? B
日 k ? I
新 k ? I
聞 k ? I
社 k ? I
特 k ? B
別 k ? I
顧 k ? B
問 k ? I ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
4 n ? B

這里第一列是待分詞的日文字,第二列暫且認為其是詞性標記,第三列是字標注中的2-tag(B, I)標記,這個很重要,對于我們需要準備的訓練集,主要是把這一列的標記做好,不過需要注意的是,其斷句是靠空行來完成的。

再來看測試集的格式:

1
2
3
4
5
6
7
8
9
10
よ h ? I
っ h ? I
て h ? I
私 k ? B
た h ? B
ち h ? I
の h ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
世 k ? B
代 k ? I
が h ? B

同樣也有3列,第一列是日文字,第二列第三列與上面是相似的,不過在測試集里第三列主要是占位作用。事實上,CRF++對于訓練集和測試集文件格式的要求是比較靈活的,首先需要多列,但不能不一致,既在一個文件里有的行是兩列,有的行是三列;其次第一列代表的是需要標注的“字或詞”,最后一列是輸出位”標記tag”,如果有額外的特征,例如詞性什么的,可以加到中間列里,所以訓練集或者測試集的文件最少要有兩列。

接下里我們再來詳細的分析一下特征模板文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Unigram
U00:%x[-2,0]
U01:%x[-1,0]
U02:%x[0,0]
U03:%x[1,0]
U04:%x[2,0]
U05:%x[-2,0]/%x[-1,0]/%x[0,0]
U06:%x[-1,0]/%x[0,0]/%x[1,0]
U07:%x[0,0]/%x[1,0]/%x[2,0]
U08:%x[-1,0]/%x[0,0] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
U09:%x[0,0]/%x[1,0]

# Bigram
B

關于CRF++中特征模板的說明和舉例,請大家參考官方文檔上的“Preparing feature templates”這一節,而以下部分的說明拿上述日文分詞數據舉例。在特征模板文件中,每一行(如U00:%x[-2,0])代表一個特征,而宏“%x[行位置,列位置]”則代表了相對于當前指向的token的行偏移和列的絕對位置,以上述訓練集為例,如果當前掃描到“新 k I”這一行,

1
2
3
4
5
6
7
8
9
10
毎 k ? B
日 k ? I
新 k ? I ? <== 掃描到這一行,代表當前位置
聞 k ? I
社 k ? I
特 k ? B
別 k ? I
顧 k ? B
問 k ? I
4 n ? B

那么依據特征模板文件抽取的特征如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Unigram
U00:%x[-2,0] ==> 毎
U01:%x[-1,0] ==> 日
U02:%x[0,0] ?==> 新
U03:%x[1,0] ?==> 聞
U04:%x[2,0] ?==> 社
U05:%x[-2,0]/%x[-1,0]/%x[0,0] ==> 每/日/新
U06:%x[-1,0]/%x[0,0]/%x[1,0] ?==> 日/新/聞
U07:%x[0,0]/%x[1,0]/%x[2,0] ? ==> 新/聞/社
U08:%x[-1,0]/%x[0,0] ? ? ? ? ?==> 日/新
U09:%x[0,0]/%x[1,0] ? ? ? ? ? ==> 新/聞

# Bigram
B

CRF++里將特征分成兩種類型,一種是Unigram的,“U”起頭,另外一種是Bigram的,“B”起頭。對于Unigram的特征,假如一個特征模板是”U01:%x[-1,0]”, CRF++會自動的生成一組特征函數(func1 … funcN) 集合:

1
2
3
4
5
func1 = if (output = B and feature="U01:日") return 1 else return 0
func2 = if (output = I and feature="U01:日") return 1 else return 0
....
funcXX = if (output = B and feature="U01:問") return 1 ?else return 0
funcXY = if (output = I and feature="U01:問") return 1 ?else return 0

生成的特征函數的數目 = (L * N),其中L是輸出的類型的個數,這里是B,I這兩個tag,N是通過模板擴展出來的所有單個字符串(特征)的個數,這里指的是在掃描所有訓練集的過程中找到的日文字(特征)。

而Bigram特征主要是當前的token和前面一個位置token的自動組合生成的bigram特征集合。最后需要注意的是U01和U02這些標志位,與特征token組合到一起主要是區分“U01:問”和“U02:問”這類特征,雖然抽取的日文”字”特征是一樣的,但是在CRF++中這是有區別的特征。

最后我們再來看一下執行腳本:

1
2
3
4
5
6
7
#!/bin/sh
../../crf_learn -f 3 -c 4.0 template train.data model
../../crf_test -m model test.data

../../crf_learn -a MIRA -f 3 template train.data model
../../crf_test -m model test.data
rm -f model

執行腳本告訴了我們如何訓練一個CRF模型,以及如何利用這個模型來進行測試,執行這個腳本之后,對于輸入的測試集,輸出結果多了一列:

1
2
3
4
5
6
7
8
9
10
よ h ? I ? B
っ h ? I ? I
て h ? I ? B
私 k ? B ? B
た h ? B ? B
ち h ? I ? I
の h ? B ? B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
世 k ? B ? B
代 k ? I ? I
が h ? B ? B

而這一列才是模型預測的改字的標記tag,也正是我們所需要的結果。到此為止,關于日文分詞樣例的介紹已經完畢,讀者應該可以猜測到接下來我們會如何做中文分詞吧?

和上一節利用最大熵模型進行中文分詞相似,第一步仍然是將backoff2005里的訓練數據轉化為CRF++所需的訓練數據格式,還是以微軟亞洲研究院提供的中文分詞語料為例,依然采用4-tag(B(Begin,詞首), E(End,詞尾), M(Middle,詞中), S(Single,單字詞))標記集,只處理utf-8編碼文本。原始訓練集./icwb2-data/training/msr_training.utf8的形式是人工分好詞的中文句子形式,如:

1
2
3
4
5
6
7
8
9
10
“ ?人們 ?常 ?說 ?生活 ?是 ?一 ?部 ?教科書 ?, ?而 ?血 ?與 ?火 ?的 ?戰爭 ?> ? ? ?更 ?是 ?不可多得 ?的 ?教科書 ?, ?她 ?確實 ?是 ?名副其實 ?的 ?‘ ?我 ?的 ?> ? ? ?大學 ?’ ?。
“ ?心 ?靜 ?漸 ?知 ?春 ?似 ?海 ?, ?花 ?深 ?每 ?覺 ?影 ?生 ?香 ?。
“ ?吃 ?屎 ?的 ?東西 ?, ?連 ?一 ?捆 ?麥 ?也 ?鍘 ?不 ?動 ?呀 ??
他 ?“ ?嚴格要求 ?自己 ?, ?從 ?一個 ?科舉 ?出身 ?的 ?進士 ?成為 ?一個 ?偉> ? ? ?大 ?的 ?民主主義 ?者 ?, ?進而 ?成為 ?一 ?位 ?杰出 ?的 ?黨外 ?共產主義 ?戰 士 ?, ?獻身 ?于 ?崇高 ?的 ?共產主義 ?事業 ?。
“ ?征 ?而 ?未 ?用 ?的 ?耕地 ?和 ?有 ?收益 ?的 ?土地 ?, ?不準 ?荒蕪 ?。
“ ?這 ?首先 ?是 ?個 ?民族 ?問題 ?, ?民族 ?的 ?感情 ?問題 ?。
’ ?我 ?扔 ?了 ?兩顆 ?手榴彈 ?, ?他 ?一下子 ?出 ?溜 ?下去 ?。
“ ?廢除 ?先前 ?存在 ?的 ?所有制 ?關系 ?, ?并不是 ?共產主義 ?所 ?獨具 ?的 ? ? ? ?特征 ?。
“ ?這個 ?案子 ?從 ?始 ?至今 ?我們 ?都 ?沒有 ?跟 ?法官 ?接觸 ?過 ?, ?也 ?> ? ? ?沒有 ?跟 ?原告 ?、 ?被告 ?接觸 ?過 ?。
“ ?你 ?只有 ?把 ?事情 ?做好 ?, ?大伙 ?才 ?服 ?你 ?。

這里同樣提供一個腳本?make_crf_train_data.py,將這個訓練語料轉換為CRF++訓練用的語料格式(2列,4-tag):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_tagging(input_file, output_file):
? ? input_data = codecs.open(input_file, 'r', 'utf-8')
? ? output_data = codecs.open(output_file, 'w', 'utf-8')
? ? for line in input_data.readlines():
? ? ? ? word_list = line.strip().split()
? ? ? ? for word in word_list:
? ? ? ? ? ? if len(word) == 1:
? ? ? ? ? ? ? ? output_data.write(word + "\tS\n")
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? output_data.write(word[0] + "\tB\n")
? ? ? ? ? ? ? ? for w in word[1:len(word)-1]:
? ? ? ? ? ? ? ? ? ? output_data.write(w + "\tM\n")
? ? ? ? ? ? ? ? output_data.write(word[len(word)-1] + "\tE\n")
? ? ? ? output_data.write("\n")
? ? input_data.close()
? ? output_data.close()

if __name__ == '__main__':
? ? if len(sys.argv) != 3:
? ? ? ? print "pls use: python make_crf_train_data.py input output"
? ? ? ? sys.exit()
? ? input_file = sys.argv[1]
? ? output_file = sys.argv[2]
? ? character_tagging(input_file, output_file)

只需要執行“python make_crf_train_data.py ./icwb2-data/training/msr_training.utf8 msr_training.tagging4crf.utf8” 即可得到CRF++要求的格式的訓練文件msr_training.tagging4crf.utf8,樣例如下:

1
2
3
4
5
6
7
8
9
10
11
“ S
人 B
們 E
常 S
說 S
生 B
活 E
是 S ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
一 S
部 S
...

有了這份訓練語料,就可以利用crf的訓練工具crf_learn來訓練模型了,執行如下命令即可:

crf_learn -f 3 -c 4.0 template msr_training.tagging4crf.utf8 crf_model

這次訓練的時間稍微有些長,在我的4G內存的mac pro上跑了將近700輪,大約2個小時,最終訓練的crf_model約51M。有了模型,現在我們需要做得還是準備一份CRF++用的測試語料,然后利用CRF++的測試工具crf_test進行字標注。原始的測試語料是icwb2-data/testing/msr_test.utf8 ,樣例如下:

1
2
3
4
5
6
7
8
9
10
揚帆遠東做與中國合作的先行
希臘的經濟結構較特殊。
海運業雄踞全球之首,按噸位計占世界總數的17%。
另外旅游、僑匯也是經濟收入的重要組成部分,制造業規模相對較小。
多年來,中希貿易始終處于較低的水平,希臘幾乎沒有在中國投資。
十幾年來,改革開放的中國經濟高速發展,遠東在崛起。
瓦西里斯的船只中有40%駛向遠東,每個月幾乎都有兩三條船停靠中國港口。
他感受到了中國經濟發展的大潮。
他要與中國人合作。
他來到中國,成為第一個訪華的大船主。

這里我們同樣提供一個python腳本?make_crf_test_data.py?對測試語料進行處理,將其轉換為CRF++要求的格式(2列,B作為最后一列的占位符)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_split(input_file, output_file):
? ? input_data = codecs.open(input_file, 'r', 'utf-8')
? ? output_data = codecs.open(output_file, 'w', 'utf-8')
? ? for line in input_data.readlines():
? ? ? ? for word in line.strip():
? ? ? ? ? ? word = word.strip()
? ? ? ? ? ? if word:
? ? ? ? ? ? ? ? output_data.write(word + "\tB\n")
? ? ? ? output_data.write("\n")
? ? input_data.close()
? ? output_data.close()

if __name__ == '__main__':
? ? if len(sys.argv) != 3:
? ? ? ? print "pls use: python make_crf_test_data.py input output"
? ? ? ? sys.exit()
? ? input_file = sys.argv[1]
? ? output_file = sys.argv[2]
? ? character_split(input_file, output_file)

執行“python make_crf_test_data.py ./icwb2-data/testing/msr_test.utf8 msr_test4crf.utf8”即可得到可用于CRF++測試的測試語料msr_test4crf.utf8,樣例如下:

1
2
3
4
5
6
7
8
9
10
11
揚 B
帆 B
遠 B
東 B
做 B
與 B
中 B
國 B
合 B
作 B ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
...

現在執行crf_test即可得到字標注結果:

crf_test -m crf_model msr_test4crf.utf8 > msr_test4crf.tag.utf8

msr_test4crf.tag.utf8即是標注結果,樣例如下:

1
2
3
4
5
6
7
8
9
10
11
揚 B ? B
帆 B ? E
遠 B ? B
東 B ? E
做 B ? S
與 B ? S
中 B ? B
國 B ? E
合 B ? B
作 B ? E ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
...

最后我們還需要一個腳本,按標注的詞位信息講這份結果再轉化為分詞結果,這里我們仍然提供一個轉換腳本?crf_data_2_word.py?:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

def character_2_word(input_file, output_file):
? ? input_data = codecs.open(input_file, 'r', 'utf-8')
? ? output_data = codecs.open(output_file, 'w', 'utf-8')
? ? for line in input_data.readlines():
? ? ? ? if line == "\n":
? ? ? ? ? ? output_data.write("\n")
? ? ? ? else:
? ? ? ? ? ? char_tag_pair = line.strip().split('\t')
? ? ? ? ? ? char = char_tag_pair[0]
? ? ? ? ? ? tag = char_tag_pair[2]
? ? ? ? ? ? if tag == 'B':
? ? ? ? ? ? ? ? output_data.write(' ' + char)
? ? ? ? ? ? elif tag == 'M':
? ? ? ? ? ? ? ? output_data.write(char)
? ? ? ? ? ? elif tag == 'E':
? ? ? ? ? ? ? ? output_data.write(char + ' ')
? ? ? ? ? ? else: # tag == 'S'
? ? ? ? ? ? ? ? output_data.write(' ' + char + ' ')
? ? input_data.close()
? ? output_data.close()

if __name__ == '__main__':
? ? if len(sys.argv) != 3:
? ? ? ? print "pls use: python crf_data_2_word.py input output"
? ? ? ? sys.exit()
? ? input_file = sys.argv[1]
? ? output_file = sys.argv[2]
? ? character_2_word(input_file, output_file)

只需執行“python crf_data_2_word.py msr_test4crf.tag.utf8 msr_test4crf.tag2word.utf8” 即可得到合并后的分詞結果文件 msr_test4crf.tag2word.utf8,樣例如下:

1
2
3
4
5
6
7
8
9
10
11
揚帆 ?遠東 ?做 ?與 ?中國 ?合作 ?的 ?先行?
?希臘 ?的 ?經濟 ?結構 ?較 ?特殊 ?。?
?海運 ?業 ?雄踞 ?全球 ?之 ?首 ?, ?按 ?噸 ?位 ?計 ?占 ?世界 ?總數 ?的 ?17% ?。?
?另外 ?旅游 ?、 ?僑匯 ?也是 ?經濟 ?收入 ?的 ?重要 ?組成部分 ?, ?制造業 ?規模 ?相對 ?較小 ?。?
?多年來 ?, ?中 ?希 ?貿易 ?始終 ?處于 ?較低 ?的 ?水平 ?, ?希臘 ?幾乎 ?沒有 ?在 ?中國 ?投資 ?。?
?十幾年 ?來 ?, ?改革開放 ?的 ?中國 ?經濟 ?高速 ?發展 ?, ?遠東 ?在 ?崛起 ?。?
?瓦西里斯 ?的 ?船只 ?中 ?有 ?40% ?駛 ?向 ?遠東 ?, ?每個 ?月 ?幾乎 ?都 ?有 ?兩三條 ?船 ?停靠 ?中國 ?港口 ?。?
?他 ?感受 ?到 ?了 ?中國 ?經濟 ?發展 ?的 ?大潮 ?。?
?他 ?要 ?與 ?中國人 ?合作 ?。?
?他 ?來到 ?中國 ?, ?成為 ?第一個 ?訪 ?華 ?的 ?大船 ?主 ?。
?...

有了這個CRF字標注分詞結果,我們就可以利用backoff2005的測試腳本來測一下這次分詞的效果了:

./icwb2-data/scripts/score ./icwb2-data/gold/msr_training_words.utf8 ./icwb2-data/gold/msr_test_gold.utf8 msr_test4crf.tag2word.utf8 > msr_crf_segment.score

結果如下:

=== SUMMARY:
=== TOTAL INSERTIONS: 1412
=== TOTAL DELETIONS: 1305
=== TOTAL SUBSTITUTIONS: 2449
=== TOTAL NCHANGE: 5166
=== TOTAL TRUE WORD COUNT: 106873
=== TOTAL TEST WORD COUNT: 106980
=== TOTAL TRUE WORDS RECALL: 0.965
=== TOTAL TEST WORDS PRECISION: 0.964
=== F MEASURE: 0.964
=== OOV Rate: 0.026
=== OOV Recall Rate: 0.647
=== IV Recall Rate: 0.974
### msr_test4crf.tag2word.utf8 1412 1305 2449 5166 106873 106980 0.965 0.964 0.964 0.026 0.647 0.974

這次我們獲得了一個準確率,召回率以及F值都在96%以上的結果,相對于前面幾節的測試結果,這個CRF字標注分詞結果還相對不錯。不過是不是感覺上面的步驟有些繁瑣,有沒有一次到位的CRF分詞器,這里我們同樣提供一個CRF分詞腳本?crf_segmenter.py?,利用CRF++的python工具包,做到一次輸入,一次輸出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: 52nlpcn@gmail.com
# Copyright 2014 @ YuZhen Technology
#
# CRF Segmenter based character tagging:
# ? ? 4 tags for character tagging: B(Begin), E(End), M(Middle), S(Single)

import codecs
import sys

import CRFPP

def crf_segmenter(input_file, output_file, tagger):
? ? input_data = codecs.open(input_file, 'r', 'utf-8')
? ? output_data = codecs.open(output_file, 'w', 'utf-8')
? ? for line in input_data.readlines():
? ? ? ? tagger.clear()
? ? ? ? for word in line.strip():
? ? ? ? ? ? word = word.strip()
? ? ? ? ? ? if word:
? ? ? ? ? ? ? ? tagger.add((word + "\to\tB").encode('utf-8'))
? ? ? ? tagger.parse()
? ? ? ? size = tagger.size()
? ? ? ? xsize = tagger.xsize()
? ? ? ? for i in range(0, size):
? ? ? ? ? ? for j in range(0, xsize):
? ? ? ? ? ? ? ? char = tagger.x(i, j).decode('utf-8')
? ? ? ? ? ? ? ? tag = tagger.y2(i)
? ? ? ? ? ? ? ? if tag == 'B':
? ? ? ? ? ? ? ? ? ? output_data.write(' ' + char)
? ? ? ? ? ? ? ? elif tag == 'M':
? ? ? ? ? ? ? ? ? ? output_data.write(char)
? ? ? ? ? ? ? ? elif tag == 'E':
? ? ? ? ? ? ? ? ? ? output_data.write(char + ' ')
? ? ? ? ? ? ? ? else: # tag == 'S'
? ? ? ? ? ? ? ? ? ? output_data.write(' ' + char + ' ')
? ? ? ? output_data.write('\n')
? ? input_data.close()
? ? output_data.close()

if __name__ == '__main__':
? ? if len(sys.argv) != 4:
? ? ? ? print "pls use: python crf_segmenter.py model input output"
? ? ? ? sys.exit()
? ? crf_model = sys.argv[1]
? ? input_file = sys.argv[2]
? ? output_file = sys.argv[3]
? ? tagger = CRFPP.Tagger("-m " + crf_model)
? ? crf_segmenter(input_file, output_file, tagger)

只需執行“python crf_segmenter.py crf_model ./icwb2-data/testing/msr_test.utf8 msr_test.seg.utf8”即可得到與前面幾步得到的分詞結果完全一致的CRF分詞結果:msr_test.seg.utf8 。

好了,到此為止,關于字標注中文分詞的系列終于可以畫上句號了,這個系列中所舉的例子以及所提供的腳本都是toy級別的中文分詞工具,距離一個真正實用的中文分詞器還有很多路要走,不過既然路已經打開,歡迎大家和我們一起繼續探索中文分詞的奧秘。

注:原創文章,轉載請注明出處“我愛自然語言處理”:www.52nlp.cn

本文鏈接地址:http://www.52nlp.cn/中文分詞入門之字標注法4

轉載于:https://www.cnblogs.com/DjangoBlog/p/4201527.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276962.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276962.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276962.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

后臺設置 datakeynames

FormView2.DataKeyNames new String[] { "ShoppingRemarkID" }; 轉載于:https://www.cnblogs.com/Fernando/archive/2008/01/16/1041717.html

4K 海思 聯詠 芯片_老電視也有春天,換裝海美迪4K電視盒子H7 Plus

寫在前面YALL&#xff0c;大家好&#xff0c;我是老炮兒許老板。疫情進入六月逐漸好轉&#xff0c;各級各類學校相繼開學&#xff0c;年前給兒子報的托班也終于迎來了開學&#xff0c;平日里幫忙照看兒子的爺爺奶奶也終于得到了解放。現在白天有大把大把的時間來追劇看電視&…

知識付費不熱了,得到們接下來故事怎么講?

如今&#xff0c;知識付費風口已過&#xff0c;紅利期隨之在逐漸消失&#xff0c;很多知識付費的創業者也在感嘆生意難做&#xff0c;甚至有人已經開始離場。比如&#xff0c;百度音頻知識付費產品只生存了6個月&#xff0c;最后的更新時間則停在7月13日。再如&#xff0c;在分…

I'm genius,用游戲柄控制鼠標

昨天不小心把鼠標放在店里沒有帶回來&#xff0c;今天電腦就沒有鼠標了&#xff0c;用了很久的鍵盤&#xff0c;實在不爽&#xff0c;就突然發現自己有一個游戲柄&#xff0c;后來到網上查了一下怎么用游戲柄控制鼠標&#xff0c;呵呵&#xff0c;發現了一個&#xff0c;下載用…

WCF從理論到實踐(4):路在何方

本文的出發點 通過閱讀本文&#xff0c;您能了解以下知識&#xff1a; Address是什么&#xff1f; Address的組成&#xff1f; 如何在配置文件中指定Address? 如何通過編程方式設置Address? Address有什么特殊應用&#xff1f; 本文適合的讀者 適合WCF初學者&#xff…

office 2007圖標_微軟Office 365桌面版新圖標開始測試

IT之家3月1日消息 此前&#xff0c;微軟公布了全新的Office圖標&#xff0c;微軟Office 365在線網頁版在2月15日開始已經全面更新新版圖標&#xff0c;而桌面版Office 365現在也陸續開始測試新版圖標。目前微軟Office Dogfood通道上推送的開發者預覽版本已經在2月27日開始測試O…

【動態規劃BFS】相遇

這是我第一次模擬題測試點全部AC。。。 同機房的DALAO都用的BFS 然而我用的DP&#xff08;其實不會BFS&#xff09; 話不多說&#xff0c;上題&#xff01; &#xff08;灰常詳細&#xff09;DP解法&#xff1a; 重點還是狀態轉移方程式的推導 1個點i要么是后面的位置i-1往前走…

Ruby on Rails 通過代理遠程安裝

在網上查了一些資料&#xff0c;都不詳細&#xff0c;現在列出標準命令&#xff1a; 1。如果代理服務器需要認證 gem install rails --include-dependencies --http-proxy http://username:passwordproxy:port 2。如果代理服務器不需要認證 gem install rails --include-depend…

五個思路,教你如何建立金融業的數據分析管理模型

說起銀行、保險、股票投資這樣的金融行業&#xff0c;很多人都認為它們是依靠數據驅動的企業&#xff0c;畢竟大數據的誕生本來就是為了金融信息流通而服務的&#xff0c;但在我身邊很多搞證券、投資的朋友看來&#xff0c;事實卻并非如此。 真正在金融行業做數據分析的人&…

【SSH網上商城項目實戰19】訂單信息的級聯入庫以及頁面的緩存問題

購物車這一塊還剩最后兩個問題&#xff0c;就是訂單信息的級聯入庫和頁面緩存&#xff0c;這里的信息是指購物車和購物項&#xff0c;即我們將購物車的信息存入數據庫的同時&#xff0c;也存入每個購物項的信息&#xff0c;而且外鍵都關聯好&#xff0c;這涉及到了Hibernate中的…

exfat分配單元大小選多少_安防監控攝像機視角大小和鏡頭毫米數的基礎知識!...

關于選擇監控鏡頭毫米數的問題&#xff0c;雖然只有新手才有此困惑&#xff0c;但是我們還是要認真地說一說。監控視角&#xff0c;就是指監控照射的鏡頭所能覆蓋到的范圍&#xff0c;就是監控畫面所能看到的角度統稱叫監控視角。我們正常選購監控的時候&#xff0c;除了可以選…

彩信編輯器之預覽功能

html代碼 <table width"200"height"250"border"0"cellpadding"0"cellspacing"0"bgcolor"#666666"><tr><td align"center"valign"middle"><marquee id"MMScreen&qu…

java 幾個實用的小工具

1、除法運算 編程的人都知道&#xff0c;java中的“/”、“%”運算&#xff0c;其中前者為取整&#xff0c;后者取余數。那么有沒有快捷的運算方法取正常的運算結果呢&#xff1f; 查了資料&#xff0c;發現很簡單。代碼如下&#xff1a; public static String txfloat(int a,i…

處理模板頁菜單高亮

//處理模板頁菜單高亮var urlstatus false;$("#indexMenu a").each(function () {if ((location.href /).indexOf($(this).attr(href)) > -1 && $(this).attr(href) ! ) {$(this).parent().addClass(active);urlstatus true;} else {$(this).parent().…

動畫演示 Delphi 2007 IDE 功能[3] - 修改屬性

動畫劇本:添加控件后用 F11 激活 Object Inspector 窗口;可用 ↑ ↓ 選擇屬性;用 Tab 切換屬性名和屬性值;用 Tab 切換到屬性名后, 鍵入屬性名的部分字母, 可迅速定位;用 Tab 切換到屬性值后, 也可以鍵入字母選擇, 而后回車確認.Ctrl↓ 可以選擇其他控件;整個過程可以做到無鼠標…

kali怎么成為管理員_網站死鏈是什么、是怎么引起的以及死鏈對SEO優化的影響?...

網站死鏈是我們在做SEO時必不可少的一個錯誤&#xff0c;對于從事SEO行業的人員來說&#xff0c;網站死鏈最熟悉不過了&#xff0c;但是對于那些剛入SEO行業的新手來說&#xff0c;還是不太熟悉。今天我們就給大家講一下什么是網站死鏈&#xff1f;網站死鏈是怎么引起的&#x…

Map-Reduce入門

1、Map-Reduce的邏輯過程 假設我們需要處理一批有關天氣的數據&#xff0c;其格式如下&#xff1a; 按照ASCII碼存儲&#xff0c;每行一條記錄每一行字符從0開始計數&#xff0c;第15個到第18個字符為年第25個到第29個字符為溫度&#xff0c;其中第25位是符號/-006701199099999…

Java之泛型T T與T的用法

<T> T表示返回值是一個泛型&#xff0c;傳遞啥&#xff0c;就返回啥類型的數據&#xff0c;而單獨的T就是表示限制你傳遞的參數類型&#xff0c;這個案例中&#xff0c;通過一個泛型的返回方式&#xff0c;獲取每一個集合中的第一個數據&#xff0c; 通過返回值<T>…

UrlReWriter 使用經驗小結

UrlRewriter 是微軟封裝好了的一個URL重寫組件。使用它可以讓我節約很多自已開發的時間。 好了&#xff0c;開始講述我的應用經驗&#xff0c;這只是很菜鳥的經驗&#xff0c;高手就不用看了。 第一步&#xff0c;請從此下載此組件。解壓&#xff0c;把UrlRewriter.dll copy到你…

clickhouse大數據分析技術與實戰_從銷售到經營——大客戶銷售策略與實戰技術...

對于首席客戶代表而言&#xff0c;要走出困局&#xff0c;所需要大客戶銷售策略性的訓練&#xff0c;而不是像基層客戶經理的銷售技巧訓練一樣&#xff1b;新業務的學習固然重要&#xff0c;但更重要的是轉化成實戰績效。從組織變革角度&#xff0c;每次成功的業務轉型背后都意…