如何仅在组内计算相邻年份文档之间的 quanteda 相似度?

How to compute similarity in quanteda between documents for adjacent years only, within groups?

我有一个历时语料库,其中包含不同组织的文本,每个组织的时间跨度从 1969 年到 2019 年。 对于每个组织,我想比较 1969 年的文本和 1970、1970 和 1971 年等的文本。 一些年份的文本丢失了。

换句话说,

我有一个语料库,cc,我将其转换为 dfm 现在我想使用 textstat_simil:

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

这会将每个文本与其他文本进行比较,得到 2.6+ 百万行。 我真的只需要将某些文本与上面的文本进行比较,如下所示:

文本A

文本B

文本C

TextD(有 NA)

文本E

所以,我想要 jaccard 统计数据 A 和 B

B 和 C,以及(因为有些具有 NA 值)

D 和 E

我对textstat_simil

中的y =很好奇

Quanteda 包裹说

"y is an optional target matrix matching x in the margin on which the similarity or distance will be computed."

我不清楚这是什么意思。

这是否意味着我可以创建两个不同的数据框

一个

B

C

D

E

B

C

D

E

F

这样我就可以得到

的相似度统计

A 和 B

乙和丙

等等?

或者有更好的方法吗?

从这里开始编辑... 我转换为 data.frame:

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

我 bind_cols 添加了文档变量和标记计数(2,405 列 -- 短文本)。

我已将系列中的初始文本分离出来,例如,

OrgA 1970,1st_in_Series_Yes,TokCount 1...等等

OrgA 1971,1st_in_Series_No,TokCount 1...等等

OrgA 1972,1st_in_Series_No,TokCount 1...等等

OrgA 1973,北美

OrgA 1974,1st_in_Series_Yes,TokCount 1...等等

OrgZ 1975,1st_in_Series_No,TokCount 1...等等

以免比较

OrgA 1973 NA 和 OrgA 1972

OrgA 1974 与 OrgA 1973

从这里开始应该可以手动计算 Jaccard,但可能还有更聪明的方法。请分享解决方案。谢谢。

有趣的问题。我没有可以使用的可重现示例,但我认为我可以使用内置的就职语料库数据集创建一个示例。在这里,我将使用文档变量 Year 作为时间变量,并将唯一的总裁(全名)名称用作您组织的类比(因为您不想对不同组织进行逐年比较。所以如果您将您的组织和时间变量替换为下面的变量,这应该有效。

请注意,我将外部 "loop" 设为 lapply,内部是一个实际的循环,但也有巧妙的方法可以将内部部分设为 lapply。在这里,为了简单起见,我将其保留为 for 循环。

首先,取一个唯一的名字,因为有些(不同的)总统有相同的姓氏。

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"

如果我们使该集合唯一,那么我们就可以遍历唯一的总统,一次对他们进行子集化。 (这是您将对每个组织执行的操作。)我们可以在创建 dfm 之前使用 corpus_subset() 来执行此操作,并且在其中 select 只是相邻的年份对。年份的排序意味着 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 创建行中添加更多选项 - 我在这里只删除了标点符号,但如果您需要的话,您也可以删除停用词、数字等。