2013-08-21 9 views
8

Próbuję równolegle używać części tagowania mowy z pakietów openNLP/NLP. Potrzebuję kodu do pracy na dowolnym systemie operacyjnym, więc wybieram używanie funkcji parLapply z poziomu równoległego (ale jestem otwarty na inne opcje niezależne od systemu operacyjnego). W przeszłości uruchamiałem funkcję tagPOS z pakietu openNLP w parLapply bez problemu. Jednak pakiet openNLP wprowadził kilka ostatnich zmian, które wyeliminowały tagPOS i dodały bardziej elastyczne opcje. Kurt był na tyle miły, że pomógł mi odtworzyć funkcję tagPOS z narzędzi nowego pakietu. Mogę pobrać wersję lapply, ale nie wersję równoległą. Ciągle mówi, że węzły potrzebują więcej zmiennych przekazanych do nich, aż w końcu prosi o nie wyeksportowaną funkcję z openNLP. Wydaje się to dziwne, że wciąż prosiłbym o podanie coraz większej liczby zmiennych, które mówią mi, że niepoprawnie konfiguruję parLapply. Jak mogę skonfigurować tagPOS, aby działał równolegle, niezależnie od OS?Równolegle konfiguracja parLapply

library(openNLP) 
library(NLP) 
library(parallel) 

## POS tagger 
tagPOS <- function(x, pos_tag_annotator, ...) { 
    s <- as.String(x) 
    ## Need sentence and word token annotations. 
    word_token_annotator <- Maxent_Word_Token_Annotator() 
    a2 <- Annotation(1L, "sentence", 1L, nchar(s)) 
    a2 <- annotate(s, word_token_annotator, a2) 
    a3 <- annotate(s, pos_tag_annotator, a2) 

    ## Determine the distribution of POS tags for word tokens. 
    a3w <- a3[a3$type == "word"] 
    POStags <- unlist(lapply(a3w$features, `[[`, "POS")) 

    ## Extract token/POS pairs (all of them): easy. 
    POStagged <- paste(sprintf("%s/%s", s[a3w], POStags), collapse = " ") 
    list(POStagged = POStagged, POStags = POStags) 
} ## End of tagPOS function 

## Set up a parallel run 
text.var <- c("I like it.", "This is outstanding soup!", 
    "I really must get the recipe.") 
ntv <- length(text.var) 
PTA <- Maxent_POS_Tag_Annotator() 

cl <- makeCluster(mc <- getOption("cl.cores", detectCores()/2)) 
clusterExport(cl=cl, varlist=c("text.var", "ntv", 
    "tagPOS", "PTA", "as.String", "Maxent_Word_Token_Annotator"), 
    envir = environment()) 
m <- parLapply(cl, seq_len(ntv), function(i) { 
     x <- tagPOS(text.var[i], PTA) 
     return(x) 
    } 
) 
stopCluster(cl) 

## Error in checkForRemoteErrors(val) : 
## 3 nodes produced errors; first error: could not find function 
## "Maxent_Simple_Word_Tokenizer" 

openNLP::Maxent_Simple_Word_Tokenizer 

## >openNLP::Maxent_Simple_Word_Tokenizer 
## Error: 'Maxent_Simple_Word_Tokenizer' is not an exported 
##  object from 'namespace:openNLP' 

## It's a non exported function 
openNLP:::Maxent_Simple_Word_Tokenizer 


## Demo that it works with lapply 
lapply(seq_len(ntv), function(i) { 
    tagPOS(text.var[i], PTA) 
}) 

lapply(text.var, function(x) { 
    tagPOS(x, PTA) 
}) 

## >  lapply(seq_len(ntv), function(i) { 
## +   tagPOS(text.var[i], PTA) 
## +  }) 
## [[1]] 
## [[1]]$POStagged 
## [1] "I/PRP like/IN it/PRP ./." 
## 
## [[1]]$POStags 
## [1] "PRP" "IN" "PRP" "." 
## 
## [[1]]$word.count 
## [1] 3 
## 
## 
## [[2]] 
## [[2]]$POStagged 
## [1] "THis/DT is/VBZ outstanding/JJ soup/NN !/." 
## 
## [[2]]$POStags 
## [1] "DT" "VBZ" "JJ" "NN" "." 
## 
## [[2]]$word.count 
## [1] 4 
## 
## 
## [[3]] 
## [[3]]$POStagged 
## [1] "I/PRP really/RB must/MD get/VB the/DT recip/NN ./." 
## 
## [[3]]$POStags 
## [1] "PRP" "RB" "MD" "VB" "DT" "NN" "." 
## 
## [[3]]$word.count 
## [1] 6 

EDIT: za sugestię Steve'a

Zanotuj openNLP jest nowy. Zainstalowałem wersję 2.1 z tar.gz z CRAN. Otrzymuję następujący błąd, mimo że ta funkcja istnieje.

biblioteka (openNLP); biblioteka (NLP); Biblioteka (równolegle)

tagPOS <- function(text.var, pos_tag_annotator, ...) { 
    s <- as.String(text.var) 

    ## Set up the POS annotator if missing (for parallel) 
    if (missing(pos_tag_annotator)) { 
     PTA <- Maxent_POS_Tag_Annotator() 
    } 

    ## Need sentence and word token annotations. 
    word_token_annotator <- Maxent_Word_Token_Annotator() 
    a2 <- Annotation(1L, "sentence", 1L, nchar(s)) 
    a2 <- annotate(s, word_token_annotator, a2) 
    a3 <- annotate(s, PTA, a2) 

    ## Determine the distribution of POS tags for word tokens. 
    a3w <- a3[a3$type == "word"] 
    POStags <- unlist(lapply(a3w$features, "[[", "POS")) 

    ## Extract token/POS pairs (all of them): easy. 
    POStagged <- paste(sprintf("%s/%s", s[a3w], POStags), collapse = " ") 
    list(POStagged = POStagged, POStags = POStags) 
} 

text.var <- c("I like it.", "This is outstanding soup!", 
    "I really must get the recipe.") 

cl <- makeCluster(mc <- getOption("cl.cores", detectCores()/2)) 
clusterEvalQ(cl, {library(openNLP); library(NLP)}) 
m <- parLapply(cl, text.var, tagPOS) 

## > m <- parLapply(cl, text.var, tagPOS) 
## Error in checkForRemoteErrors(val) : 
## 3 nodes produced errors; first error: could not find function "Maxent_POS_Tag_Annotator" 

stopCluster(cl) 


> packageDescription('openNLP') 
Package: openNLP 
Encoding: UTF-8 
Version: 0.2-1 
Title: Apache OpenNLP Tools Interface 
[email protected]: person("Kurt", "Hornik", role = c("aut", "cre"), email = 
      "[email protected]") 
Description: An interface to the Apache OpenNLP tools (version 1.5.3). The Apache OpenNLP 
      library is a machine learning based toolkit for the processing of natural language 
      text written in Java. It supports the most common NLP tasks, such as tokenization, 
      sentence segmentation, part-of-speech tagging, named entity extraction, chunking, 
      parsing, and coreference resolution. See http://opennlp.apache.org/ for more 
      information. 
Imports: NLP (>= 0.1-0), openNLPdata (>= 1.5.3-1), rJava (>= 0.6-3) 
SystemRequirements: Java (>= 5.0) 
License: GPL-3 
Packaged: 2013-08-20 13:23:54 UTC; hornik 
Author: Kurt Hornik [aut, cre] 
Maintainer: Kurt Hornik <[email protected]> 
NeedsCompilation: no 
Repository: CRAN 
Date/Publication: 2013-08-20 15:41:22 
Built: R 3.0.1; ; 2013-08-20 13:48:47 UTC; windows 

Odpowiedz

5

Skoro funkcji z NLP na pracowników klastra dzwoni, należy załadować go na każdym z pracowników przed wywołaniem parLapply. Można to zrobić z funkcji pracownika, ale mają tendencję do używania clusterCall lub clusterEvalQ zaraz po utworzeniu obiektu klastra:

clusterEvalQ(cl, {library(openNLP); library(NLP)}) 

Od as.String i Maxent_Word_Token_Annotator są w tych pakietach, nie powinny być wywożone.

Należy zauważyć, że podczas uruchamiania przykładu na moim komputerze, zauważyłem, że obiekt PTA nie działa po wyeksportowaniu na maszyny pracujące. Przypuszczalnie jest w tym obiekcie coś, czego nie można bezpiecznie spersonalizować i zserializować. Po utworzeniu tego obiektu na robotach przy użyciu clusterEvalQ, przykład zakończył się pomyślnie. Tutaj jest to, używając openNLP 0,2-1:

library(parallel) 
tagPOS <- function(x, ...) { 
    s <- as.String(x) 
    word_token_annotator <- Maxent_Word_Token_Annotator() 
    a2 <- Annotation(1L, "sentence", 1L, nchar(s)) 
    a2 <- annotate(s, word_token_annotator, a2) 
    a3 <- annotate(s, PTA, a2) 
    a3w <- a3[a3$type == "word"] 
    POStags <- unlist(lapply(a3w$features, `[[`, "POS")) 
    POStagged <- paste(sprintf("%s/%s", s[a3w], POStags), collapse = " ") 
    list(POStagged = POStagged, POStags = POStags) 
} 
text.var <- c("I like it.", "This is outstanding soup!", 
    "I really must get the recipe.") 
cl <- makeCluster(mc <- getOption("cl.cores", detectCores()/2)) 
clusterEvalQ(cl, { 
    library(openNLP) 
    library(NLP) 
    PTA <- Maxent_POS_Tag_Annotator() 
}) 
m <- parLapply(cl, text.var, tagPOS) 
print(m) 
stopCluster(cl) 

Jeśli clusterEvalQ powiodło się, ponieważ nie znaleziono Maxent_POS_Tag_Annotator, może być ładowanie złą wersję openNLP na robotników. Można określić, jakie wersje pakietu dostajesz na pracowników wykonując sessionInfo z clusterEvalQ:

library(parallel) 
cl <- makeCluster(2) 
clusterEvalQ(cl, {library(openNLP); library(NLP)}) 
clusterEvalQ(cl, sessionInfo()) 

ten powróci wyniki zastosowania sessionInfo() na każdym z pracowników klastra. Oto informacje o wersji niektórych pakietów, z których korzystam i które działają dla mnie:

other attached packages: 
[1] NLP_0.1-0  openNLP_0.2-1 

loaded via a namespace (and not attached): 
[1] openNLPdata_1.5.3-1 rJava_0.9-4 
+0

Dziękuję za informację. Ten sam błąd nadal występuje. –

+0

@ TylerRinker Czy to pomaga, jeśli nie wyeksportujesz bezpośrednio pliku Maxent_Word_Token_Annotator? –

+0

Steve Dziękuję raz jeszcze za poświęcony czas. Otrzymuję ten sam błąd. Zobacz moją edycję powyżej. Czy możesz spróbować z openNLP 2.1. Nie mogę spróbować 2.0, ponieważ nie mam Internetu na moim komputerze. Zauważ, że nowe nazwy funkcji w 2.1 –