2015-11-02 25 views
6

openNLPからの解析(POSタグ付け)をツリー構造の視覚化として表示したいとします。以下では、openNLPの解析ツリーを提供していますが、Python's parsingに共通するビジュアルツリーとしてプロットすることはできません。ツリー構造は、このようになりますパーズツリー構造の可視化

install.packages(
    "http://datacube.wu.ac.at/src/contrib/openNLPmodels.en_1.5-1.tar.gz", 
    repos=NULL, 
    type="source" 
) 

library(NLP) 
library(openNLP) 

x <- 'Scroll bar does not work the best either.' 
s <- as.String(x) 

## Annotators 
sent_token_annotator <- Maxent_Sent_Token_Annotator() 
word_token_annotator <- Maxent_Word_Token_Annotator() 
parse_annotator <- Parse_Annotator() 

a2 <- annotate(s, list(sent_token_annotator, word_token_annotator)) 
p <- parse_annotator(s, a2) 
ptext <- sapply(p$features, `[[`, "parse") 
ptext 
Tree_parse(ptext) 

## > ptext 
## [1] "(TOP (S (NP (NNP Scroll) (NN bar)) (VP (VBZ does) (RB not) (VP (VB work) (NP (DT the) (JJS best)) (ADVP (RB either))))(. .)))" 
## > Tree_parse(ptext) 
## (TOP 
## (S 
##  (NP (NNP Scroll) (NN bar)) 
##  (VP (VBZ does) (RB not) (VP (VB work) (NP (DT the) (JJS best)) (ADVP (RB either)))) 
##  (. .))) 

:このツリーの可視化を表示する方法は

enter image description here

ありますか?

私はthis related tree vizという数値式をプロットして使用することができますが、私は文解析の可視化には一般化できませんでした。

+0

を呼び出すことで、グラフを作成します

x <- 'Scroll bar does not work the best either.' ptext # [1] "(TOP (S (NP (NNP Scroll) (NN bar)) (VP (VBZ does) (RB not) (VP (VB work) (NP (DT the) (JJS best)) (ADVP (RB either))))(. .)))" 

のように見えるあなたの例を使用して、文字列xとその注釈付きバージョンptext、その後は何がありますか? – Indi

+2

多分https://en.wikibooks.org/wiki/LaTeX/Linguistics#tikz-qtree経由ですか? – Reactormonk

答えて

8

ここにはigraphバージョンがあります。この関数は、入力としてParse_annotatorの結果を受け取ります。したがって、例ではptextです。 NLP::Tree_parseはすでに素敵なツリー構造を作成しているので、再帰的にそれをトラバースし、igraphに接続するedgelistを作成することです。 edgelistはhead-> tail値の2列の行列です。

igraphが適切なノード間にエッジを作成するためには、固有の識別子が必要です。私はこれを、Tree_parseを使う前に、テキスト内の単語に整数のシーケンスを(regmatches<-を使って)追加することによって行いました。

内部機能edgemakerは木を横切り、edgelistのように記入します。残りのノードとは別に葉に色付けするオプションがありますが、オプションvertex.label.colorを渡すと、それらはすべて同じ色になります。

だから、
## Make a graph from Tree_parse result 
parse2graph <- function(ptext, leaf.color='chartreuse4', label.color='blue4', 
         title=NULL, cex.main=.9, ...) { 
    stopifnot(require(NLP) && require(igraph)) 

    ## Replace words with unique versions 
    ms <- gregexpr("[^() ]+", ptext)          # just ignoring spaces and brackets? 
    words <- regmatches(ptext, ms)[[1]]         # just words 
    regmatches(ptext, ms) <- list(paste0(words, seq.int(length(words)))) # add id to words 

    ## Going to construct an edgelist and pass that to igraph 
    ## allocate here since we know the size (number of nodes - 1) and -1 more to exclude 'TOP' 
    edgelist <- matrix('', nrow=length(words)-2, ncol=2) 

    ## Function to fill in edgelist in place 
    edgemaker <- (function() { 
     i <- 0          # row counter 
     g <- function(node) {      # the recursive function 
      if (inherits(node, "Tree")) {   # only recurse subtrees 
       if ((val <- node$value) != 'TOP1') { # skip 'TOP' node (added '1' above) 
        for (child in node$children) { 
         childval <- if(inherits(child, "Tree")) child$value else child 
         i <<- i+1 
         edgelist[i,1:2] <<- c(val, childval) 
        } 
       } 
       invisible(lapply(node$children, g)) 
      } 
     } 
    })() 

    ## Create the edgelist from the parse tree 
    edgemaker(Tree_parse(ptext)) 

    ## Make the graph, add options for coloring leaves separately 
    g <- graph_from_edgelist(edgelist) 
    vertex_attr(g, 'label.color') <- label.color # non-leaf colors 
    vertex_attr(g, 'label.color', V(g)[!degree(g, mode='out')]) <- leaf.color 
    V(g)$label <- sub("\\d+", '', V(g)$name)  # remove the numbers for labels 
    plot(g, layout=layout.reingold.tilford, ...) 
    if (!missing(title)) title(title, cex.main=cex.main) 
} 

、オーケー

library(igraph) 
library(NLP) 

parse2graph(ptext, # plus optional graphing parameters 
      title = sprintf("'%s'", x), margin=-0.05, 
      vertex.color=NA, vertex.frame.color=NA, 
      vertex.label.font=2, vertex.label.cex=1.5, asp=0.5, 
      edge.width=1.5, edge.color='black', edge.arrow.size=0) 

enter image description here

+1

私はうんざりしました:-)私は+500 –

+0

の仕事を感謝します。私はRでこれを3年間やりたいと思っていました。簡単な構文解析を可能にするパッケージに戻って、最後の部分は、解析された文章をプロットする方法を欲しかったということでした。あなたの実際の情報を私に電子メールで送ることができるので、あなたをパッケージの著者として含めることができますか? –

+0

は今のところ効率的である必要はなく、ちょうど働いています:-)遅い/非効率的であっても、Rが現在利用できるものよりも優れています。私はあなたのSOのハンドルを使用し、この質問を参照して倫理的な完全性を維持します(つまり、期限が到来した場合にクレジットを与える)。あなたがいつでもあなたの心を変えたら、私に知らせてください。私はあなたの実際の名前を使用します。再度、感謝します。 –