То же значение, но другой результат? О removeSparseTerms (R)

#r

#r

Вопрос:

Прежде всего, вот пример данных для воспроизведения проблемы, которая у меня есть, и я попытаюсь объяснить ниже: https://drive.google.com/file/d/0B4RCdYlVF8otUll6V2x0cDJORGc/view?usp=sharing

Дело в том, что я получаю разные результаты от removeSparseTerms, несмотря на то, что я ввел ему то же значение. Кажется, это противоречит человеческой логике или, по крайней мере, моей. У меня есть эта функция:

 generateTDM <- function (Room_name, dest.train, RST){
          s.dir <- sprintf("%s/%s", dest.train, Room_name)
          s.cor <- Corpus(DirSource(directory = s.dir, pattern = "txt", encoding = "UTF-8"))                  #Crea unos corpora de los archivos txt ya limpios.
          s.tdm <- TermDocumentMatrix(s.cor, control = list(bounds = list(local = c(2, Inf)), tokenize = TrigramTokenizer))                     #Crea una matriz de terminos a partir de los corpora teniendo en cuenta unigramas, bigramas y trigramas.
          s.tdm <- removeSparseTerms(s.tdm, RST)                                                           #Mantiene aquellos términos que aparezcan en el (1-RST)% de los archivos, el resto los elimina.
      }
  

Ну, когда я вызываю эту функцию таким образом:

 tdm.train <- lapply(Room_name, generateTDM, dest.train, RST[p])
  

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

Например:

Случай 1:

 RST <-seq (0.45, 0.6, 0.05)
p<-4
  

Сначала у меня будет = (0.45, 0.5, 0.55, 0.6), тогда RST[p] равно 0.6.

Результат в этом случае:

     > tdm.train 
        [[1]]
    <<TermDocumentMatrix (terms: 84, documents: 51)>>
    Non-/sparse entries: 2451/1833
    Sparsity           : 43%
    Maximal term length: 10
    Weighting          : term frequency (tf)

    [[2]]
    <<TermDocumentMatrix (terms: 82, documents: 52)>>
    Non-/sparse entries: 2409/1855
    Sparsity           : 44%
    Maximal term length: 11
    Weighting          : term frequency (tf)

    [[3]]
    <<TermDocumentMatrix (terms: 68, documents: 51)>>
    Non-/sparse entries: 1926/1542
    Sparsity           : 44%
    Maximal term length: 13
    Weighting          : term frequency (tf)

    [[4]]
    <<TermDocumentMatrix (terms: 36, documents: 48)>>
    Non-/sparse entries: 985/743
    Sparsity           : 43%
    Maximal term length: 10
    Weighting          : term frequency (tf)

    [[5]]
    <<TermDocumentMatrix (terms: 48, documents: 50)>>
    Non-/sparse entries: 1295/1105
    Sparsity           : 46%
    Maximal term length: 10
    Weighting          : term frequency (tf)

    [[6]]
    <<TermDocumentMatrix (terms: 27, documents: 50)>>
    Non-/sparse entries: 756/594
    Sparsity           : 44%
    Maximal term length: 8
    Weighting          : term frequency (tf)
  

Случай 2:

     RST <-seq (0.45, 0.8, 0.05)
    p<-4
  

Теперь у меня будет это ПЕРВОЕ = (0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8), следовательно, RST[p] на этот раз то же самое (0.6).

Тогда почему у меня другой результат? Я не могу этого понять.

 > tdm.train
[[1]]
<<TermDocumentMatrix (terms: 84, documents: 51)>>
Non-/sparse entries: 2451/1833
Sparsity           : 43%
Maximal term length: 10
Weighting          : term frequency (tf)

[[2]]
<<TermDocumentMatrix (terms: 82, documents: 52)>>
Non-/sparse entries: 2409/1855
Sparsity           : 44%
Maximal term length: 11
Weighting          : term frequency (tf)

[[3]]
<<TermDocumentMatrix (terms: 68, documents: 51)>>
Non-/sparse entries: 1926/1542
Sparsity           : 44%
Maximal term length: 13
Weighting          : term frequency (tf)

[[4]]
<<TermDocumentMatrix (terms: 36, documents: 48)>>
Non-/sparse entries: 985/743
Sparsity           : 43%
Maximal term length: 10
Weighting          : term frequency (tf)

[[5]]
<<TermDocumentMatrix (terms: 57, documents: 50)>>
Non-/sparse entries: 1475/1375
Sparsity           : 48%
Maximal term length: 10
Weighting          : term frequency (tf)

[[6]]
<<TermDocumentMatrix (terms: 34, documents: 50)>>
Non-/sparse entries: 896/804
Sparsity           : 47%
Maximal term length: 8
Weighting          : term frequency (tf)
  

Я не знаю … это очень странно, не так ли?. Если значение RST одинаковое, почему результат removeSparseTerms в последних двух каталогах отличается в каждом случае. Пожалуйста, помогите мне, не зная причины, меня убивает.

Большое вам спасибо и хорошего дня.


Воспроизводимый пример, основанный на обновлении операционной системы:

 library(tm)
library(RWeka)
download.file("https://docs.google.com/uc?authuser=0amp;id=0B4RCdYlVF8otUll6V2x0cDJORGcamp;export=download", tf <- tempfile(fileext = ".zip"), mode = "wb")
unzip(tf, exdir = tempdir())
TrigramTokenizer <- function(x) NGramTokenizer(x, Weka_control(min = 1, max = 3))
generateTDM <- function (Room_name, dest.train, rst){
  s.dir <- sprintf("%s/%s", dest.train, Room_name)
  s.cor <- Corpus(DirSource(directory = s.dir, pattern = "txt", encoding = "UTF-8"))                  #Crea unos corpora de los archivos txt ya limpios.
  s.tdm <- TermDocumentMatrix(s.cor, control = list(bounds = list(local = c(2, Inf)), tokenize = TrigramTokenizer))                     #Crea una matriz de terminos a partir de los corpora teniendo en cuenta unigramas, bigramas y trigramas.
  t <- table(s.tdm$i) > (s.tdm$ncol * (1 - rst)) # from tm::removeSparseTerms()
  termIndex <- as.numeric(names(t[t]))
  return(s.tdm[termIndex, ])
}
dest.train <- file.path(tempdir(), "stackoverflow", "TrainDocs")
Room_name <- "Venus"
p <- 4
RST1 <- seq(0.45, 0.6, 0.05)
RST2 <- seq(0.45, 0.8, 0.05)
RST2[p]
# [1] 0.6
RST1[p]
# [1] 0.6
identical(RST2[p], RST1[p])
# [1] FALSE # ?!?

lapply(Room_name, generateTDM, dest.train, RST1[p])
# <<TermDocumentMatrix (terms: 48, documents: 50)>>

lapply(Room_name, generateTDM, dest.train, RST2[p])
# <<TermDocumentMatrix (terms: 57, documents: 50)>> # ?!?
  

Комментарии:

1. Имхо, было бы лучше выделить различия и предоставить примеры данных для воспроизведения вместо того, чтобы подчеркивать «Я не знаю… Я не могу понять это «несколько раз. 🙂

2. Да, верно. Я подготовлю zip-файл с важными документами и частями скрипта, чтобы прикрепить его сюда, как только это будет возможно. Извините за это.

3. Выполнено. Пример данных прилагается, и уровень ударения в предложениях уменьшился… немного. 🙂

4. Интересно. identical(RST2[p], RST1[p]) это FALSE , чего я не понимаю, и, похоже, таким образом table(m$i) > m$ncol * (1 - sparse) , inside removeSparseTerms дает несколько иные результаты.

5. Спасибо lukeA за ваше время и усилия. Воспроизводимый пример, который вы сделали, потрясающий и гораздо более понятный. Спасибо за это, я уже знаю, как правильно поделиться кодом в следующий раз. Что касается вопроса, я использовал all.equal и str для сравнения обоих значений (я не знал инструкции identical ), поэтому я предположил, что они одинаковые, потому что так и должно быть. Действительно, действительно странно. :S

Ответ №1:

Проблема, похоже, связана с популярным вопросом «7.31 Почему R не считает, что эти числа равны?«:

Единственными числами, которые могут быть представлены точно в числовом типе R, являются целые числа и дроби, знаменатель которых равен степени 2. Все остальные числа внутренне округлены до (обычно) точности 53 двоичных цифр. В результате два числа с плавающей запятой не будут надежно равны, если они не были вычислены с помощью одного и того же алгоритма, и даже тогда не всегда

Учитывая

 (x <- seq(0.45, 0.6, 0.05))
# [1] 0.45 0.50 0.55 0.60
(y <- seq(0.45, 0.8, 0.05))
# [1] 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80
  

затем

 x==y
# [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
x[4]==y[4]
# [1] FALSE
x[4]-y[4]
# [1] -1.110223e-16
x[3]-y[3]
# [1] 0
  

Поскольку

 MASS::as.fractions(x)
# [1]  9/20   1/2 11/20   3/5
  

Я думаю, что здесь они .5 надежно равны. Таким образом, ваша функция может давать разные результаты.

Комментарии:

1. Большое вам спасибо, lukeA. После вашего ответа мне удалось решить проблему, создав ПЕРВЫЙ вектор с целочисленными значениями: RST <-seq (45, 60, 5) , и во время вызова функции я ввожу ПЕРВОЕ значение, разделенное на 100: tdm.train <- lapply(Room_name, TDM_roomRST, dest.train, (RST[p]/100)) . Таким образом, результат, который я получаю, уже точно такой же в каждом случае. Серьезно, я действительно ценю вашу помощь и вклад здесь, приятель. Я желаю вам всего наилучшего. Приветствую и благодарю вас.