Skip to main content

TermXtract

CI Docs License

TermXtract is a Python library for automatic term extraction (ATE): finding the domain-specific terms in a collection of documents. It offers a range of classic unsupervised scoring methods (TF-IDF, C-Value, Weirdness, RAKE, topic models, …) and supervised methods that learn from labelled examples (AdaBoost, Roger, and transformer-based token classification).

Every method takes either a plain list of strings or a Teanga Corpus, and returns the same ATEResults object.

📖 Documentation: https://teanga.io/TermXtract/
📝 Changelog: CHANGELOG.md. TermXtract follows Semantic Versioning; before 1.0, minor releases may contain breaking changes.

Installation

TermXtract needs Python 3.10 or later. It is not yet on PyPI, so install it from GitHub:

pip install git+https://github.com/TeangaNLP/TermXtract.git

The transformer-based token-classification extractor needs PyTorch and Hugging Face Transformers, which are large, so they are an optional extra. Install them with:

pip install "termxtract[transformers] @ git+https://github.com/TeangaNLP/TermXtract.git"

All other methods work with the base install.

Quickstart

Unsupervised extraction

from termxtract import TermExtractor

corpus = [
    "Machine learning is a field of artificial intelligence.",
    "Deep learning is a subfield of machine learning.",
    "Natural language processing applies machine learning to text.",
]

extractor = TermExtractor(method="cvalue", n=2)  # consider unigrams and bigrams
results = extractor.extract(corpus)

for doc in results.terms:
    print(doc["doc_id"], doc["terms"][:3])
# doc_0 [{'term': 'machine learning', 'score': 1.0}, {'term': 'artificial intelligence', 'score': 1.0}, {'term': 'machine', 'score': 0.0}]
# ...

Each document's terms are ranked from highest to lowest score.

Pass threshold=... to keep only terms scoring at or above a minimum.

Candidates that start or end with a stopword, such as is a or of machine, are dropped by default, using a built-in list of English function words. Stopwords inside a term, as in degree of freedom, are kept. Pass stopwords=None to keep every candidate, or a list of words to use your own stopwords.

If a Teanga corpus has part-of-speech tags, pos_pattern="noun_phrase" keeps only noun phrases, such as machine learning or degree of freedom (see Using a Teanga corpus).

Methods that need a reference corpus

weirdness, domainpertinence and relevance compare the target corpus against a general-language reference corpus:

reference = [
    "The weather was pleasant and people walked in the park.",
    "She bought bread and milk at the shop on the corner.",
]

extractor = TermExtractor(method="weirdness", reference_corpus=reference, n=2)
results = extractor.extract(corpus)

Supervised extraction

Supervised methods are trained from a dictionary of candidate terms labelled 1 (term) or 0 (not a term):

from termxtract import SupervisedTermExtractor

labels = {
    "machine learning": 1,
    "deep learning": 1,
    "natural language processing": 1,
    "field": 0,
    "text": 0,
}

extractor = SupervisedTermExtractor(method="adaboost", n=3)
results = extractor.extract(corpus, labels)

The AdaBoost extractor uses Open English WordNet through the wn package. The first time it needs WordNet it downloads the oewn:2025+ lexicon into ~/.wn_data (set WN_DATA_DIR to change this). To install it ahead of time, e.g. for offline use, run python -m wn download oewn:2025+. Pass wordnet_lexicon=... to use a different lexicon.

Using a Teanga corpus

Any extractor also accepts a Teanga Corpus with a words span layer:

from teanga import Corpus

corpus = Corpus()
corpus.add_layer_meta("text")
corpus.add_layer_meta("words", layer_type="span", base="text")
doc = corpus.add_doc("Deep learning is a subfield of machine learning.")
doc.words = [(0, 4), (5, 13), (14, 16), (17, 18), (19, 27), (28, 30), (31, 38), (39, 47)]

results = TermExtractor(method="basic", n=2).extract(corpus)

Words are read from the words layer or, if there is none, from a tokens layer, as written by Teanga's CoNLL-U reader and spaCy service; pass words_layer=... to use another layer. If the corpus has part-of-speech tags in a upos or pos layer based on the words, pass pos_pattern to keep only the terms whose tags match a pattern, either "noun_phrase" or your own pattern such as "<ADJ|NOUN>*<NOUN>". See the TF-IDF tutorial.

Available methods

TermExtractor.METHODS and SupervisedTermExtractor.METHODS map each method name to its implementation, so list(TermExtractor.METHODS) lists the available methods. Passing an unknown method raises a ValueError that lists them too.

Unsupervised — TermExtractor(method=...)

method Description Extra parameters
tfidf Term frequency–inverse document frequency
ridf Residual IDF
cvalue C-Value (nested multi-word terms)
basic Basic alpha
combobasic ComboBasic alpha, beta
rake Rapid Automatic Keyword Extraction stoplist, phrase_delimiters (required)
domaincoherence Domain coherence window_size
domainpertinence Domain pertinence reference_corpus (required)
weirdness Weirdness reference_corpus (required)
relevance Relevance reference_corpus (required)
topicmodeling LDA topic-model-based scoring num_topics
nmf NMF topic-model-based scoring n_topics, max_features

All methods accept n (maximum n-gram length), threshold (minimum score), stopwords (default "english"), and, for Teanga input, words_layer, pos_pattern and pos_layer. rake does not use n, stopwords or words_layer; it splits candidates at its own stoplist.

Supervised — SupervisedTermExtractor(method=...)

method Description Extra parameters
adaboost AdaBoost over linguistic and statistical features threshold, max_depth, n_estimators, estimator, wordnet_lexicon
roger Ranking function of association measures, learned by evolution (multi-word terms only) population_size, offspring_size, generations, runs, random_state
token-classification Fine-tuned Hugging Face token-classification model (needs the transformers extra) model_name, epochs, batch_size, learning_rate, max_length, language

All supervised methods accept n (maximum n-gram length, default 6), and stopwords and pos_pattern, which filter the extracted terms but not the training candidates, and words_layer and pos_layer for Teanga input.

Results

extract() returns an ATEResults object with:

  • results.terms: one entry per document, {"doc_id": ..., "terms": [{"term": str, "score": float}, ...]}, with terms ranked from highest to lowest score. Every method uses this format.
  • results.offsets: for Teanga input, one entry per document, {"doc_id": ..., "offsets": [{"term": str, "offset": (start, end)}, ...]}, giving the character offsets of every occurrence of each extracted term. It is None for plain-text input, and for nmf and domaincoherence, which score terms over the whole corpus rather than per document.
  • results.corpus: the input corpus.

Development

git clone https://github.com/TeangaNLP/TermXtract.git
cd TermXtract
poetry install --with dev --extras transformers

poetry run pytest                              # run the test suite
poetry run pytest --cov                        # ...with a coverage report
poetry run ruff check termxtract tests         # lint
poetry run ruff format termxtract tests        # format
poetry run mypy termxtract                     # type check
poetry run mkdocs serve                        # preview the docs locally

CI runs all of these on every pull request, with the tests on Python 3.10–3.12, on Linux, macOS and Windows, and against the oldest dependency versions pyproject.toml allows. The codebase was reformatted in one commit, which git blame can skip with git config blame.ignoreRevsFile .git-blame-ignore-revs.

Releasing

Version numbers follow Semantic Versioning: bump the patch version for bug fixes, the minor version for new features, and the major version for breaking changes (before 1.0, breaking changes bump the minor version).

  1. In CHANGELOG.md, rename ## [Unreleased] to ## [X.Y.Z] - YYYY-MM-DD, add a new empty ## [Unreleased] section above it, and update the comparison links at the bottom of the file.
  2. Set the version with poetry version X.Y.Z (or poetry version patch, minor or major).
  3. Commit both files as Release X.Y.Z and get the commit onto main.
  4. On GitHub, draft a release with a new tag vX.Y.Z on that commit, paste the changelog section as the release notes, and publish it. The release workflow checks that the tag matches the version, builds the package and uploads it to PyPI.

pyproject.toml is still at 0.1.0 and nothing has been published, so the first release can be 0.1.0 without a version bump.

License

TermXtract is licensed under the Apache License 2.0, the same license as Teanga.

Metadata

Release files for termxtract 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for termxtract 0.1.0
File Size Uploaded Provenance Actions
termxtract-0.1.0.tar.gz 42.3 kB With provenance Details for termxtract-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for termxtract 0.1.0
File Interpreter ABI Platform Actions
termxtract-0.1.0-py3-none-any.whl Python 3 none any Details for termxtract-0.1.0-py3-none-any.whl

Total release size: 99.8 kB

Release files / termxtract-0.1.0.tar.gz

Download URL termxtract-0.1.0.tar.gz
Size 42.3 kB
Tags Source
SHA-256 checksum
How to use checksums
bdc272ea5b4ec8c4e1a89701c1f712750b662c2327643a56937701b2939491fc
BLAKE2b-256 checksum
How to use checksums
a8ae03ccd746b04346f8807eb77a2fbc8882275c3925b744f6ba09c3731a7d50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Release files / termxtract-0.1.0-py3-none-any.whl

Download URL termxtract-0.1.0-py3-none-any.whl
Size 57.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dd88edb911f16dcd01d528797b76c34c96a9fbae01d659720c6d4bc292a68140
BLAKE2b-256 checksum
How to use checksums
9ede5f46749218ee4dc8835cc4f13e83ae4a3faf613f3d97b30f4684f23891b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

Security for termxtract 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for termxtract-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page