【问题标题】:Language based processing in R: Selecting features in dfm with certain pointwise mutual information (PMI) valueR 中基于语言的处理:在 dfm 中选择具有特定逐点互信息 (PMI) 值的特征
【发布时间】:2019-05-17 01:34:17
【问题描述】:

我想在我的 dfm 中保留 2-3 个单词的短语(即特征),它们的 PMI 值大于短语中单词数的 3 倍*。

PMI在此定义为:pmi(phrase) = log(p(phrase)/Product(p(word))

与 p(phrase):基于其相对频率的短语的概率 Product(p(word):词组中每个单词的概率的乘积。

到目前为止,我使用了以下代码,但 PMI 值似乎不正确,但我无法找到问题:

#creating dummy data
id <- c(1:5)
text <- c("positiveemoticon my name is positiveemoticon positiveemoticon i love you", "hello dont", "i love you", "i love you", "happy birthday")
ids_text_clean_test <- data.frame(id, text)
ids_text_clean_test$id <- as.character(ids_text_clean_test$id)
ids_text_clean_test$text <- as.character(ids_text_clean_test$text)

test_corpus <- corpus(ids_text_clean_test[["text"]], docnames = ids_text_clean_test[["id"]])

tokens_all_test <- tokens(test_corpus, remove_punct = TRUE)

## Create a document-feature matrix(dfm)
doc_phrases_matrix_test <- dfm(tokens_all_test, ngrams = 2:3) #extracting two- and three word phrases
doc_phrases_matrix_test

# calculating the pointwise mututal information for each phrase to identify phrases that occur at rates much higher than chance
tcmrs = Matrix::rowSums(doc_phrases_matrix_test) #number of words per user
tcmcs = Matrix::colSums(doc_phrases_matrix_test) #counts of each phrase
N = sum(tcmrs) #number of total words used 
colp = tcmcs/N #proportion of the phrases by total phrases
rowp = tcmrs/N #proportion of each users' words used by total words used
pp = doc_phrases_matrix_test@p + 1
ip = doc_phrases_matrix_test@i + 1
tmpx = rep(0,length(doc_phrases_matrix_test@x)) # new values go here, just a numeric vector
# iterate through sparse matrix:
for (i in 1:(length(doc_phrases_matrix_test@p) - 1) ) {
  ind = pp[i]:(pp[i + 1] - 1)
  not0 = ip[ind]
  icol = doc_phrases_matrix_test@x[ind]
  tmp = log( (icol/N) / (rowp[not0] * colp[i] )) # PMI
  tmpx[ind] = tmp
}

doc_phrases_matrix_test@x = tmpx
doc_phrases_matrix_test

我相信 PMI 不应该在一个短语内因用户而异,但我认为将 PMI 直接应用于 dfm 会更容易,因此更容易根据 PMI 功能对其进行子集化。

我尝试的另一种方法是将 PMI 直接应用于功能:

test_pmi <- textstat_keyness(doc_phrases_matrix_test,  measure =  "pmi",
                             sort = TRUE)
test_pmi

但是,首先,我收到一个警告,警告说产生了 NaN,其次,我不了解 PMI 值(例如,为什么会有负值)?

有没有人知道如何根据上面定义的 PMI 值提取特征?

任何提示都非常感谢:)

*继 Park 等人(2015 年)之后

【问题讨论】:

  • 您的编程问题到底是什么?
  • 问题是:我使用什么代码(如何调整提供的代码)来找到每个功能的正确 PMI 值,以便我可以相应地对我的 dfm 进行子集化。 (我会尝试修改我上面的问题以使其更清楚,谢谢)
  • 还可以根据您的数据添加您期望的 pmi 输出。
  • pmi 是一种关联度量,问题的不清楚之处在于您要将阶段的出现与什么关联。 textstat_keyness() 使用参考分区计算 dfm 的一个分区,以找出目标中出现的短语相对于参考的几率更大。在这里,不清楚您希望作为比较集的内容。还有用于稀疏矩阵对象的运算符,使您无需遍历元素方法。
  • 我不知道如何重新打开它,但这就是我将如何使用 udpipe R 包library(udpipe) data(brussels_reviews_anno) x &lt;- subset(brussels_reviews_anno, language %in% "fr") ## find keywords with PMI &gt; 3 keyw &lt;- keywords_collocation(x, term = "lemma", group = c("doc_id", "sentence_id"), ngram_max = 3, n_min = 10) keyw &lt;- subset(keyw, pmi &gt; 3) ## recodes to keywords x$term &lt;- txt_recode_ngram(x$lemma, compound = keyw$keyword, ngram = keyw$ngram) ## create DTM dtm &lt;- document_term_frequencies(x = x$term, document = x$doc_id) dtm &lt;- document_term_matrix(dtm)

标签: r machine-learning statistics nlp quanteda


【解决方案1】:

您可以使用以下使用 udpipe R 包的 R 代码来获取您所要求的内容。作为 udpipe 一部分的标记化 data.frame 示例

library(udpipe) 
data(brussels_reviews_anno, package = "udpipe") 
x <- subset(brussels_reviews_anno, language %in% "fr") 

## find keywords with PMI > 3 
keyw <- keywords_collocation(x, term = "lemma", 
                             group = c("doc_id", "sentence_id"), ngram_max = 3, n_min = 10) 
keyw <- subset(keyw, pmi > 3) 

## recodes to keywords 
x$term <- txt_recode_ngram(x$lemma, compound = keyw$keyword, ngram = keyw$ngram) 
## create DTM 
dtm <- document_term_frequencies(x = x$term, document = x$doc_id) 
dtm <- document_term_matrix(dtm) 

如果你想得到一个与 x 结构相似的数据集。只需使用 udpipe(text, "english") 或您选择的任何语言。如果您想使用 quanteda 进行标记化,您仍然可以将其放入更丰富的 data.frame 中 - 例如herehere。在 udpipe R 包的帮助下,它有很多小插图 (?udpipe)。

注意 PMI 很有用,使用 udpipe R 包的依赖解析输出会更有用。如果您查看 dep_rel 字段,您会发现有识别多词表达式的类别(例如,dep_rel 固定/扁平/复合是在http://universaldependencies.org/u/dep/index.html 中定义的多词表达式)您也可以使用这些将它们放入您的文档/术语中/矩阵

【讨论】:

  • 非常感谢,非常有帮助! :) 尽管重新编码关键字(txt_recode_ngram)似乎有些奇怪:使用您的示例,不应该用关键字替换 x$lemma 吗?对我来说,引理列保持不变
  • 如果单词序列是关键字的一部分,则词条会被更新。如果不是,它会保留当前的引理。如果您只想在数据中包含这些多标记关键字,请使用简单的 ifelse 逻辑 (ifelse(x$term %in% keyw$keyword, x$term, NA)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 2016-02-25
  • 1970-01-01
  • 2013-02-17
  • 2020-10-09
相关资源
最近更新 更多