Comment construire un système d'extraction d'informations et de données structurées à partir d'un texte non structuré ? Quelles méthodes utilisent ce type de comportement ? Quels corpus sont adaptés à ce travail ? Est-il possible de former et d'évaluer le modèle ?
L'extraction d'informations, en particulier l'extraction d'informations structurées, peut être comparée aux enregistrements de bases de données. La relation correspondante lie les informations de données correspondantes. Pour les données non structurées telles que le langage naturel, afin d'obtenir la relation correspondante, la relation spéciale correspondant à l'entité doit être recherchée et enregistrée à l'aide de certaines structures de données telles que des chaînes et des éléments.
Par exemple : Nous avons vu le chien jaune, selon l'idée de chunking, les trois derniers mots seront divisés en NP, et le trois mots à l'intérieur Chaque mot correspond respectivement à DT/JJ/NN ; saw est divisé en VBD ; Pour les trois derniers mots, NP est le morceau (ensemble le plus grand). Pour y parvenir, vous pouvez utiliser la propre syntaxe de segmentation de NLTK, similaire aux expressions régulières, pour implémenter la segmentation de phrases.
Faites juste attention à trois points :
Chunking de base : 组块 :{组块下的子组块}
(similaire à : "NP: {<DT>?<JJ>*<NN>}"
Une telle chaîne). Et ?*+ enregistre la signification de l'expression régulière.
import nltk sentence = [('the','DT'),('little','JJ'),('yellow','JJ'),('dog','NN'),('brak','VBD')] grammer = "NP: {<DT>?<JJ>*<NN>}"cp = nltk.RegexpParser(grammer) #生成规则result = cp.parse(sentence) #进行分块print(result) result.draw() #调用matplotlib库画出来
peut définir un Gap : }<VBD|IN>+{
import nltk sentence = [('the','DT'),('little','JJ'),('yellow','JJ'),('dog','NN'),('bark','VBD'),('at','IN'),('the','DT'),('cat','NN')] grammer = """NP: {<DT>?<JJ>*<NN>} }<VBD|NN>+{ """ #加缝隙,必须保存换行符cp = nltk.RegexpParser(grammer) #生成规则result = cp.parse(sentence) #进行分块print(result)
peut être un appel récursif, conforme à l'imbrication récursive dans le langage structure. Par exemple : VP: {<NP|PP|CLAUSE>*} PP:{<NN><VP>}
. À ce stade, le paramètre RegexpParser
de la fonction loop
peut être réglé sur 2 et bouclé plusieurs fois pour éviter les omissions.
Si vous appelez print(type(result))
pour voir le type, vous constaterez qu'il s'agit de nltk.tree.Tree
. Comme son nom l’indique, il s’agit d’une structure arborescente. nltk.Tree
Peut réaliser une structure arborescente et prend en charge la technologie d'épissage, fournissant une requête de nœuds et un dessin d'arborescence.
tree1 = nltk.Tree('NP',['Alick'])print(tree1) tree2 = nltk.Tree('N',['Alick','Rabbit'])print(tree2) tree3 = nltk.Tree('S',[tree1,tree2])print(tree3.label()) #查看树的结点tree3.draw()
représentent respectivement interne, externe et début (les premières lettres des mots anglais). Pour les classifications telles que NP et NN mentionnées ci-dessus, il vous suffit d'ajouter I-/B-/O- devant. Cela permet d'exposer les collections en dehors des règles, de la même manière que pour ajouter des lacunes ci-dessus.
NLTK nous fournit déjà des chunkers, réduisant ainsi les règles de construction manuelles. Dans le même temps, il fournit également du contenu divisé en morceaux pour référence lorsque nous construisons nos propres règles.
#这段代码在python2下运行from nltk.corpus import conll2000print conll2000.chunked_sents('train.txt')[99] #查看已经分块的一个句子text = """ he /PRP/ B-NP accepted /VBD/ B-VP the DT B-NP position NN I-NP of IN B-PP vice NN B-NP chairman NN I-NP of IN B-PP Carlyle NNP B-NP Group NNP I-NP , , O a DT B-NP merchant NN I-NP banking NN I-NP concern NN I-NP . . O"""result = nltk.chunk.conllstr2tree(text,chunk_types=['NP'])
Pour les règles précédemment définies cp
, vous pouvez utiliser cp.evaluate(conll2000.chunked_sents('train.txt')[99])
pour tester l'exactitude. En utilisant le tagger Unigram que nous avons appris précédemment, nous pouvons segmenter les phrases nominales en morceaux et tester l'exactitude de la reconnaissance des entités nommées et de l'extraction des informations.
class UnigramChunker(nltk.ChunkParserI):""" 一元分块器, 该分块器可以从训练句子集中找出每个词性标注最有可能的分块标记, 然后使用这些信息进行分块 """def __init__(self, train_sents):""" 构造函数 :param train_sents: Tree对象列表 """train_data = []for sent in train_sents:# 将Tree对象转换为IOB标记列表[(word, tag, IOB-tag), ...]conlltags = nltk.chunk.tree2conlltags(sent)# 找出每个词性标注对应的IOB标记ti_list = [(t, i) for w, t, i in conlltags] train_data.append(ti_list)# 使用一元标注器进行训练self.__tagger = nltk.UnigramTagger(train_data)def parse(self, tokens):""" 对句子进行分块 :param tokens: 标注词性的单词列表 :return: Tree对象 """# 取出词性标注tags = [tag for (word, tag) in tokens]# 对词性标注进行分块标记ti_list = self.__tagger.tag(tags)# 取出IOB标记iob_tags = [iob_tag for (tag, iob_tag) in ti_list]# 组合成conll标记conlltags = [(word, pos, iob_tag) for ((word, pos), iob_tag) in zip(tokens, iob_tags)]return nltk.chunk.conlltags2tree(conlltags) test_sents = conll2000.chunked_sents("test.txt", chunk_types=["NP"]) train_sents = conll2000.chunked_sents("train.txt", chunk_types=["NP"]) unigram_chunker = UnigramChunker(train_sents)print(unigram_chunker.evaluate(test_sents))
. Si binaire est défini sur True, alors les entités nommées sont uniquement étiquetées comme NE ; sinon les balises sont un peu plus compliquées.
nltk.ne_chunk(tagged_sent[,binary=False])
Si l'entité nommée est déterminée, une
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!