2015-11-02 18 views
6

Ağaç yapı görselleştirmesi olarak ayrıştırma işlemini (POS etiketleme) openNLP'dan görüntülemek istiyorum. Aşağıda openNLP'dan ayrıştırma ağacını sağladım ancak Python's parsing için ortak bir görsel ağaç olarak çizim yapamıyorum. Ağaç yapısı buna benzer görünmelidirAyrıştırma Ağaç Yapısını Görüntüleme

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

: Bu ağaç görselleştirme görüntülemek için bir yol

enter image description here

var mı?

Kullanılabilecek sayısal ifadeleri çizmek için ancak cümle ayrıştırma görselleştirmesine genelleştiremediğim için this related tree viz sorusunu buldum.

+0

Tamam arayarak grafik oluşturma görünüyor onun açıklamalı versiyonu ptext, ama bundan sonra ne var? – Indi

+2

Belki de https://en.wikibooks.org/wiki/LaTeX/Linguistics#tikz-qtree? – Reactormonk

cevap

8

İşte bir igraph sürümü. Bu işlev, sonucu olarak Parse_annotator sonucunu alır, örneğinizde ptext. NLP::Tree_parse zaten güzel bir ağaç yapısı yaratıyor, bu yüzden buradaki fikir, yinelemeli olarak çaprazlamak ve igraph'a takmak için bir edgelist oluşturmaktır. Edgelist, sadece 2 sütunlu bir kafa matrisidir.

igraph'un uygun düğümler arasında kenarlar oluşturması için, bunların benzersiz tanımlayıcılara sahip olması gerekir. Ben Tree_parse kullanmadan önce metinde sözcüklere bir tamsayılar dizisi (regmatches<- kullanarak) ekleyerek yaptım.

edgemaker iç işlevi, ilerledikçe edgelist numaralı dolguyu doldurarak ağacı çevirir. Yaprakları düğümlerin geri kalanından ayrı renklendirmek için seçenekler vardır, ancak vertex.label.color seçeneğini geçirirseniz, bunları aynı şekilde renklendirir.

## 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) 
} 

Yani, örnek kullanarak, dize x ve

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

gibi

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

Ben ağladım :-) Bu çalışma için takdir ediyorum +500 –

+0

Ben de bunu R için 3 yıl içinde yapmak istedim. Sadece kolayca ayrıştırmayı mümkün kılan bir pakete geri dönüyorum ve son parça, ayrıştırılmış cümleleri çizmek için bir yol istedim. Gerçek bilgilerinizi bana e-postayla gönderebilir misiniz, böylece size pakette bir yazar olarak ekleyebilir miyim? –

+0

şu an için verimli olmak zorunda değil, sadece çalışıyor :-) Yavaş/verimsiz olsa bile, şu anda mevcut olandan daha iyi. SO işlemcinizi kullanacağım ve etik bütünlüğü sağlamak için bu soruyu referans alıyorum (yani, vadesi geldiğinde kredi verin). Fikrinizi istediğiniz zaman değiştirirseniz, gerçek isminizi kullanacağım. Tekrar teşekkürler. –