Getting Started¶
Installation¶
Text4GCN requires Python ≥ 3.10 and PyTorch ≥ 2.3. PyTorch comes from PyPI with the package: CUDA-enabled on Linux, CPU-only on Windows and macOS. For another build, install PyTorch first from pytorch.org; see Device Management.
Verify installation¶
import text4gcn
print(text4gcn.__version__)
from text4gcn.utils.device import check_pytorch_installation
info = check_pytorch_installation()
print(f"PyTorch {info['torch_version']} — CUDA: {info['cuda_available']}")
Data format¶
Each dataset needs two files in the same directory:
{dataset_name}.txt — one document per line, UTF-8 by default (pass TextPipeline(encoding="latin1"), or another encoding, for other files):
computer software engineering systems design
natural language processing machine learning algorithms
{dataset_name}.meta — tab-separated: index split label (labels may contain spaces, not tabs):
Supported split values: train, training, 20news-bydate-train, anything else is treated as test.
Cleaning keeps only ASCII letters and digits by default, as in the original TextGCN; pass TextPipeline(ascii_only=False) to keep non-ASCII letters (accented Latin, Cyrillic, Arabic, …).
Get a dataset¶
from text4gcn.datasets import download, save_corpus, twenty_newsgroups
download("R8", "data/") # R8, R52, ohsumed or pubmed (SHA-256 verified)
twenty_newsgroups("data/", name="20NG4", # via scikit-learn, official train/test split
categories=["alt.atheism", "soc.religion.christian", "comp.graphics", "sci.med"])
save_corpus("data/", "mine", # your own texts, labels and train/test splits
texts=["great movie", "boring plot"], labels=["pos", "neg"], splits=["train", "test"])
See the Datasets API and the Bring your own corpus tutorial.
The three-step pipeline¶
Step 1 — Preprocess text¶
TextPipeline cleans the corpus, shuffles train/test splits, builds a vocabulary, and extracts node feature matrices. Output is written to disk under {dataset_path}/.
from text4gcn import TextPipeline
TextPipeline(
dataset_name="R8",
dataset_path="data/",
rare_count=5, # drop words appearing fewer than 5 times
language="english", # language for stop-word removal
seed=1234,
).execute(validation_ratio=0.10)
After this step the following directories are created:
data/
R8.cleaned/ ← stop-word and rare-word filtered corpus
R8.shuffled/ ← train/test splits, vocabulary, word vectors
R8.node_features/ ← x, y, tx, ty, allx, ally (pickle files)
log/ ← pipeline execution log
Step 2 — Build the graph¶
Choose an adjacency strategy that fits your data and compute time budget. See Choosing a Builder for a comparison.
After this step:
Step 3 — Train the GCN¶
from text4gcn import GNN, Builder
result = GNN(
dataset_name="R8",
dataset_path="data/",
log_dir="logs/",
builder=Builder.Tfidf,
seed=1234,
epochs=200,
lr=0.02,
nhid=200,
dropout=0.5,
early_stopping=10,
).fit()
print(result)
# TrainingResult(accuracy=0.9712, macro_f1=0.9301, loss=0.0984, epochs=187, best_epoch=177, model_path='logs/…pth')
fit() shows a progress bar while training and ends with a summary: accuracy, macro-F1
and a per-class table. The same numbers are in the result (result.metrics,
result.report, result.confusion_matrix, and result.history per epoch). Pass
verbose=0 to silence it, or verbose=2 for one line per epoch. Accuracy and loss
plots are saved to log_dir/.
Validation ratio
The train/val split is set by TextPipeline.execute(validation_ratio=…) (default 10% of the training documents).
Minimal usage¶
All parameters except dataset_name and dataset_path have sensible defaults:
from text4gcn import GNN
result = GNN(dataset_name="R8", dataset_path="data/", seed=1234).fit()
print(f"accuracy={result.test_accuracy:.4f}")
Defaults: builder=Builder.Tfidf, log_dir=".", epochs=200, lr=0.02, nhid=200, dropout=0.5, early_stopping=10, layer=Layer.GCN, seed=1234, device=None (auto-detect), verbose=1.
With graph refinement¶
Reduce graph size and noise before training:
from text4gcn import GNN, Builder, RefinementConfig
result = GNN(
dataset_name="R8",
dataset_path="data/",
builder=Builder.Tfidf,
refinement_config=RefinementConfig(
min_doc_freq=2, # drop words in fewer than 2 documents
min_word_degree=1.0, # drop words whose edge weights sum to < 1
edge_weight_threshold=0.1, # drop very weak edges
keep_docs=True, # always preserve document nodes
),
).fit()
See Graph Refinement for the full parameter reference.
Error messages¶
If you call GNN.fit() without running a previous step, you get an actionable error:
FileNotFoundError: Node feature files not found at 'data/R8.node_features'.
Run the preprocessing step first:
from text4gcn import TextPipeline
TextPipeline(
dataset_name='R8',
dataset_path='data/',
).execute()
A missing graph names the builder call that writes it:
FileNotFoundError: Adjacency file not found at 'data/R8.adjacency/ind.embedding.word2vec.R8.adj'.
Build the 'embedding.word2vec' graph after preprocessing:
from text4gcn.builder import Semantic
Semantic(
dataset_name='R8',
dataset_path='data/',
).word2vec(training_algorithm=1, embedding_dimension=300, num_epochs=20)
The builders raise the same kind of error, with the TextPipeline command, when {dataset_path}/{dataset_name}.shuffled/ is missing.