Trains the dual-attention hypergraph network of Ding et al. (2020) –
every document becomes its own hypergraph (its unique words as
vertices, its sentences as hyperedges), two attention layers aggregate
words into sentence and optional LDA-topic hyperedges and those hyperedges
back into words, and a masked mean
pool feeds a linear classifier. Inductive: only labeled documents are
trained on, and every document (labeled or not) is scored. Needs the
suggested torch package. Semantics follow the official
implementation. semantic = "none" reproduces its sentence-only
("w/o semantic") ablation. semantic = "lda" adds the full paper path:
online variational-Bayes LDA is fitted to labeled documents only, with the
topic count defaulting to the number of classes, and each document receives
one edge per topic containing the topic's top words present in that document.
Usage
hg_hypergat(
x,
labels,
column = NULL,
id = NULL,
stop_words = stop_words_en(),
min_count = 1L,
lowercase = TRUE,
semantic = c("none", "lda"),
lda_keywords = NULL,
lda_topics = NULL,
lda_top_n = 10L,
lda_max_iter = 10L,
lda_batch_size = 128L,
lda_offset = 50,
lda_decay = 0.7,
lda_seed = 0L,
embed_dim = 300L,
hidden = 100L,
epochs = 10L,
lr = 0.001,
dropout = 0.3,
batch_size = 8L,
weight_decay = 1e-06,
lr_decay = 0.1,
lr_step = 3L,
validation = 0.1,
class_weights = c("balanced", "none"),
embeddings = NULL,
seed = 1L,
verbose = FALSE,
what = c("predictions", "attention")
)
text_hypergat(
x,
labels,
column = NULL,
id = NULL,
stop_words = stop_words_en(),
min_count = 1L,
lowercase = TRUE,
semantic = c("none", "lda"),
lda_keywords = NULL,
lda_topics = NULL,
lda_top_n = 10L,
lda_max_iter = 10L,
lda_batch_size = 128L,
lda_offset = 50,
lda_decay = 0.7,
lda_seed = 0L,
embed_dim = 300L,
hidden = 100L,
epochs = 10L,
lr = 0.001,
dropout = 0.3,
batch_size = 8L,
weight_decay = 1e-06,
lr_decay = 0.1,
lr_step = 3L,
validation = 0.1,
class_weights = c("balanced", "none"),
embeddings = NULL,
seed = 1L,
verbose = FALSE,
what = c("predictions", "attention")
)Arguments
- x
A character vector of documents (names become ids) or a data.frame with a text column.
- labels
The known labels: a named character vector (names are document ids, values class labels) or a tidy data.frame with a
nodecolumn and alabel,clusterorpredictedcolumn. At least two classes.- column, id
When
xis a data.frame: the text column and the optional id column, as intext_hypergraph().- stop_words
Words removed before building sentences (default
stop_words_en()).- min_count
Minimum corpus frequency for a word to become a vertex.
- lowercase
Lowercase the text first.
- semantic
"none"(default) for sentence hyperedges only, or"lda"to append the paper's semantic topic hyperedges.- lda_keywords
Optional precomputed topic keywords: a list of character vectors, one per topic. With
semantic = "lda",NULLfits LDA natively; supplying the list bypasses fitting and reproduces a saved official preprocessing run.- lda_topics
Number of LDA topics.
NULL(default) uses the number of classes, as in the paper. Ignored whenlda_keywordsis supplied.- lda_top_n
Number of highest-probability words per fitted topic (paper default 10).
- lda_max_iter, lda_batch_size
Online variational-Bayes passes and minibatch size (scikit-learn defaults used by the official code: 10 and 128).
- lda_offset, lda_decay
Online learning schedule (official values 50 and 0.7).
- lda_seed
LDA initialization seed (official value 0), separate from the neural training
seed.Embedding and hidden width (official defaults 300 and 100).
- epochs, lr, dropout, batch_size, weight_decay
Training hyperparameters (official defaults: 10, 0.001, 0.3, 8, 1e-6).
- lr_decay, lr_step
StepLR schedule: multiply the learning rate by
lr_decayeverylr_stepepochs (official 0.1 every 3).- validation
Fraction of the labeled documents held out (stratified) to pick the best epoch;
0keeps the final weights.- class_weights
"balanced"(default, inverse-frequency loss weights as in the official run script) or"none".- embeddings
Optional pretrained word-vector matrix (rownames are words,
embed_dimcolumns); words not covered keep their random initialization.- seed
Integer seed (R and torch); results are deterministic given a seed.
- verbose
Message the loss each epoch.
- what
"predictions"(default) returns the per-document classification table;"attention"returns the trained network's node-level attention per document and word, the inputhg_keywords(type = "attention")takes.
Value
With what = "predictions", a base data.frame, one row per
(kept) document: node, label (the given label or NA),
predicted, score (softmax probability of the winning class),
margin (winner minus runner-up). The training history is attached
as attribute "history" (epoch, loss, val_accuracy).
Attribute "semantic" records the topic keywords and LDA settings.
With what = "attention", a base data.frame, one row per
(document, word) pair: node, word, attention (the word's
node-level attention weights from the first attention layer, the
one that attends over the word embeddings, in evaluation mode, summed
over the hyperedges it belongs to – each hyperedge's weights sum to
one, so a document's attention column sums to its hyperedge count),
attention_2 (the same from the second layer) and n_edges (how many
of the document's hyperedges contain the word). Ordered by node,
then word. The second layer attends over first-layer outputs, which
are identical for every word of a document that has a single hyperedge
(one sentence), so attention_2 is uniform within such documents by
construction; hg_keywords(type = "attention") uses attention.
References
Ding, K., Wang, J., Li, J., Li, D., & Liu, H. (2020). Be more with less: Hypergraph attention networks for inductive text classification. EMNLP 2020.
Examples
# \donttest{
if (requireNamespace("torch", quietly = TRUE)) {
docs <- c(
cooking_1 = "Simmer the soup. Add onions and carrots.",
cooking_2 = "This soup recipe needs salt. Serve on a cold night.",
space_1 = "The telescope revealed a galaxy. Stars everywhere.",
space_2 = "Astronomers aimed the telescope. The stars were sharp."
)
hg_hypergat(docs, labels = c(cooking_1 = "cooking", space_1 = "space"),
embed_dim = 16, hidden = 8, epochs = 5, validation = 0)
}
# }