Я бы хотел, чтобы в моей dfm содержалось 2-3 словосочетания (т.е. функции), у которых значение PMI превышает 3-кратное количество слов в фразе *.
PMI определяется как: pmi(фраза) = log (p (фраза) / Продукт (p (слово))
с p (фраза): вероятность фразы на основе ее относительной частоты. Продукт (p (слово): произведениевероятности каждого слова в фразе.
До сих пор я использовал следующий код, однако значения 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.
AnАльтернативный подход, который я попробовал, заключается в непосредственном применении PMI к функциям:
test_pmi <- textstat_keyness(doc_phrases_matrix_test, measure = "pmi",
sort = TRUE)
test_pmi
Однако, во-первых, здесь я получаю предупреждение, предупреждающее, что были созданы NaN, и, во-вторых, я не понимаю значения PMI (например, почему есть негатive values)?
Кто-нибудь лучше знает, как извлекать функции на основе их значений PMI, как определено выше?
Любая подсказка высоко ценится:)
* послеПарк и др. (2015)