美文网首页
实体识别-0

实体识别-0

作者: China空鸟 | 来源:发表于2021-01-06 10:16 被阅读0次

    实体识别的领域是建筑领域,处理的文本是《地铁设计规范》,2014 年 3 月 1 日开始施行的。
    参考的基准代码是https://github.com/Determined22/zh-NER-TF,该源码设计的模型,参考的论文是这两篇,Bidirectional LSTM-CRF Models for Sequence Tagging
    Neural Architectures for Named Entity Recognition
    (注:但是目前写这一篇时,尚未将代码和论文模型进行比对)
    现将所更改的一些内容,进行记录。
    1.因为我的实体类别粗粒度分为6类,细粒度分为18类,因此默认写死的tag2lable显得不太灵活

    tag2label.png
    并且对应于字编号,我将这一变量更名为tag2id,同时因为字编号的使用方式是写入文件,由使用方进行读取使用,所以tag2id也写入文件,分开两个文件写(TODO:可以写入同一个文件,参考ChineseNER这个代码的写法)
    代码位置:data.py/vocab_build
    def vocab_build(vocab_dir, corpus_path, min_count):
        """
    
        :param vocab_dir:
        :param corpus_path:
        :param min_count:
        :return:
        """
        data = read_corpus(corpus_path)
        # word2id筛选掉不满足字频的字,将其他字进行编号,并把英文用<ENG>,数字用<NUM>,然后再给未来没有在字典中的字留一个<UNK>
        # 用<UNK>来代替,把不满足统一句子长度的句子用<PAD>进行填充,形成这样子的一个字典;其中<PAD>编号为0,<UNK>为最大编号
        # word2id = {'<PAD>': 0, '': , '': , .. '<ENG>': , '': , ..  '<NUM>': , '': , ..  '<UNK>': }
        word2id = {}
        tag2id = {}
        tag_id = 0
        for sent_, tag_ in data:
            for word in sent_:
                if word.isdigit():
                    word = '<NUM>'
                # A-Z, a-z
                elif ('\u0041' <= word <='\u005a') or ('\u0061' <= word <='\u007a'):
                    word = '<ENG>'
                if word not in word2id:
                    word2id[word] = [len(word2id)+1, 1]
                else:
                    word2id[word][1] += 1
    
            for tag in tag_:
                if tag not in tag2id:
                    tag2id[tag] = tag_id
                    tag_id += 1
        low_freq_words = []
        for word, [word_id, word_freq] in word2id.items(): # 其实这个word_id真的没用到,表示字加入字典时的序号
            if word_freq < min_count and word != '<NUM>' and word != '<ENG>':
                low_freq_words.append(word)
        for word in low_freq_words:
            del word2id[word]
    
        # 后面修改一下按照字频去编号,这个也是参考https://github.com/zjy-ucas/ChineseNER
        new_id = 1
        for word in word2id.keys():
            word2id[word] = new_id
            new_id += 1
        word2id['<UNK>'] = new_id # 查找表中没有对应的自嵌入,被替换成UNK,使用UNK对应的嵌入
        word2id['<PAD>'] = 0 # 为了保证每个batch句子长度一致,用PAD对应嵌入填充句子
    
        # print(len(word2id))
        word_vocab_path = os.path.join(vocab_dir, 'word2id.pkl')
        with open(word_vocab_path, 'wb') as fw:
            pickle.dump(word2id, fw) # 将对象写入打开的文件中,二进制;反序列化load()
    
        tag_vocab_path = os.path.join(vocab_dir, 'tag2id.pkl')
        with open(tag_vocab_path, 'wb') as fw:
            pickle.dump(tag2id, fw)
    

    2.适应tag2id和word2id的使用方式
    原有main.py中,只读取word2id,因为tag2id是写死的,如下图


    读取word2id.png

    改为


    i读取word2id和tag2id.png
    对应这个参数是文件夹,因此,将data.py/read_dictionary修改如下
    def read_dictionary(vocab_dir):
        """
        读取字典文件
        :param vocab_path:
        :return:
        """
        word_vocab_path = os.path.join(vocab_dir, 'word2id.pkl')
        with open(word_vocab_path, 'rb') as fr:
            word2id = pickle.load(fr)
        print('vocab_size:', len(word2id))
        tag_vocab_path = os.path.join(vocab_dir, 'tag2id.pkl')
        with open(tag_vocab_path, 'rb') as fr:
            tag2id = pickle.load(fr)
        print('vocab_size:', len(tag2id))
        return word2id, tag2id
    

    3.在这个预处理得到字编号的过程中,将不满足字频的字进行了删除,具体逻辑在data.py/vocab_build,字频限制使用min_count这个变量,对了,在开始训练前,需要先得到字编号和标签编号,因此首先需要在data.py中,我首先设置的词频是3,这个后面也可以作为要调的一个参数

    if __name__ == '__main__':
        '''
        vocab_dir = 'data_path/rail_data18'
        corpus_path = 'data_path/rail_data18/train_data'
        '''
        vocab_dir = 'data_path/rail_data6'
        corpus_path = 'data_path/rail_data6/train_data'
        min_count = 3
        vocab_build(vocab_dir, corpus_path, min_count)
        word2id, tag2id = read_dictionary(vocab_dir)
        print(word2id)
        print(tag2id)
    

    4.将结果写入部分,进行了改动,源码中是unicode了,改为不进行编码

    not encode.png
    5.main.py中将训练数据的默认路径进行修改,如图
    数据文件默认位置.png
    源代码中是将测试数据用作验证用,但我有构造出验证数据,因此使用验证数据进行验证
    dev_test1.png
    dev_test2.png
    6.添加perl语言的解析环境
    windows
    activeperl官网下载安装,命令行perl -v检查安装成功,但是需要重启电脑才能被识别到
    linux
    检查是否已经安装:perl -v,没有直接用rpm安装就可以了
    7.将数据集放入相应的位置,就可以跑起来代码了
    训练命令:python main.py --mode=train
    测试命令:python main.py --mode=test --demo_model=1608281271(后面那个数字为训练的模型)

    相关文章

      网友评论

          本文标题:实体识别-0

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