2011-08-31 10 views
7

R의 tm 패키지를 사용하여 일반 텍스트 문서의 코퍼스에서 문서를 줄이려고합니다. 내가 Corpus의 모든 문서에 SnowballStemmer 함수를 적용하면 각 문서의 마지막 단어 만 줄기.Snowball Stemmer는 마지막 단어 만 말합니다.

문서가 코퍼스로 읽히는 방식과 관련이 있다고 생각합니다. 몇 가지 간단한 예제와 함께이 문제를 설명하기 위해 :

> vec<-c("running runner runs","happyness happies") 
> stemDocument(vec) 
    [1] "running runner run" "happyness happi" 

> vec2<-c("running","runner","runs","happyness","happies") 
> stemDocument(vec2) 
    [1] "run" "runner" "run" "happy" "happi" <- 

> corp<-Corpus(VectorSource(vec)) 
> corp<-tm_map(corp, stemDocument) 
> inspect(corp) 
    A corpus with 2 text documents 

    The metadata consists of 2 tag-value pairs and a data frame 
    Available tags are: 
    create_date creator 
    Available variables in the data frame are: 
    MetaID 

    [[1]] 
    run runner run 

    [[2]] 
    happy happi 

> corp2<-Corpus(DirSource(path),readerControl=list(reader=readPlain,language="en_US" , load=T)) 
> corp2<-tm_map(corp2, stemDocument) 
> inspect(corp2) 
    A corpus with 2 text documents 

    The metadata consists of 2 tag-value pairs and a data frame 
    Available tags are: 
    create_date creator 
    Available variables in the data frame are: 
    MetaID 

    $`1.txt` 
    running runner runs 

    $`2.txt` 
    happyness happies 
+0

스노우 보의 R 인터페이스에서 제외 하시겠습니까? 따라서 라이브러리 (Rstem)와 tm_map (corp, wordStem)을 시도해야합니다. –

+0

의견을 주셔서 감사합니다. 나는 그것을 시도하고 결과는 동일했다. 문제를 좀 더 자세히 설명하기 위해 위의 더 좋은 예제를 포함 할 것입니다. – Christian

답변

3

내가 볼 문제는 wordStem 단어의 벡터에 걸리지 만 코퍼스 plainTextReader가 읽기 문서에서 각 단어는 한 줄에 있다고 가정합니다. 당신이 대신

From ancient grudge break to new mutiny, 
Where civil blood makes civil hands unclean. 
From forth the fatal loins of these two foes 

문서의 3 "단어"로 끝날 것 같은 즉,이 또한 그 문장 부호도wordStem가 혼란 문서가

From 
ancient 
grudge 
break 
to 
new 
mutiny 
where 
civil 
...etc... 

참고해야 plainTextReader을 혼동 것 때문에 당신도 그들을 데리고 나가야 할 것입니다.

실제 문서를 수정하지 않고이 작업을 수행하는 또 다른 방법은 분리를 수행하고 단어 앞뒤에 나타나는 영숫자가 아닌 문자를 제거하는 기능을 정의하는 것입니다. 다음은 간단한 것입니다 :

wordStem2 <- function(x) { 
    mywords <- unlist(strsplit(x, " ")) 
    mycleanwords <- gsub("^\\W+|\\W+$", "", mywords, perl=T) 
    mycleanwords <- mycleanwords[mycleanwords != ""] 
    wordStem(mycleanwords) 
} 

corpA <- tm_map(mycorpus, wordStem2); 
corpB <- Corpus(VectorSource(corpA)); 

이제 코퍼스로 corpB를 사용하십시오.

+0

감사합니다, 형태소 분석이 이제 효과가있었습니다. 그러나 wordStem과 SnowballStemmer를 적용한 결과는 개별적인 문자 벡터입니다. 이로 인해 DocumentTermMatrix 함수가 더 이상 결과 코퍼스에서 작동하지 않는 문제가 발생합니다. 이걸 어떻게 작동시킬 수 있니? – Christian

+0

@Christian 나는 이것에 대한 나의 대답을 편집했다. 더 쉬운 방법이 있다면, 나는 그것을 모른다. –

4

부하 필요한 라이브러리

library(tm) 
library(Snowball) 

만들 벡터

vec<-c("running runner runs","happyness happies") 

vec<-Corpus(VectorSource(vec)) 

매우 중요한 것은 우리 신체의 클래스를 확인하고 우리가 원하는대로 보존하는 것입니다 벡터에서 코퍼스를 만들 R 함수가 이해하는 표준 코퍼스

class(vec[[1]]) 

vec[[1]] 
<<PlainTextDocument (metadata: 7)>> 
running runner runs 

이 아마 그래서 지금 우리는 우리의 결함이 stemDocument 기능을 수정하면 일반 텍스트 문서

을 알려드립니다. 먼저 일반 텍스트를 문자로 변환 한 다음 텍스트를 나눕니다. 이제는 잘 작동하는 stemDocument를 적용하고 다시 붙여 넣습니다. 가장 중요한 것은 tm 패키지가 제공 한 PlainTextDocument로 출력을 변환한다는 것입니다.

stemDocumentfix <- function(x) 
{ 
    PlainTextDocument(paste(stemDocument(unlist(strsplit(as.character(x), " "))),collapse=' ')) 
} 

지금 우리는 우리의 신체에 표준 tm_map을 사용할 수 있습니다

vec1 = tm_map(vec, stemDocumentfix) 

결과는 당신이 기억해야 할

vec1[[1]] 
<<PlainTextDocument (metadata: 7)>> 
run runner run 

가장 중요한 것은 항상 코퍼스에 문서의 클래스를 presever하는 것입니다. 로드 된 2 개의 라이브러리 내에서 함수를 사용하여 문제에 대한 단순화 된 솔루션이되기를 바랍니다.