學(xué)習(xí)整理---中文分詞

首先找爱,談一下這個(gè)概念是怎么走進(jìn)我的腦袋的惯驼。要解決的問題是清蚀,土木專業(yè)有一些專業(yè)學(xué)術(shù)的文檔需要根據(jù)一些特殊的實(shí)體進(jìn)行標(biāo)注匕荸,以前都是一些老師傅或者前輩人工進(jìn)行工作,這樣費(fèi)人費(fèi)力枷邪,并且人非圣賢孰能無過榛搔。所以,我們作為計(jì)算機(jī)一員东揣,伸出了橄欖枝践惑,希望通過計(jì)算機(jī)最大程度地正確快速進(jìn)行實(shí)體標(biāo)注。一開始嘶卧,需求提出尔觉,我們就開始尋找匹配算法,網(wǎng)絡(luò)資源雖然很多芥吟,但是并不知道怎么去查找侦铜。過程不細(xì)說专甩,之后我莫名地就進(jìn)入了CRF算法的了解與學(xué)習(xí)中。

CRF的使用場(chǎng)景:
假設(shè)你有許多小明同學(xué)一天內(nèi)不同時(shí)段的照片钉稍,從小明提褲子起床到脫褲子睡覺各個(gè)時(shí)間段都有(小明是照片控5佣恪)。現(xiàn)在的任務(wù)是對(duì)這些照片進(jìn)行分類嫁盲。比如有的照片是吃飯篓叶,那就給它打上吃飯的標(biāo)簽;有的照片是跑步時(shí)拍的羞秤,那就打上跑步的標(biāo)簽缸托;有的照片是開會(huì)時(shí)拍的,那就打上開會(huì)的標(biāo)簽瘾蛋。問題來了俐镐,你準(zhǔn)備怎么干?一個(gè)簡(jiǎn)單直觀的辦法就是哺哼,不管這些照片之間的時(shí)間順序佩抹,想辦法訓(xùn)練出一個(gè)多元分類器。就是用一些打好標(biāo)簽的照片作為訓(xùn)練數(shù)據(jù)取董,訓(xùn)練出一個(gè)模型棍苹,直接根據(jù)照片的特征來分類。例如茵汰,如果照片是早上6:00拍的枢里,且畫面是黑暗的,那就給它打上睡覺的標(biāo)簽;如果照片上有車蹂午,那就給它打上開車的標(biāo)簽栏豺。這樣可行嗎?乍一看可以豆胸!但實(shí)際上奥洼,由于我們忽略了這些照片之間的時(shí)間順序這一重要信息,或者說晚胡,照片之間的一些聯(lián)系灵奖。我們的分類器會(huì)有缺陷的。舉個(gè)例子搬泥,假如有一張小明閉著嘴的照片桑寨,怎么分類?顯然難以直接判斷忿檩,需要參考閉嘴之前的照片尉尾,如果之前的照片顯示小明在吃飯,那這個(gè)閉嘴的照片很可能是小明在咀嚼食物準(zhǔn)備下咽燥透,可以給它打上吃飯的標(biāo)簽沙咏;如果之前的照片顯示小明在唱歌辨图,那這個(gè)閉嘴的照片很可能是小明唱歌瞬間的抓拍,可以給它打上唱歌的標(biāo)簽肢藐。所以故河,為了讓我們的分類器能夠有更好的表現(xiàn),在為一張照片分類時(shí)吆豹,我們必須將與它相鄰的照片的標(biāo)簽信息考慮進(jìn)來鱼的。這——就是條件隨機(jī)場(chǎng)(CRF)大顯身手的地方!
(注:示例摘自:https://www.zhihu.com/question/35866596/answer/139485548

分析:先補(bǔ)充一下痘煤,我們整個(gè)設(shè)計(jì)過程中擁有的輸入凑阶,一份需要標(biāo)注的doc文檔;一份xlsx格式的實(shí)體庫衷快。那么宙橱,結(jié)合示例和我們擁有的輸入分析,CRF算法是需要一個(gè)訓(xùn)練模型的蘸拔,也就是說要使用CRF算法實(shí)現(xiàn)分詞师郑,必須有一個(gè)訓(xùn)練模型作為輸入,這個(gè)訓(xùn)練模型說的通俗點(diǎn)调窍,就是經(jīng)過可以確定的一些相互關(guān)系實(shí)現(xiàn)了分詞的文檔宝冕。但是我們的輸入,與訓(xùn)練模型概念相匹配的就是那個(gè)xlsx格式的實(shí)體庫邓萨,但是這個(gè)實(shí)體庫只是一些沒有相互關(guān)系的詞組猬仁,是一個(gè)個(gè)邏輯上沒有聯(lián)系的個(gè)體,所以我們無法將它作為訓(xùn)練模型先誉。

小結(jié)一下:講了這么多,是因?yàn)橄胝f明的烁,從實(shí)現(xiàn)分詞的角度上褐耳,CRF這個(gè)基于統(tǒng)計(jì)以及機(jī)器學(xué)習(xí)的分詞方法,或許在準(zhǔn)確度或者更多的方面要優(yōu)于其他算法渴庆。但是我們要追求铃芦,對(duì)癥下藥。

下面描述一下網(wǎng)上我最接收的中文分詞算法的分類
中文分詞算法大概分為三大類襟雷,第一類是基于字符串匹配刃滓,即掃描字符串,如果發(fā)現(xiàn)字符串的子串和詞典中的詞相同耸弄,就算匹配咧虎,比如機(jī)械分詞方法。這類分詞通常會(huì)加入一些啟發(fā)式規(guī)則计呈,比如“正向/反向最大匹配”砰诵,“長(zhǎng)詞優(yōu)先”等征唬。第二類是基于統(tǒng)計(jì)以及機(jī)器學(xué)習(xí)的分詞方法,它們基于人工標(biāo)注的詞性和統(tǒng)計(jì)特征茁彭,對(duì)中文進(jìn)行建模总寒,即根據(jù)觀測(cè)到的數(shù)據(jù)(標(biāo)注好的語料)對(duì)模型參數(shù)進(jìn)行訓(xùn)練,在分詞階段再通過模型計(jì)算各種分詞出現(xiàn)的概率理肺,將概率最大的分詞結(jié)果作為最終結(jié)果摄闸。常見的序列標(biāo)注模型有HMM和CRF。這類分詞算法能很好處理歧義和未登錄詞問題妹萨,效果比前一類效果好年枕,但是需要大量的人工標(biāo)注數(shù)據(jù),以及較慢的分詞速度眠副。第三類是通過讓計(jì)算機(jī)模擬人對(duì)句子的理解画切,達(dá)到識(shí)別詞的效果,由于漢語語義的復(fù)雜性囱怕,難以將各種語言信息組織成機(jī)器能夠識(shí)別的形式霍弹,目前這種分詞系統(tǒng)還處于試驗(yàn)階段。

由此可以看來娃弓,問題的解決辦法趨向于使用機(jī)械分詞的算法典格,即這中間最簡(jiǎn)單的正逆向匹配算法。這個(gè)網(wǎng)上也有各種語言的實(shí)現(xiàn)過程台丛,異曲同工耍缴。

正向最大匹配算法(MM):按照人得而自然閱讀順序從左往右對(duì)一段話甚至文章進(jìn)行詞庫匹配切分。
設(shè)MaxLen為最大詞長(zhǎng),D為分詞詞典
(1)從待切分語料中按正向取長(zhǎng)度為MaxLen的字符串str挽霉,令Len =MaxLen防嗡;
(2)將str與D中的詞語互相匹配;
(3)if匹配成功侠坎,將指針向前移Len個(gè)漢字蚁趁,并返回到(1);
(4)if 不成功:
    if( Len>1):
      Len = Len-1实胸;
      從待切分語料中取長(zhǎng)度為L(zhǎng)en的字符串str他嫡,并返回(2);
    else:
      得到單個(gè)漢字庐完,指針向前移一個(gè)漢字钢属,并返回(1)
逆向最大匹配算法(RMM):主要原理與正向最大匹配算法一致,只是切分方向相反门躯,從文章的尾部開始匹配淆党。
(注:這不是我總結(jié)的_,來源也是一篇博客,看的多了宁否,源地址一時(shí)找不到了...)

下面放出我的實(shí)現(xiàn)代碼
match_result.py(正向匹配)

# -*- coding: utf-8 -*-


import xlrd # 處理xlsx文件
import codecs
from win32com import client # 處理word文檔
import sys


# 打開xlsx文件
def open_excel(file_name):
    try:
        data = xlrd.open_workbook(file_name)
        print("[data]:", data)
        return data
    except (Exception, e):
        print(e)
    return False


# 解析xlsx文件中的內(nèi)容
def excel_table_byindex(file_name, colnameindex=0, by_index=0):
    try:
        data = open_excel(file_name)
    except:
        return False
    if not data:
        return False
    table = data.sheets()[by_index]
    #print("[table]:", table)
    nrows = table.nrows # 行數(shù)
    print("[nrows]:", nrows)
    colnames = table.row_values(colnameindex) # 第一行數(shù)據(jù)(表頭)
    #print("[colnames]:", colnames)
    ret_list = []
    for rownum in range(1, nrows):  # 對(duì)于表中的一行進(jìn)行操作
        row = table.row_values(rownum)  # 一行的數(shù)據(jù)
        max_len = 0
        for item in row:
            item_no_blank = item.strip()
            if len(item_no_blank) > max_len:
                max_len = len(item_no_blank)
            ret_list.append(item_no_blank)
    return ret_list,max_len


# 進(jìn)行匹配
# 這里有個(gè)坑解決了好長(zhǎng)時(shí)間,temp.txt是本目錄下的窒升,但是win32這個(gè)模塊在使用的時(shí)候必須
# 要寫全路徑,不然報(bào)錯(cuò):File "<COMObject <unknown>>", line 8, in Open
def match_result(input_file, output_file, word_dict, max_len):
    word = client.Dispatch('Word.Application')
    input_data = word.Documents.Open(input_file)
    input_data.SaveAs(r"C:\Users\Maria\Desktop\研究生資料\正向匹配\temp.txt", 4)
    temp_file = open("temp.txt", "r")
    txt_content = temp_file.read()
    data_len = len(txt_content)
    temp_file.close()
    input_data.Close()
    word.Quit()
    word_list = ""
    cur = 0
    while cur < data_len:
        data = None
        for data in range(max_len, 0, -1):
            if txt_content[cur: cur+data] in word_dict:
                word_list += txt_content[cur: cur+data] + "/"
                break
        cur += data
    output_data = open(output_file, "w")
    output_data.write(word_list)
    output_data.close()


if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Usage:Need two arguments!")
        sys.exit()
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    data,max_len = excel_table_byindex("實(shí)體庫.xlsx")
    #print(data)
    match_result(input_file, output_file, data, max_len)


逆向匹配
reverse_match_result.py

def reverse_match_result(input_file, output_file, word_dict, max_len):
    word = client.Dispatch('Word.Application')
    input_data = word.Documents.Open(input_file)
    input_data.SaveAs(r"C:\Users\Maria\Desktop\研究生資料\正向匹配\temp.txt", 4)
    temp_file = open("temp.txt", "r")
    txt_content = temp_file.read()
    data_len = len(txt_content)
    temp_file.close()
    input_data.Close()
    word.Quit()
    word_list = []
    cur = data_len
    while cur > 0:
        data = None
        if max_len > cur:
            max_len = cur
        for data in range(max_len, 0, -1):
            if txt_content[cur-data: cur] in word_dict:
                word_list.insert(0, str(txt_content[cur-data: cur]) + "/")
                break
        cur -= data
    output_data = open(output_file, "w")
    output_data.write("".join(word_list))
    output_data.close()

注:兩點(diǎn),1.正逆向匹配算法簡(jiǎn)單說起來就是字符串匹配,一種很機(jī)械化地分詞方式歇僧,所以只是在于編寫代碼的語言相應(yīng)代碼的多少和使用的數(shù)據(jù)結(jié)構(gòu)上有的選胆筒,或者一些程度上的優(yōu)化。2.代碼實(shí)現(xiàn)過程中可能有些繁瑣,希望提出意見。

最后,雖然CRF算法直接使用有點(diǎn)不太合適酪呻,但是,優(yōu)先在待分析字符串中識(shí)別和切分出一些帶有明顯特征的詞,以這些詞作為斷點(diǎn),可將原字符串分為較小的串再來進(jìn)機(jī)械分詞盐须,從而減少匹配的錯(cuò)誤率玩荠,這也是一個(gè)不錯(cuò)的選擇,只不過這樣的話贼邓,我們就需要有一個(gè)這個(gè)行業(yè)的訓(xùn)練模型了阶冈。

這是CRF算法中可以下載的一些訓(xùn)練模型(我自己的騰訊云服務(wù)器沒有實(shí)現(xiàn)訓(xùn)練,可能是內(nèi)存的關(guān)系吧塑径,對(duì)于CRF的使用女坑,網(wǎng)上有很多教程,搜索即可统舀。)
下載中文分詞語料庫地址:http://sighan.cs.uchicago.edu/bakeoff2005/匆骗,語料來自:
臺(tái)灣中央研究院(Academia Sinica)、香港城市大學(xué)(City University of Hong Kong)誉简、北京大學(xué)(Peking University)及微軟亞洲研究院(Microsoft Research)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碉就,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子闷串,更是在濱河造成了極大的恐慌铝噩,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窿克,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡毛甲,警方通過查閱死者的電腦和手機(jī)年叮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玻募,“玉大人只损,你說我怎么就攤上這事。” “怎么了跃惫?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵叮叹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我爆存,道長(zhǎng)蛉顽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任先较,我火速辦了婚禮携冤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闲勺。我一直安慰自己曾棕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布菜循。 她就那樣靜靜地躺著翘地,像睡著了一般。 火紅的嫁衣襯著肌膚如雪癌幕。 梳的紋絲不亂的頭發(fā)上衙耕,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音序芦,去河邊找鬼臭杰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谚中,可吹牛的內(nèi)容都是我干的渴杆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宪塔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼磁奖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起某筐,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤比搭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后南誊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體身诺,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年抄囚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霉赡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡幔托,死狀恐怖穴亏,靈堂內(nèi)的尸體忽然破棺而出蜂挪,到底是詐尸還是另有隱情,我是刑警寧澤嗓化,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布棠涮,位于F島的核電站,受9級(jí)特大地震影響刺覆,放射性物質(zhì)發(fā)生泄漏严肪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一隅津、第九天 我趴在偏房一處隱蔽的房頂上張望诬垂。 院中可真熱鬧,春花似錦伦仍、人聲如沸结窘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隧枫。三九已至,卻和暖如春谓苟,著一層夾襖步出監(jiān)牢的瞬間官脓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工涝焙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卑笨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓仑撞,卻偏偏與公主長(zhǎng)得像赤兴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子隧哮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容