R, строя строку/документ/корпус

Я пытаюсь сделать некоторые из них в R, но, похоже, это работает только на отдельных документах. Моя конечная цель - это матрица терминов документов, которая показывает частоту каждого термина в документе.

Вот пример:

require(RWeka)
require(tm)
require(Snowball)

worder1<- c("I am taking","these are the samples",
"He speaks differently","This is distilled","It was placed")
df1 <- data.frame(id=1:5, words=worder1)

> df1
  id                 words
1  1           I am taking
2  2 these are the samples
3  3 He speaks differently
4  4     This is distilled
5  5         It was placed

Этот метод работает для основной части, но не для словарной части документа:

> corp1 <- Corpus(VectorSource(df1$words))
> inspect(corp1)
A corpus with 5 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]]
I am taking

[[2]]
these are the samples

[[3]]
He speaks differently

[[4]]
This is distilled

[[5]]
It was placed

> corp1 <- tm_map(corp1, SnowballStemmer)
> inspect(corp1)
A corpus with 5 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]]
[1] I am tak

[[2]]
[1] these are the sampl

[[3]]
[1] He speaks differ

[[4]]
[1] This is distil

[[5]]
[1] It was plac

>  class(corp1)
[1] "VCorpus" "Corpus"  "list"   
> tdm1 <- TermDocumentMatrix(corp1)
Error in UseMethod("Content", x) : 
  no applicable method for 'Content' applied to an object of class "character"

Поэтому вместо этого я попытался сначала создать матрицу документов, но на этот раз слова не получаются:

> corp1 <- Corpus(VectorSource(df1$words))
> tdm1 <- TermDocumentMatrix(corp1, control=list(stemDocument=TRUE))
>  as.matrix(tdm1)
             Docs
Terms         1 2 3 4 5
  are         0 1 0 0 0
  differently 0 0 1 0 0
  distilled   0 0 0 1 0
  placed      0 0 0 0 1
  samples     0 1 0 0 0
  speaks      0 0 1 0 0
  taking      1 0 0 0 0
  the         0 1 0 0 0
  these       0 1 0 0 0
  this        0 0 0 1 0
  was         0 0 0 0 1

Здесь слова, очевидно, не вытекают.

Любые предложения?

Ответ 1

Пакет RTextTools на CRAN позволяет это сделать.

library(RTextTools)
worder1<- c("I am taking","these are the samples",
"He speaks differently","This is distilled","It was placed")
df1 <- data.frame(id=1:5, words=worder1)

matrix <- create_matrix(df1, stemWords=TRUE, removeStopwords=FALSE, minWordLength=2)
colnames(matrix) # SEE THE STEMMED TERMS

Это возвращает DocumentTermMatrix, который можно использовать с пакетом tm. Вы можете играть с другими параметрами (например, удалять стоп-слова, изменять минимальную длину слова, используя стебельщик для другого языка), чтобы получить нужные результаты. При отображении as.matrix в примере создается следующая матрица термов:

                         Terms
Docs                      am are differ distil he is it place sampl speak take the these this was
  1 I am taking            1   0      0      0  0  0  0     0     0     0    1   0     0    0   0
  2 these are the samples  0   1      0      0  0  0  0     0     1     0    0   1     1    0   0
  3 He speaks differently  0   0      1      0  1  0  0     0     0     1    0   0     0    0   0
  4 This is distilled      0   0      0      1  0  1  0     0     0     0    0   0     0    1   0
  5 It was placed          0   0      0      0  0  0  1     1     0     0    0   0     0    0   1

Ответ 2

Это работает в R, как ожидалось, с tm версии 0.6. У вас было несколько незначительных ошибок, которые препятствовали правильному функционированию, возможно, они из более старой версии tm? В любом случае, вот как это сделать:

require(RWeka)
require(tm)

Исходный пакет не является вашим Snowball, а SnowballC:

require(SnowballC)

worder1<- c("I am taking","these are the samples",
            "He speaks differently","This is distilled","It was placed")
df1 <- data.frame(id=1:5, words=worder1)
corp1 <- Corpus(VectorSource(df1$words))
inspect(corp1)

Измените SnowballStemmer на stemDocument в следующей строке следующим образом:

corp1 <- tm_map(corp1, stemDocument)
inspect(corp1)

Слова вызваны, как и ожидалось:

<<VCorpus (documents: 5, metadata (corpus/indexed): 0/0)>>

[[1]]
<<PlainTextDocument (metadata: 7)>>
I am take

[[2]]
<<PlainTextDocument (metadata: 7)>>
these are the sampl

[[3]]
<<PlainTextDocument (metadata: 7)>>
He speak differ

[[4]]
<<PlainTextDocument (metadata: 7)>>
This is distil

[[5]]
<<PlainTextDocument (metadata: 7)>>
It was place

Теперь введите термин документа:

corp1 <- Corpus(VectorSource(df1$words))

Измените stemDocument на stemming:

tdm1 <- TermDocumentMatrix(corp1, control=list(stemming=TRUE))
as.matrix(tdm1)

И мы получаем tdm слова, как ожидалось:

        Docs
Terms    1 2 3 4 5
  are    0 1 0 0 0
  differ 0 0 1 0 0
  distil 0 0 0 1 0
  place  0 0 0 0 1
  sampl  0 1 0 0 0
  speak  0 0 1 0 0
  take   1 0 0 0 0
  the    0 1 0 0 0
  these  0 1 0 0 0
  this   0 0 0 1 0
  was    0 0 0 0 1

Итак, вы идете. Возможно, более тщательное чтение документов tm могло бы немного сэкономить ваше время:)

Ответ 3

Да для хранения слов документа в корпусе вам необходимы пакеты Rweka, Snowball и tm.

используйте следующую команду

> library (tm)
#set your directory Suppose u have set "F:/St" then next command is 
> a<-Corpus(DirSource("/st"), 
            readerControl=list(language="english")) # "/st" it is path of your directory
> a<-tm_map(a, stemDocument, language="english")
> inspect(a)

убедитесь, что вы найдете нужный результат.

Ответ 4

Другим решением является жесткое кодирование. Он просто разрывает тексты, а стебли затем восстанавливаются:

library(SnowballC)
i=1
#Snowball stemming
while(i<=nrow(veri)){
  metin=veri[i,2]
  stemmed_metin="";
  parcali=unlist(strsplit(metin,split=" ")) #split the text
  for(klm in parcali){
    stemmed_klm=wordStem(klm,language = "turkish") #stem word by word
    stemmed_metin=sprintf("%s %s",stemmed_metin,stemmed_klm) #reconcantrate
  }

  veri[i,4]=stemmed_metin #write to new column

  i=i+1
}