Как посчитать частоту многословных выражений в Quanteda? - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь подсчитать частоту многословных выражений в Quanteda. Я знаю, что несколько статей в корпусе содержат это выражение, так как, когда я ищу его с помощью 're' в Python, он может их найти. Однако с Quanteda это, похоже, не работает. Кто-нибудь может сказать мне, что я делаю не так?

> mwes <- phrase(c("抗美 援朝"))
> tc <- tokens_compound(toks_NK, mwes, concatenator = "")
> dfm <- dfm(tc, select="抗美援朝")
> dfm
Document-feature matrix of: 2,337 documents, 0 features and 7 docvars.
[ reached max_ndoc ... 2,331 more documents ]

Ответы [ 3 ]

2 голосов
/ 14 июля 2020

Во-первых, приносим свои извинения за то, что не могу использовать полностью китайский текст. Но вот президентское обращение, в которое я позволил себе вставить ваши слова на мандаринском диалекте:

data <- "I stand here today humbled by the task before us 抗美 援朝, 
grateful for the trust you have bestowed, mindful of the sacrifices borne by our ancestors. 
I thank President Bush for his service to our nation, 
as well as the generosity and cooperation he has shown throughout this transition.

Forty-four Americans 抗美 援朝 have now taken the presidential oath. 
The words have been spoken during rising tides of prosperity 
and the still waters of peace. Yet, every so often the oath 抗美 援朝
is taken amidst gathering clouds and raging storms. At these moments, 
America has carried on not simply because of the skill or vision of those in high office, 
but because We the People 抗美 援朝 have remained faithful to the ideals of our forbearers, 
and true to our founding documents."

Что вы можете сделать, если хотите использовать quanteda, так это вычислить 4-граммы (я считать, что ваши слова состоят из четырех знаков и, следовательно, будут обрабатываться как четыре слова)

Шаг 1: разделите текст на токены слов:

data_tokens <- tokens(data, remove_punct = TRUE, remove_numbers = TRUE)

Шаг 2: вычислите 4-граммы и сделайте список их частот

fourgrams <- sort(table(unlist(as.character(tokens_ngrams(data_tokens, n = 4, concatenator = " ")))), decreasing = T)

Вы можете проверить первые десять:

fourgrams[1:10]

                抗 美 援 朝               美 援 朝 have      America has carried on          Americans 抗 美 援 
                          4                           2                           1                           1 
amidst gathering clouds and ancestors I thank President      and cooperation he has        and raging storms At 
                          1                           1                           1                           1 
       and the still waters             and true to our 
                          1                           1 

Если вы просто хотите узнать частоту вашего целевого соединения:

fourgrams["抗 美 援 朝"]
抗 美 援 朝 
         4 

В качестве альтернативы, и это намного проще, особенно если вы действительно интересуетесь только одним соединением, вы можете использовать str_extract_all из stringr. Это немедленно предоставит вам количество частот:

library(stringr)
length(unlist(str_extract_all(data, "抗美 援朝")))
[1] 4
1 голос
/ 15 июля 2020

Вообще говоря, лучше всего сделать словарь для поиска или составных токенов на китайском или японском языках, но значения словаря должны быть сегментированы так же, как и токены.

require(quanteda)
require(stringi)

txt <- "10月初,聯合國軍逆轉戰情,向北開進,越過38度線,終促使中华人民共和国決定出兵介入,中国称此为抗美援朝。"
lis <- list(mwe1 = "抗美援朝", mwe2 = "向北開進")

## tokenize dictionary values
lis <- lapply(lis, function(x) stri_c_list(as.list(tokens(x)), sep = " "))
dict <- dictionary(lis)

## tokenize texts and count
toks <- tokens(txt)
dfm(tokens_lookup(toks, dict))
## Document-feature matrix of: 1 document, 2 features (0.0% sparse).
##        features
## docs    mwe1 mwe2
##   text1    1    1
0 голосов
/ 14 июля 2020

Вы на правильном пути, но токенизатор по умолчанию quanteda , кажется, разделяет токены в вашей фразе на четыре символа:

> tokens("抗美 援朝")
Tokens consisting of 1 document.
text1 :
[1] "抗" "美" "援" "朝"

По этим причинам вам следует рассмотрите альтернативный токенизатор. К счастью, отличная библиотека spaCy Python предлагает средства для этого и содержит модели на китайском языке. Используя пакет spacyr и quanteda , вы можете создавать токены непосредственно из вывода spacyr::spacy_tokenize() после загрузки небольшой модели китайского языка.

Для подсчета только этих выражений , вы можете использовать комбинацию tokens_select(), а затем textstat_frequency() на dfm.

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

txt <- "Forty-four Americans 抗美 援朝 have now taken the presidential oath. 
The words have been spoken during rising tides of prosperity 
and the still waters of peace. Yet, every so often the oath 抗美 援朝
is taken amidst gathering clouds and raging storms. At these moments, 
America has carried on not simply because of the skill or vision of those in high office, 
but because We the People 抗美 援朝 have remained faithful to the ideals of our forbearers, 
and true to our founding documents."

library("spacyr")
# spacy_download_langmodel("zh_core_web_sm") # only needs to be done once
spacy_initialize(model = "zh_core_web_sm")
## Found 'spacy_condaenv'. spacyr will use this environment
## successfully initialized (spaCy Version: 2.3.2, language model: zh_core_web_sm)
## (python options: type = "condaenv", value = "spacy_condaenv")

spacy_tokenize(txt) %>%
  as.tokens() %>%
  tokens_compound(pattern = phrase("抗美 援朝"), concatenator = " ") %>%
  tokens_select("抗美 援朝") %>%
  dfm() %>%
  textstat_frequency()
##     feature frequency rank docfreq group
## 1 抗美 援朝         3    1       1   all
...