非構造化テキストから構造化情報とデータを抽出するシステムを構築するにはどうすればよいですか?この種の動作を使用するメソッドは何ですか?この作業にはどのコーパスが適していますか?モデルをトレーニングして評価することは可能ですか?
情報抽出、特に構造化情報抽出は、データベース レコードと比較できます。対応関係は、対応するデータ情報を結び付ける。自然言語などの非構造化データの場合、対応関係を取得するには、文字列や要素などのデータ構造を利用して、エンティティに対応する特殊な関係を検索して記録する必要があります。
例: 黄色い犬を見た、ブロックのアイデアに従って、最後の 3 つの単語が NP に分割され、その中の 3 つの単語が DT/JJ/NN に対応します。それぞれ、saw は VBD に割り当てられ、We は NP に割り当てられます。最後の 3 ワードの場合、NP はチャンク (より大きなセット) です。これを実現するには、正規表現と同様に、NLTK 独自のチャンク構文を使用して文のチャンク化を実装できます。
チャンク構文の構築次の 3 つの点に注意してください: チャンク: {チャンクの下のサブチャンク}
(次と同様: "NP: {<DT>?<JJ>*<NN>}"
のような文字列)。また、?*+ は正規表現の意味を保存します。
组块 :{组块下的子组块}
(类似于:"NP: {<DT>?<JJ>*<NN>}"
这样的字符串)。而?*+保存了正则表达式的意义。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库画出来
可以为不包括再大块中的标识符序列定义一个缝隙:}<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)
可以递归式的调用,这符合语言结构中的递归嵌套。例如:VP: {<NP|PP|CLAUSE>*} PP:{<NN><VP>}
。此时,RegexpParser
函数的参数loop
即可以设置为2,多次循环,来防止遗漏。
如果调用print(type(result))
查看类型就会发现,是 nltk.tree.Tree
。从名字看出来这是一种树状结构。nltk.Tree
可以实现树状结构,并且支持拼接技术,提供结点的查询和树的绘制。
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()
分别代表内部,外部,开始(就是英语单词的首字母)。对于上面讲的 NP,NN这样的分类,只需要在前面加上 I-/B-/O-即可。这样就能使规则外的集合被显式出来,类似上面的加缝隙。
NLTK已经为我们提供了分块器,减少了手动构建规则。同时,也提供了已经分块好的内容,供我们自己构建规则时候进行参考。
#这段代码在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'])
对于之前自己定义的规则cp
,可以使用cp.evaluate(conll2000.chunked_sents('train.txt')[99])
来测试正确率。利用之前学过的Unigram标注器,可以进行名词短语分块,并且测试准确度
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))
命名实体:确切的名词短语,指特定类型的个体,如日期、人、组织等 。如果自己去许梿分类器肯定头大(ˉ▽ ̄~)~~。NLTK提供了一个训练好的分类器--nltk.ne_chunk(tagged_sent[,binary=False])
sent = nltk.corpus.treebank.tagged_sents()[22]print(nltk.ne_chunk(sent,binary=True))
より大きなチャンクに含まれない識別子のシーケンスに対して ギャップ を定義することが可能です: }<VBD|IN>+ {</ code></p></li></ul><div class="sourceCode"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="sourceCode python">#请在Python2下运行import re
IN = re.compile(r&#39;.*\bin\b(?!\b.+ing)&#39;)for doc in nltk.corpus.ieer.parsed_docs(&#39;NYT_19980315&#39;):for rel in nltk.sem.extract_rels(&#39;ORG&#39;,&#39;LOC&#39;,doc,corpus=&#39;ieer&#39;,pattern = IN):print nltk.sem.show_raw_rtuple(rel)</pre><div class="contentsignin">ログイン後にコピー</div></div></div>
<p></p>🎜🎜🎜🎜は再帰的に呼び出すことができます。これは、言語構造の再帰的な入れ子に沿っています。例: <code>VP: {<np>*} PP:{<nn>gt;<vp>}</vp></nn></np>
。このとき、RegexpParser
関数のパラメータ loop
を 2 に設定し、複数回ループすることで抜けを防ぐことができます。 🎜🎜ツリー図🎜🎜 print(type(result))
を呼び出してタイプを表示すると、それが nltk.tree.Tree であることがわかります。
。名前からもわかるように、木のような構造になっています。 nltk.Tree
はツリー構造を実現し、スプライシング技術をサポートし、ノード クエリとツリー描画を提供します。 🎜🎜rrreee🎜🎜🎜🎜🎜IOBマーク🎜🎜は、それぞれinternal、external、begining(英語の単語の頭文字)を表します。上記の NP や NN などの分類の場合は、先頭に I-/B-/O- を付けるだけで済みます。これにより、上記のギャップを追加するのと同様に、ルール外のコレクションが公開されるようになります。 🎜
cp
の場合、 cp.evaluate(conll2000.chunked_sents('train.txt')[99])
を使用できます。精度をテストします。以前に学習した Unigram タガーを使用して、名詞フレーズをチャンクに分割し、精度をテストできます🎜🎜rrreee🎜🎜🎜🎜🎜固有表現の認識と情報抽出🎜🎜🎜固有表現: 特定の種類の個人を指す正確な名詞フレーズ、日付、人物、組織など🎜。一人で許燕分類に行ったら、間違いなく頭でっかちになりますよ(ˉ▽ ̄~)~~。 NLTK は、トレーニングされた分類子、nltk.ne_chunk(tagged_sent[,binary=False])
を提供します。 binary が True に設定されている場合、名前付きエンティティは NE としてのみタグ付けされます。それ以外の場合、タグはもう少し複雑になります。 🎜🎜rrreee🎜🎜🎜🎜🎜名前付きエンティティが決定されたら、🎜関係抽出🎜を実装して情報を抽出できます。 1 つの方法は、すべてのトリプル (X、a、Y) を見つけることです。ここで、X と Y は名前付きエンティティであり、a は 2 つの関係を表す文字列です。例は次のとおりです。以上がシステムを構築するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。