Clusters are defined by the structure of the network, not by the content
of the nodes. To interpret them, it helps to know which words are
specific to each cluster. extract_tfidf() extracts the words and
n-grams of one or several text columns (e.g. titles, abstracts) and
returns, for each group (e.g. each cluster), the terms with the highest
tf-idf (Spärck Jones 1972; Salton and Buckley 1988)
:
$$\mathrm{tf}_{td} = \frac{n_{td}}{\sum_u n_{ud}}, \qquad
\mathrm{idf}_t = \log\frac{D}{\mathrm{df}_t}, \qquad
\text{tf-idf}_{td} = \mathrm{tf}_{td} \times \mathrm{idf}_t,$$
with \(n_{td}\) the count of term \(t\) in group \(d\), \(D\) the
number of groups and \(\mathrm{df}_t\) the number of groups containing
\(t\). A term present in every group has a tf-idf of 0.
Usage
extract_tfidf(
data,
text_columns,
grouping_columns,
grouping_across_list = FALSE,
n_gram = 2L,
stopwords_type = "smart",
stopwords_vector = NULL,
clean_word_method = c("lemmatize", "stemming", "none"),
ngrams_filter = 5L,
nb_terms = 5L
)Arguments
- data
A
tbl_graph, a list oftbl_graphs (their node tables are stacked) or a data frame.- text_columns
Character vector, the column(s) with text. Several columns are pasted together, separated by ". ".
- grouping_columns
Character vector, the column(s) defining the groups, the "documents" of the tf-idf (e.g.
"cluster_leiden").- grouping_across_list
Logical. For a list of graphs whose group identifiers repeat across graphs (cluster "01" exists in every window),
TRUEadds the name of the graph to the groups, so that each cluster of each window is a separate document. Not needed for identifiers that are already unique across the list, such as dynamic clusters.- n_gram
Integer, the maximum length of n-grams (2 by default: words and pairs of words).
- stopwords_type
Character scalar, the stop word list of
tidytext::get_stopwords()("smart"by default).- stopwords_vector
Optional character vector of stop words, used instead of
stopwords_type.- clean_word_method
"lemmatize","stemming"(with thetextstempackage) or"none"(chosen when no method is given).- ngrams_filter
Integer, the minimum number of occurrences of a term in the whole corpus (5 by default).
- nb_terms
Integer, the number of terms returned per group (5 by default).
Value
A data.table with one row per group and term, for the
nb_terms best terms of each group: the grouping columns, term, n
(count of the term in the group), tf, idf and tf_idf.
Details
The texts are lower-cased and split into n-grams of 1 to n_gram words
by tidytext::unnest_tokens() (Silge and Robinson 2017)
. Each
word is lemmatised or stemmed if requested; n-grams containing a stop
word or a number are dropped, as are terms rarer than ngrams_filter in
the corpus and terms appearing only once in a group, which would
otherwise reach the top of small groups by accident.
The choice of the groups decides what "specific" means: computed on the
clusters of one network, tf-idf finds what distinguishes a cluster from
the other clusters of the same period; computed on the stacked windows
with grouping_across_list = TRUE, it also distinguishes a cluster from
its own past and future.
Lemmatising and stemming are optional and need the textstem package. For
larger corpora or other weighting schemes, the text-mining functions of
the mintR package (https://codeberg.org/agoutsmedt/mintR) can be used
on the node table.
References
Salton G, Buckley C (1988).
“Term-Weighting Approaches in Automatic Text Retrieval.”
Information Processing & Management, 24(5), 513–523.
Silge J, Robinson D (2017).
Text Mining with R: A Tidy Approach.
O'Reilly.
Spärck Jones K (1972).
“A Statistical Interpretation of Term Specificity and Its Application in Retrieval.”
Journal of Documentation, 28(1), 11–21.
Examples
network <- build_network(
nodes = subset(Nodes_stagflation, source_type == "Stagflation"),
directed_edges = Ref_stagflation,
source_id = "source_id",
target_id = "target_id",
method = "similarity",
edges_threshold = 1
)
#> ℹ Coupling (`biblionetwork::biblio_coupling()`) with "similarity": ties
#> weighted by the idf-weighted cosine of the two lists of targets, after Shen
#> et al. (2019), between source_id entities sharing target_id entities.
#> ℹ Two source_id are linked when they share at least 1 target_id
#> (`edges_threshold`).
#> ℹ Nodes without any edge are removed (`keep_singleton = FALSE`).
network <- add_clusters(
network,
clustering_method = "leiden",
objective_function = "modularity",
seed = 123,
verbose = FALSE
)
extract_tfidf(
network,
text_columns = "source_title",
grouping_columns = "cluster_leiden",
n_gram = 2,
clean_word_method = "none",
nb_terms = 3
)
#> cluster_leiden term n tf idf tf_idf
#> <char> <char> <int> <num> <num> <num>
#> 1: 01 productivity 8 0.04705882 1.3862944 0.06523738
#> 2: 01 unemployment 7 0.04117647 1.3862944 0.05708271
#> 3: 01 prices 7 0.04117647 1.3862944 0.05708271
#> 4: 02 great inflation 21 0.11290323 1.3862944 0.15651711
#> 5: 02 stabilization 5 0.02688172 1.3862944 0.03726598
#> 6: 02 stabilization policy 5 0.02688172 1.3862944 0.03726598
#> 7: 03 oil 13 0.14942529 0.6931472 0.10357372
#> 8: 03 oil price 5 0.05747126 1.3862944 0.07967209
#> 9: 03 great stagflation 4 0.04597701 0.6931472 0.03186884
#> 10: 04 stagflation 2 0.12500000 0.2876821 0.03596026
#> 11: 04 inflation 5 0.31250000 0.0000000 0.00000000
#> 12: 04 1970s 2 0.12500000 0.0000000 0.00000000
