<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          NLP(四十)利用seqeval模塊獲取序列實(shí)體識(shí)別結(jié)果

          共 11897字,需瀏覽 24分鐘

           ·

          2021-03-06 18:13

          ??在文章NLP(二十三)序列標(biāo)注算法評(píng)估模塊seqeval的使用中,筆者首次介紹了seqeval模塊,它可以幫助我們很好地完成序列標(biāo)注算法的模型效果評(píng)估,并且能在Keras模型訓(xùn)練過(guò)程中引入。
          ??其實(shí),在seqeval模塊中還有一個(gè)get_entities函數(shù),它能幫助我們迅速地從一個(gè)標(biāo)注序列中獲取完整實(shí)體,支持常規(guī)的BIO、BMESO等標(biāo)注方式。讓我們來(lái)看下該函數(shù)的源代碼:

          def get_entities(seq, suffix=False):
              """Gets entities from sequence.

              Args:
                  seq (list): sequence of labels.

              Returns:
                  list: list of (chunk_type, chunk_start, chunk_end).

              Example:
                  >>> from seqeval.metrics.sequence_labeling import get_entities
                  >>> seq = ['B-PER', 'I-PER', 'O', 'B-LOC']
                  >>> get_entities(seq)
                  [('PER', 0, 1), ('LOC', 3, 3)]
              """

              # for nested list
              if any(isinstance(s, list) for s in seq):
                  seq = [item for sublist in seq for item in sublist + ['O']]

              prev_tag = 'O'
              prev_type = ''
              begin_offset = 0
              chunks = []
              for i, chunk in enumerate(seq + ['O']):
                  if suffix:
                      tag = chunk[-1]
                      type_ = chunk.split('-')[0]
                  else:
                      tag = chunk[0]
                      type_ = chunk.split('-')[-1]

                  if end_of_chunk(prev_tag, tag, prev_type, type_):
                      chunks.append((prev_type, begin_offset, i-1))
                  if start_of_chunk(prev_tag, tag, prev_type, type_):
                      begin_offset = i
                  prev_tag = tag
                  prev_type = type_

              return chunks

          該函數(shù)的輸入為標(biāo)注序列,輸出結(jié)果為實(shí)體列表,包含實(shí)體類型、實(shí)體開(kāi)始下標(biāo)和結(jié)束下標(biāo)。
          ??我們以文章NLP入門(六)pyltp的介紹與使用中的命名實(shí)體識(shí)別程序?yàn)槔?,同時(shí)采用自己提取標(biāo)注序列中的實(shí)體識(shí)別信息和使用seqeval模塊提取標(biāo)注序列中的實(shí)體識(shí)別信息兩種方式,實(shí)現(xiàn)代碼如下:

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

          import os
          from pyltp import Segmentor, Postagger

          # 分詞
          cws_model_path = os.path.join(os.path.dirname(__file__), 'ltp_v3.4/cws.model')  # 分詞模型路徑,模型名稱為`cws.model`
          lexicon_path = os.path.join(os.path.dirname(__file__), 'ltp_v3.4/lexicon.txt')  # 參數(shù)lexicon是自定義詞典的文件路徑

          segmentor = Segmentor()
          segmentor.load_with_lexicon(cws_model_path, lexicon_path)

          sent = "據(jù)韓聯(lián)社12月28日反映,美國(guó)防部發(fā)言人杰夫·莫萊爾27日表示,美國(guó)防部長(zhǎng)蓋茨將于2011年1月14日訪問(wèn)韓國(guó)。"
          # sent = "記者4日從中國(guó)航空工業(yè)集團(tuán)有限公司獲悉,AG600項(xiàng)目研制加速推進(jìn),001架機(jī)在成功完成陸上、水上、海上首飛之后,于3月4日在湖北荊門漳河機(jī)場(chǎng)完成滅火任務(wù)系統(tǒng)首次科研試飛,飛機(jī)狀態(tài)良好。"
          # sent = "大臨鐵路通車當(dāng)天,81歲的佤族老人田學(xué)明專程趕到臨滄站,觀看列車發(fā)車?!拔易畲蟮膲?mèng)想,就是有一天火車能開(kāi)進(jìn)阿佤山。今天,我的夢(mèng)想終于實(shí)現(xiàn)了!”"
          words = segmentor.segment(sent)  # 分詞

          # 詞性標(biāo)注
          pos_model_path = os.path.join(os.path.dirname(__file__), 'ltp_v3.4/pos.model')  # 詞性標(biāo)注模型路徑,模型名稱為`pos.model`

          postagger = Postagger()  # 初始化實(shí)例
          postagger.load(pos_model_path)  # 加載模型
          postags = postagger.postag(words)  # 詞性標(biāo)注


          ner_model_path = os.path.join(os.path.dirname(__file__), 'ltp_v3.4/ner.model')   # 命名實(shí)體識(shí)別模型路徑,模型名稱為`pos.model`

          from pyltp import NamedEntityRecognizer
          recognizer = NamedEntityRecognizer() # 初始化實(shí)例
          recognizer.load(ner_model_path)  # 加載模型
          netags = list(recognizer.recognize(words, postags))  # 命名實(shí)體識(shí)別
          print(list(words))
          print(netags)

          # 用自己的方法提取識(shí)別結(jié)果中的人名,地名,組織機(jī)構(gòu)名
          persons, places, orgs = set(), set(), set()
          i = 0
          for tag, word in zip(netags, words):
              j = i
              # 人名
              if 'Nh' in tag:
                  if str(tag).startswith('S'):
                      persons.add(word)
                  elif str(tag).startswith('B'):
                      union_person = word
                      while netags[j] != 'E-Nh':
                          j += 1
                          if j < len(words):
                              union_person += words[j]
                      persons.add(union_person)
              # 地名
              if 'Ns' in tag:
                  if str(tag).startswith('S'):
                      places.add(word)
                  elif str(tag).startswith('B'):
                      union_place = word
                      while netags[j] != 'E-Ns':
                          j += 1
                          if j < len(words):
                              union_place += words[j]
                      places.add(union_place)
              # 機(jī)構(gòu)名
              if 'Ni' in tag:
                  if str(tag).startswith('S'):
                      orgs.add(word)
                  elif str(tag).startswith('B'):
                      union_org = word
                      while netags[j] != 'E-Ni':
                          j += 1
                          if j < len(words):
                              union_org += words[j]
                      orgs.add(union_org)

              i += 1

          print('人名:'','.join(persons))
          print('地名:'','.join(places))
          print('組織機(jī)構(gòu):'','.join(orgs))

          # 用seqeval提取識(shí)別結(jié)果中的人名,地名,組織機(jī)構(gòu)名
          from seqeval.metrics.sequence_labeling import get_entities
          from collections import defaultdict
          seq_result = get_entities(netags)
          words = list(words)
          ner_result_dict = defaultdict(list)
          for seq_res in seq_result:
              ner_result_dict[seq_res[0]].append("".join(words[seq_res[1]:seq_res[2]+1]))
          print('人名:', ner_result_dict["Nh"])
          print('地名:', ner_result_dict["Ns"])
          print('組織機(jī)構(gòu):', ner_result_dict["Ni"])

          # 釋放模型
          segmentor.release()
          postagger.release()
          recognizer.release()

          輸出結(jié)果如下:

          ['據(jù)''韓聯(lián)社''12月''28日''反映'',''美''國(guó)防部''發(fā)言人''杰夫·莫萊爾''27日''表示'',''美''國(guó)防部長(zhǎng)''蓋茨''將''于''2011年''1月''14日''訪問(wèn)''韓國(guó)''。']
          ['O''S-Ni''O''O''O''O''B-Ni''E-Ni''O''S-Nh''O''O''O''S-Ns''O''S-Nh''O''O''O''O''O''O''S-Ns''O']
          人名: 蓋茨,杰夫·莫萊爾
          地名: 韓國(guó),美
          組織機(jī)構(gòu): 美國(guó)防部,韓聯(lián)社
          人名: ['杰夫·莫萊爾''蓋茨']
          地名: ['美''韓國(guó)']
          組織機(jī)構(gòu): ['韓聯(lián)社''美國(guó)防部']

          我們?cè)賴L試兩個(gè)句子,識(shí)別結(jié)果如下:

          ['記者''4日''從''中國(guó)''航空''工業(yè)''集團(tuán)''有限公司''獲悉'',''AG600''項(xiàng)目''研制''加速''推進(jìn)'',''001架機(jī)''在''成功''完成''陸上''、''水上''、''海上''首''飛''之后'',''于''3月''4日''在''湖北''荊門''漳河''機(jī)場(chǎng)''完成''滅火''任務(wù)''系統(tǒng)''首''次''科研''試飛'',''飛機(jī)''狀態(tài)''良好''。']
          ['O''O''O''B-Ni''I-Ni''I-Ni''I-Ni''E-Ni''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''B-Ns''I-Ns''I-Ns''E-Ns''O''O''O''O''O''O''O''O''O''O''O''O''O']
          人名: 
          地名: 湖北荊門漳河機(jī)場(chǎng)
          組織機(jī)構(gòu): 中國(guó)航空工業(yè)集團(tuán)有限公司
          人名: []
          地名: ['湖北荊門漳河機(jī)場(chǎng)']
          組織機(jī)構(gòu): ['中國(guó)航空工業(yè)集團(tuán)有限公司']
          ['大臨鐵路''通車''當(dāng)天'',''81''歲''的''佤族''老人''田學(xué)明''專程''趕到''臨滄站'',''觀看''列車''發(fā)車''。''“''我''最''大''的''夢(mèng)想'',''就''是''有''一''天''火車''能''開(kāi)進(jìn)''阿佤山''。''今天'',''我''的''夢(mèng)想''終于''實(shí)現(xiàn)''了''!''”']
          ['O''O''O''O''O''O''O''O''O''S-Nh''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''O''S-Ns''O''O''O''O''O''O''O''O''O''O''O']
          人名: 田學(xué)明
          地名: 阿佤山
          組織機(jī)構(gòu): 
          人名: ['田學(xué)明']
          地名: ['阿佤山']
          組織機(jī)構(gòu): []

          從上我們可以發(fā)現(xiàn):

          • 使用seqeval的實(shí)現(xiàn)方式與自己的實(shí)現(xiàn)方式效果一致;

          • seqeval的實(shí)現(xiàn)方式更加簡(jiǎn)潔高效,從代碼上看,seqeval只需3-4行代碼,而自己實(shí)現(xiàn)需20-30行代碼。

          ??本文介紹了如何使用seqeval模塊快速地從標(biāo)注序列中提取實(shí)體識(shí)別結(jié)果,這是我們?cè)谧雒麑?shí)體識(shí)別任務(wù)時(shí)經(jīng)常會(huì)碰到的問(wèn)題,使用seqeval能夠提升我們的工作效果,使代碼更加簡(jiǎn)潔優(yōu)雅。
          ??本次分享到此結(jié)束,感謝大家閱讀~
          ??2021年3月5日于上海楊浦


          瀏覽 111
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费TV | 黄色片在线观看免费 | 国内aV免费 | 男人的天堂视频网站 | 色五月婷婷综合 |