Как вычислить схожесть в квантах между документами только за соседние годы внутри групп? - PullRequest
1 голос
/ 06 мая 2020

У меня есть корпус диахроний c с текстами для разных организаций, каждый с 1969 по 2019 год. Для каждой организации я хочу сравнить текст за 1969 год и текст за 1970, 1970 и 1971, и т. Д. c. Тексты в течение нескольких лет отсутствуют.

Другими словами,

У меня есть корпус, cc, который я преобразовал в dfm Теперь я хочу использовать textstat_simil:

ncsimil <- textstat_simil(dfm.cc, 
                           y = NULL,
                           selection = NULL,
                           margin = "documents",
                           method = "jaccard",
                           min_simil = NULL)

При этом каждый текст сравнивается с любым другим текстом, в результате получается 2,6+ миллиона строк. Мне действительно нужно только сравнить определенные тексты с текстом непосредственно выше, например:

TextA

TextB

Text C

TextD (имеет NA)

TextE

Итак, мне нужна статистика jaccard c для A и B

B и C, и (поскольку некоторые имеют значения NA)

D и E

Мне любопытно, что y = в textstat_simil

Пакет Quanteda говорит:

"y - необязательное соответствие целевой матрицы x в поле, на котором будет вычисляться сходство или расстояние. "

Мне не ясно, что это означает.

Означает ли это, что я могу создать два разных фрейма данных

A

B

C

D

E

и

B

C

D

E

F

Чтобы я получил статистику сходства c для

A и B

B и C

и так далее?

Или есть лучший способ сделать это?

Отредактировано, начиная здесь ... Я преобразовал в data.frame:

df <- convert(dfm.cc, to = "data.frame")

Я сделал bind_cols, чтобы добавить docvars и счетчики токенов ( 2405 столбцов - короткие тексты).

Я выделил исходные тексты в серии, например,

OrgA 1970, 1st_in_Series_Yes, TokCount 1 ... et c.

OrgA 1971, 1st_in_Series_No, TokCount 1 ... et c.

OrgA 1972, 1st_in_Series_No, TokCount 1 ... et c.

OrgA 1973, NA

OrgA 1974, 1st_in_Series_Yes, TokCount 1 ... et c.

OrgZ 1975, 1st_in_Series_No, TokCount 1 ... et c.

Чтобы не сравнивать

OrgA 1973 NA с OrgA 1972

или

OrgA 1974 с OrgA 1973

Отсюда должно работать ручное вычисление Jaccard , но, вероятно, есть более умный способ. Поделитесь пожалуйста решениями. Спасибо.

1 Ответ

1 голос
/ 06 мая 2020

Интересный вопрос. У меня нет воспроизводимого примера для работы, но я думаю, что могу создать его, используя встроенный набор данных первого корпуса. Здесь я буду использовать переменные документа Year для переменной времени и уникальное имя президента (полное) в качестве аналога для вашей организации (так как вам не нужны ежегодные сравнения различных организаций. Итак, если вы замените вашу организацию и переменную времени на те, что указаны ниже, это должно сработать. способы сделать внутреннюю часть тоже лафской. Здесь я оставил это как l oop для простоты.

Во-первых, получите уникальное имя, поскольку у некоторых (разных) президентов одинаковые фамилии .

library("quanteda")
## Package version: 2.0.1

data_corpus_inaugural$president <- paste(data_corpus_inaugural$President,
  data_corpus_inaugural$FirstName,
  sep = ", "
)
head(data_corpus_inaugural$president, 10)
##  [1] "Washington, George" "Washington, George" "Adams, John"       
##  [4] "Jefferson, Thomas"  "Jefferson, Thomas"  "Madison, James"    
##  [7] "Madison, James"     "Monroe, James"      "Monroe, James"     
## [10] "Adams, John Quincy"

Если мы сделаем этот набор уникальным, то мы сможем перебирать уникальных президентов, чтобы подгруппировать их по одному (это то, что вы будете делать с каждой из своих организаций). Мы можем сделать это с помощью corpus_subset() перед созданием dfm, и в этом, выберите только смежные пары лет. Сортировка лет означает, что i и i + 1 будут смежными. Большая часть президента У Франклина Рузвельта, у которого было четыре инаугурационных обращения, всего три пары лет. А у однопартийных президентов, таких как Картер 1977, нет никаких пар.

simpairs <- lapply(unique(data_corpus_inaugural$president), function(x) {
  dfmat <- corpus_subset(data_corpus_inaugural, president == x) %>%
    dfm(remove_punct = TRUE)
  df <- data.frame()
  years <- sort(dfmat$Year)
  for (i in seq_along(years)[-length(years)]) {
    sim <- textstat_simil(
      dfm_subset(dfmat, Year %in% c(years[i], years[i + 1])),
      method = "jaccard"
    )
    df <- rbind(df, as.data.frame(sim))
  }
  df
})

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

do.call(rbind, simpairs)
##          document1       document2    jaccard
## 1  1789-Washington 1793-Washington 0.09250399
## 2   1801-Jefferson  1805-Jefferson 0.20512821
## 3     1809-Madison    1813-Madison 0.20138889
## 4      1817-Monroe     1821-Monroe 0.29436202
## 5     1829-Jackson    1833-Jackson 0.20693928
## 6     1861-Lincoln    1865-Lincoln 0.14055885
## 7       1869-Grant      1873-Grant 0.20981595
## 8   1885-Cleveland  1893-Cleveland 0.23037543
## 9    1897-McKinley   1901-McKinley 0.25031211
## 10     1913-Wilson     1917-Wilson 0.21285564
## 11  1933-Roosevelt  1937-Roosevelt 0.20956522
## 12  1937-Roosevelt  1941-Roosevelt 0.20081549
## 13  1941-Roosevelt  1945-Roosevelt 0.18740157
## 14 1953-Eisenhower 1957-Eisenhower 0.21566976
## 15      1969-Nixon      1973-Nixon 0.23451777
## 16     1981-Reagan     1985-Reagan 0.24381368
## 17    1993-Clinton    1997-Clinton 0.24199623
## 18       2001-Bush       2005-Bush 0.24170616
## 19      2009-Obama      2013-Obama 0.24739195

Для вычисления подобия вам может потребоваться добавить дополнительные параметры в строку создания dfm - я удалил здесь только знаки препинания, но вы также можете удалить стоп-слова, числа и т. Д. c. если это то, что вы хотите.

...