美文网首页自然语言处理
自然语言处理之分词3

自然语言处理之分词3

作者: 星空慕辰 | 来源:发表于2016-05-10 12:06 被阅读539次

本节将介绍在自然语言处理分词或序列标注过程中应用较广泛的CRF条件随机场模型。

CRF算法是2001年提出,结合了最大熵模型和隐马尔科夫模型,是一个典型的判别式模型。近年来在分词、词性标注和命名实体识别等序列标注任务中取得了很好的效果。其基本思路是把分词转换为分类问题,通过给汉字打标签实现分词,不仅考虑文字词语出现的频率,同时考虑上下文语境,对歧异词和未登录词的识别效果较好,此外,对所有特征进行全局归一化,进而求得全局最优值。但是训练周期较长,计算量大,性能不如词典统计分词。本文使用开源的条件随机场工具包“CRF++:Yet Another CRF toolkit”实现中文分词,选用的训练语料是微软亚洲研究院提供的中文分词语料(如下图所示),测试语料来自backoff2005测试脚本。


上图语料来自微软亚洲研究院提供的中文分词语料

CRF分词原理:
1、训练语料预处理。原始训练语料是已经分好词的预料,词与词之间通过空格隔开。按照如下定义字对数据进行格式化:①词首——用B表示 ②词中——用M表示 ③词尾——用E表示 ④单子词——用S表示。数据格式化脚本如下:

import codecs
import sys
def character_tagging(input_file, output_file): 
    #这里的codecs库保证了输入文件为utf-8格式,输出也为utf-8格式
    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: 
            #注意这里的“\tS\n”一定不能漏写,这是设置处理之后的数据的格式的重要部分  
            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 ####.py input output" 
        sys.exit(-1) 
    #这里的sys.argv[]是参数,需要在liunx环境下运行Python脚本时,输入的两个参数:输入文件位置,输出文件位置
    input_file = sys.argv[1] 
    output_file = sys.argv[2] 
    character_tagging(input_file, output_file)

格式化之后的数据如图所示:假设格式化后的文件为training_tag.utf8


格式化处理后training_tag.utf8文件格式

2、训练模型。用格式化后的训练语料training_tag.utf8训练CRF模型。主要利用CRF工具中的crf_learn训练模型,执行如下命令:crf_learn -f 3 -c 4.0 template training_tag.utf8 crf_model。其中,crf_model即为训练过后的模型。
3、测试语料格式化。原始的测试语料是一个纯文本文件,没有任何处理,如图a所示。需要将其处理成CRF要求的输入格式,处理脚本如下所示。

图a 原始测试语料
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 ####.py input output" 
        sys.exit()    
    input_file = sys.argv[1]    
    output_file = sys.argv[2]    
    character_split(input_file, output_file)    

格式化之后的数据如图所示:假设格式化后的文件为test_format.utf8

test_format.utf8文件格式

4、测试模型。用格式化后的测试语料test_format.utf8测试CRF模型。主要利用CRF工具中的crf_test测试模型,执行如下命令:crf_test -m crf_model test_format.utf8>test_tag.utf8 。其中,crf_model即为训练过后的模型,test_format.utf8即为格式化后的测试文件,test_tag.utf8即为模型的标注结果。
5、分词结果显示。按照定义的分词格式,将标记结果转换为分词结果,即将B和E之间的字,以及S单字构成分词。脚本如下:

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 ####.py input output" 
        sys.exit()
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    character_2_word(input_file, output_file)

得到分词结果文件test_result.utf8,样式如图所示

分词结果文件test_result.utf8

6、分词结果测试。利用backoff2005测试样本对分词结果test_result.utf8进行测试。
执行./icwb2-data/scripts/score ./icwb2-data/gold/pku_training_words.utf8 ./icwb2-data/gold/pku_test_gold.utf8 test_result.utf8 > test_result.score
此处,pku_training_words.utf8 和pku_test_gold.utf8是测试文件中自带的,test_result.utf8即为上步生成的文件。test_result.score即为最后模型的评分。

上述步骤均可以复现,具体细节参考www.52nlp.cn/中文分词入门之字标注法4

相关文章

  • 中文分词工具及中文语料资源

    关键词: 中文分词;分词;自然语言处理;中文语料 最近要做中文自然语言处理相关任务,牵涉到使用中文分词工具和相关算...

  • <<数学之美>> part1

    摘要 : [自然语言处理] [基于规则] [基于统计] [统计语言模型] [马尔科夫] [分词] 自然语言处理--...

  • 自然语言处理基本流程与应用

    自然语言处理是人工智能皇冠上的明珠 自然语言处理的基本流程: 分词(Segment) 命名实体识别(NER) 词性...

  • 自然语言处理之分词3

    本节将介绍在自然语言处理分词或序列标注过程中应用较广泛的CRF条件随机场模型。 CRF算法是2001年提出,结合了...

  • python 结巴分词学习

    结巴分词(自然语言处理之中文分词器) jieba分词算法使用了基于前缀词典实现高效的词图扫描,生成句子中汉字所有可...

  • 1. jieba中文处理

    jieba中文处理 1. 中文分词 jieba是一个在中文自然语言处理中用的最多的工具包之一,它以分词起家,目前已...

  • 自然语言处理之_SentencePiece分词

    1、 说明  SentencePiece是一个google开源的自然语言处理工具包。网上是这么描述它的:数据...

  • 中文分词方法

    中文分词是中文自然语言处理的基础,现代语言分析处理算法基本是以词为单位进行计算的。 1、词典匹配 词典匹配是分词最...

  • 客服问答短文本分类实践

    本文的应用场景例子是针对短文本的。 1. 分词 分词是自然语言处理中最基础的功能,分词功能的好坏对于之后的词法分析...

  • 基于Trie 树实现简单的中文分词

    中文分词简介 中文分词是中文自然语言处理的基础,中文分词的正确率如何直接影响后续的词性标注(也有些词性标注算法不需...

网友评论

    本文标题:自然语言处理之分词3

    本文链接:https://www.haomeiwen.com/subject/zmqyrttx.html