我如何使用 quanteda bootstrap 文本可读性统计数据?
How can I bootstrap text readability statistics using quanteda?
我对 bootstrapping 和用于文本分析的 quanteda 包都不熟悉。我有大量按文档组类型组织的文本语料库,我想获得这些文本的可读性分数。我可以使用以下函数轻松获得每个组的可读性分数:
textstat_readability(texts(mwe, groups = "document"), "Flesch")
然后我想 bootstrap 通过包装一个函数来获得 95% 置信区间的结果:
b_readability <- function(x, i, groups = NULL, measure = "Flesch")
textstat_readability(texts(x[i], groups = groups), measure)
n <- 10
groups <- factor(mwe[["document"]]$document)
b <- boot(texts(mwe), b_readability, strata = groups, R = n, groups = groups)
colnames(b$t) <- names(b$t0)
apply(b$t, 2, quantile, c(.025, .5, .975))
但是 "b <-" 失败并出现以下错误:
"Error in t.star[r, ] <- res[[r]] : incorrect number of subscripts on matrix"
我已经浪费了两天时间尝试调试,但没有成功。我究竟做错了什么?非常感谢任何建议...
MWE:
mwe<-structure(list(document = structure(c(1L, 1L),
.Label = c("a", "b", "c", "d", "e"), class = "factor"), text = c("Text 1. Text 1.1", "Text 2."), section = structure(2:1, .Label = c("aa", "bb", "cc", "dd", "ee", "ff", "hh", "ii", "jj", "kk"), class = "factor"), year = c(1919L, 1944L), preamble = structure(8:9, .Label = c("1", "2","3", " 4 ", "5", "6 ", "7 ", "8 ", "9 ", "10 "), class = "factor"), articles = c(43L, 47L), pages = c(5.218, 7.666), wordcount = c(3503L, 4929L), mean_articles = c(45, 45)), row.names = 1:2, class = "data.frame")
mwe <- corpus(mwe)
b_readability <- function(x, i, groups = NULL, measure = "Flesch")
textstat_readability(texts(x[i], groups = groups), measure)
n <- 10
groups <- factor(mwe[["document"]]$document)
b <- boot(texts(mwe), b_readability, strata = groups, R = n, groups = groups)
colnames(b$t) <- names(b$t0)
apply(b$t, 2, quantile, c(.025, .5, .975))
一个很好的问题,涉及对 boot 包以及如何在 quanteda 中索引和分组语料库文本的很多了解。这是最好的(目前)和最安全的方法。 "Safest" 这里的意思是面向未来,因为有些东西目前在 quanteda 语料库的内部寻址中有效,但在即将到来的 v2 中将无效。 (我们在 ?corpus
中非常清楚地警告了这一点,但似乎没有人注意到这个警告...)还请注意,虽然这应该始终有效,但我们还计划在未来的版本中使用更直接的方法来引导文本统计信息不需要用户深入研究 boot 包。
让我们先从内置对象中尝试一个可重现的例子。对于 "bootstrap" 一个文本,我们将使用句子级重采样(带替换)从原始文本构建一个新的假设文本,并使用 texts(x, groups = "<groupvar>")
将其拼凑成一种假设的文本。 (这就是我在 post 末尾的两个参考文献中所做的。)为了实现这一点,我们可以利用 texts()
的 属性 来获取文本来自语料库对象,但也适用于字符对象(但具有快速分组)。
为了得到句子,在对语料库进行子集化以简化我们这里的示例之后,我们将其重塑为句子。
但是,首先,我将原始文档的名称记录在一个新的文档变量中,以便我们以后可以使用它进行分组。在此示例中,我们也可以使用 Year,但这样做对任何示例都适用。 (有一些关于我们可能使用过的原始文档名的内部记录,但这样做是面向未来的。)
library("quanteda")
## Package version: 1.4.1
library("boot")
docvars(data_corpus_inaugural, "docnameorig") <- docnames(data_corpus_inaugural)
sent_corpus <- data_corpus_inaugural %>%
corpus_subset(Year > 2000) %>%
corpus_reshape(to = "sentences")
然后我们必须定义要引导的函数。我们将使用 "index" 方法并调用索引 i
(如上所示)。在这里,x
将是一个 character
而 不是 一个语料库,即使我们将调用 texts()
再次使用分组变量来重新组装它。这还需要 return 一个 向量 而不是 data.frame,后者是 textstat_*()
return 的正常形式。因此,我们将仅提取 measure
列并将其 return 作为向量。
b_readability <- function(x, i, groups = NULL, measure = "Flesch") {
textstat_readability(texts(x[i], groups = groups[i]), measure)[[measure]]
}
我们将调用我们的分组变量 simgroups
只是为了区分参数名称的值,并将其用于 groups
参数和 strata
的调用中 boot()
。 strata
是 boot()
的参数,而 groups
传递给我们的函数 b_readability()
。我们需要对这个分组变量进行因式分解,因为该函数似乎需要这样做。然后我们调用 boot()
并得到我们的答案。
simgroups <- factor(docvars(sent_corpus, "docnameorig"))
boot(texts(sent_corpus), b_readability, R = 10,
strata = simgroups, groups = simgroups)
##
## STRATIFIED BOOTSTRAP
##
##
## Call:
## boot(data = texts(sent_corpus), statistic = b_readability, R = 10,
## strata = simgroups, groups = simgroups)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 60.22723 -0.01454477 2.457416
## t2* 53.23332 1.24942328 2.564719
## t3* 60.56705 1.07426297 1.996705
## t4* 53.55532 -0.28971190 1.943986
## t5* 58.63471 0.52289051 2.502101
这些对应于五个(原始)文档,此处以年份区分,但不幸的是,这些名称已被替换为 t1
、t2
、... return来自 boot()
的对象。
至return您的原始示例,假设这些形成来自一个层的两个文档(因为它们太短,两个进一步细分)。那么:
simgroups <- rep(1, ndoc(mwe))
boot(texts(mwe), b_readability, R = 10, strata = simgroups, groups = simgroups)
##
## STRATIFIED BOOTSTRAP
##
##
## Call:
## boot(data = texts(mwe), statistic = b_readability, R = 10, strata = simgroups,
## groups = simgroups)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 119.19 0.6428333 0.4902916
我对 bootstrapping 和用于文本分析的 quanteda 包都不熟悉。我有大量按文档组类型组织的文本语料库,我想获得这些文本的可读性分数。我可以使用以下函数轻松获得每个组的可读性分数:
textstat_readability(texts(mwe, groups = "document"), "Flesch")
然后我想 bootstrap 通过包装一个函数来获得 95% 置信区间的结果:
b_readability <- function(x, i, groups = NULL, measure = "Flesch")
textstat_readability(texts(x[i], groups = groups), measure)
n <- 10
groups <- factor(mwe[["document"]]$document)
b <- boot(texts(mwe), b_readability, strata = groups, R = n, groups = groups)
colnames(b$t) <- names(b$t0)
apply(b$t, 2, quantile, c(.025, .5, .975))
但是 "b <-" 失败并出现以下错误: "Error in t.star[r, ] <- res[[r]] : incorrect number of subscripts on matrix"
我已经浪费了两天时间尝试调试,但没有成功。我究竟做错了什么?非常感谢任何建议...
MWE:
mwe<-structure(list(document = structure(c(1L, 1L),
.Label = c("a", "b", "c", "d", "e"), class = "factor"), text = c("Text 1. Text 1.1", "Text 2."), section = structure(2:1, .Label = c("aa", "bb", "cc", "dd", "ee", "ff", "hh", "ii", "jj", "kk"), class = "factor"), year = c(1919L, 1944L), preamble = structure(8:9, .Label = c("1", "2","3", " 4 ", "5", "6 ", "7 ", "8 ", "9 ", "10 "), class = "factor"), articles = c(43L, 47L), pages = c(5.218, 7.666), wordcount = c(3503L, 4929L), mean_articles = c(45, 45)), row.names = 1:2, class = "data.frame")
mwe <- corpus(mwe)
b_readability <- function(x, i, groups = NULL, measure = "Flesch")
textstat_readability(texts(x[i], groups = groups), measure)
n <- 10
groups <- factor(mwe[["document"]]$document)
b <- boot(texts(mwe), b_readability, strata = groups, R = n, groups = groups)
colnames(b$t) <- names(b$t0)
apply(b$t, 2, quantile, c(.025, .5, .975))
一个很好的问题,涉及对 boot 包以及如何在 quanteda 中索引和分组语料库文本的很多了解。这是最好的(目前)和最安全的方法。 "Safest" 这里的意思是面向未来,因为有些东西目前在 quanteda 语料库的内部寻址中有效,但在即将到来的 v2 中将无效。 (我们在 ?corpus
中非常清楚地警告了这一点,但似乎没有人注意到这个警告...)还请注意,虽然这应该始终有效,但我们还计划在未来的版本中使用更直接的方法来引导文本统计信息不需要用户深入研究 boot 包。
让我们先从内置对象中尝试一个可重现的例子。对于 "bootstrap" 一个文本,我们将使用句子级重采样(带替换)从原始文本构建一个新的假设文本,并使用 texts(x, groups = "<groupvar>")
将其拼凑成一种假设的文本。 (这就是我在 post 末尾的两个参考文献中所做的。)为了实现这一点,我们可以利用 texts()
的 属性 来获取文本来自语料库对象,但也适用于字符对象(但具有快速分组)。
为了得到句子,在对语料库进行子集化以简化我们这里的示例之后,我们将其重塑为句子。
但是,首先,我将原始文档的名称记录在一个新的文档变量中,以便我们以后可以使用它进行分组。在此示例中,我们也可以使用 Year,但这样做对任何示例都适用。 (有一些关于我们可能使用过的原始文档名的内部记录,但这样做是面向未来的。)
library("quanteda")
## Package version: 1.4.1
library("boot")
docvars(data_corpus_inaugural, "docnameorig") <- docnames(data_corpus_inaugural)
sent_corpus <- data_corpus_inaugural %>%
corpus_subset(Year > 2000) %>%
corpus_reshape(to = "sentences")
然后我们必须定义要引导的函数。我们将使用 "index" 方法并调用索引 i
(如上所示)。在这里,x
将是一个 character
而 不是 一个语料库,即使我们将调用 texts()
再次使用分组变量来重新组装它。这还需要 return 一个 向量 而不是 data.frame,后者是 textstat_*()
return 的正常形式。因此,我们将仅提取 measure
列并将其 return 作为向量。
b_readability <- function(x, i, groups = NULL, measure = "Flesch") {
textstat_readability(texts(x[i], groups = groups[i]), measure)[[measure]]
}
我们将调用我们的分组变量 simgroups
只是为了区分参数名称的值,并将其用于 groups
参数和 strata
的调用中 boot()
。 strata
是 boot()
的参数,而 groups
传递给我们的函数 b_readability()
。我们需要对这个分组变量进行因式分解,因为该函数似乎需要这样做。然后我们调用 boot()
并得到我们的答案。
simgroups <- factor(docvars(sent_corpus, "docnameorig"))
boot(texts(sent_corpus), b_readability, R = 10,
strata = simgroups, groups = simgroups)
##
## STRATIFIED BOOTSTRAP
##
##
## Call:
## boot(data = texts(sent_corpus), statistic = b_readability, R = 10,
## strata = simgroups, groups = simgroups)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 60.22723 -0.01454477 2.457416
## t2* 53.23332 1.24942328 2.564719
## t3* 60.56705 1.07426297 1.996705
## t4* 53.55532 -0.28971190 1.943986
## t5* 58.63471 0.52289051 2.502101
这些对应于五个(原始)文档,此处以年份区分,但不幸的是,这些名称已被替换为 t1
、t2
、... return来自 boot()
的对象。
至return您的原始示例,假设这些形成来自一个层的两个文档(因为它们太短,两个进一步细分)。那么:
simgroups <- rep(1, ndoc(mwe))
boot(texts(mwe), b_readability, R = 10, strata = simgroups, groups = simgroups)
##
## STRATIFIED BOOTSTRAP
##
##
## Call:
## boot(data = texts(mwe), statistic = b_readability, R = 10, strata = simgroups,
## groups = simgroups)
##
##
## Bootstrap Statistics :
## original bias std. error
## t1* 119.19 0.6428333 0.4902916