2015-11-02 87 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

好創建圖形,但之後呢? – Indi

+2

也許通過https://en.wikibooks.org/wiki/LaTeX/Linguistics#tikz-qtree? – Reactormonk

回答

8

這裏是一個igraph版本。該函數將Parse_annotator作爲輸入的結果,因此在您的示例中爲ptextNLP::Tree_parse已經創建了一個很好的樹形結構,所以這裏的想法是遞歸地遍歷它並創建一個邊界列表來插入igraph。邊界列表只是頭部 - >尾部值的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) 
} 

因此,使用您的例子中,字符串x及其註釋版本ptext,它看起來像

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))))(. .)))" 

通過調用

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處理並引用這個問題來保持道德的完整性(即在到期時給予信用)。如果您隨時改變主意,請告訴我,我將使用您的真實姓名。再次感謝。 –