Implicit Word Network
Implicit Word Network extracts and explores (contextual) implicit entity networks from text corpora: cooccurrence graphs over named entities and terms in which relations are weighted by the sentence distance of their mentions. The model was introduced by Spitz & Gertz and powers entity-centric corpus exploration tools such as ECCE.
Documentation: https://julianschelb.github.io/implicit-word-network/
Features
- Pluggable entity extraction – spaCy NER, zero-shot NER with
GLiNER v2.5,
offline gazetteers, or your own
BaseEntityExtractor. - Vectorised network construction – entity–entity weights
ω(v, w) = Σ exp(−δ)are computed with sparse matrix products and updated incrementally as documents are added. - Provenance – every edge can be expanded into its cooccurrence instances and the sentence contexts they stem from.
- LOAD/EVELIN queries – directed importance weights
log(|Y| / |N(x) ∩ Y|) · ωand ranking of related entities, summarising sentences and documents for one or more query entities. - Contextual edges (CIEN) – cluster the contexts of an edge with DBSCAN over bag-of-words or sentence-transformer embeddings, on demand or batched.
- Interoperability – export to NetworkX, JSON, CSV edge lists, pandas, GraphML/GEXF; save and reload full networks.
- Validated – property-based tests check the engine against a literal implementation of the published definitions and against the original 0.0.x code; the vectorised builder is 25× faster than the original and processes about 1.4 M tokens/s.
- Typed, tested, documented – Python 3.10+, mypy-clean, offline test suite, MkDocs Material docs with an executed example notebook.
Installation
pip install implicit-word-network
# entity extraction backends (choose one or more)
pip install "implicit-word-network[spacy]" && python -m spacy download en_core_web_sm
pip install "implicit-word-network[gliner]"
# optional: neural context embeddings, plotting, pandas export, everything
pip install "implicit-word-network[embeddings]"
pip install "implicit-word-network[viz]"
pip install "implicit-word-network[all]"
Quick Start
from implicit_word_network import Corpus, GLiNEREntityExtractor, ImplicitNetworkPipeline
# 1. Load documents (one per line; CSV and Python lists work too)
corpus = Corpus.from_txt("documents.txt")
# 2. Choose an extractor – GLiNER accepts arbitrary labels
extractor = GLiNEREntityExtractor(
"gliner-community/gliner_medium-v2.5",
labels=["person", "organization", "location", "award"],
threshold=0.5,
)
# 3. Build the network (window = cooccurrence distance in sentences)
pipeline = ImplicitNetworkPipeline(extractor, window=2)
network = pipeline.run(corpus, show_progress=True)
print(network.summary())
# 4. Explore
for edge in network.edges(top_k=10):
print(f"{edge.weight:6.2f} {edge.source.text} -- {edge.target.text}")
feynman = network.entity("Feynman", "person")
network.neighbors(feynman, k=5) # strongest related entities
network.entity_terms(feynman, k=10) # characteristic terms
network.contexts(feynman, ("Nobel Prize", "award")) # where do they cooccur?
network.rank_entities([feynman, ("Nobel Prize", "award")], k=5) # LOAD/EVELIN ranking
network.rank_sentences(feynman, k=3) # summarising sentences
# 5. Export
graph = network.to_networkx(min_weight=0.5)
network.save("network.npz")
With spaCy instead of GLiNER:
from implicit_word_network import SpacyEntityExtractor
extractor = SpacyEntityExtractor("en_core_web_sm", labels=["PERSON", "ORG", "GPE", "NORP", "LOC", "WORK_OF_ART"])
Contextual implicit entity networks
Split an edge into context clusters (Spitz & Gertz, 2018; ECCE):
from implicit_word_network import ContextualEdgeClusterer, SentenceTransformerEmbedder
clusterer = ContextualEdgeClusterer(SentenceTransformerEmbedder(), eps=0.25)
for cluster in clusterer.cluster_edge(network, feynman, ("Nobel Prize", "award")):
print(cluster.size, round(cluster.weight, 2), cluster.contexts[0][:80])
Custom extractors
import re
from implicit_word_network import EntitySpan, SpanEntityExtractor
class HashtagExtractor(SpanEntityExtractor):
def extract_spans(self, texts, sentences):
return [[EntitySpan(m.start(), m.end(), "HASHTAG") for m in re.finditer(r"#\w+", t)] for t in texts]
Examples and Benchmarks
examples/example.ipynb– executed, offline walkthrough of the whole APIexamples/example.py,examples/example_gliner.py– spaCy and GLiNER scriptsbenchmarks/– synthetic corpora, construction throughput and the comparison with 0.0.x
Command-Line Interface
implicit-word-network build documents.txt -o network.json --extractor spacy --window 2
implicit-word-network build documents.csv -o network.graphml --extractor gliner --labels person company
implicit-word-network summary documents.txt --top 15
Theoretical Background
- Spitz, A. & Gertz, M. (2016). Terms over LOAD: Leveraging Named Entities for Cross-Document Extraction and Summarization of Events. SIGIR '16. https://doi.org/10.1145/2911451.2911529
- Spitz, A. & Gertz, M. (2018). Exploring Entity-centric Networks in Entangled News Streams. WWW '18 Companion. https://doi.org/10.1145/3184558.3188726
- Spitz, A. (2019). Implicit Entity Networks: A Versatile Document Model. Heidelberg University. https://doi.org/10.11588/HEIDOK.00026328
- Schelb, J., Ehrmann, M., Romanello, M. & Spitz, A. (2022). ECCE: Entity-centric Corpus Exploration Using Contextual Implicit Networks. WWW '22 Companion. https://doi.org/10.1145/3487553.3524237
Development
See DEVELOPMENT.md for setup, testing, linting, docs and the release process.
pip install -e ".[dev,spacy]"
poe check # ruff, mypy, pytest
License
MIT – see LICENSE.
Metadata
Release files for implicit-word-network 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| implicit_word_network-0.1.0.tar.gz | 65.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| implicit_word_network-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 141.7 kB
Release files / implicit_word_network-0.1.0.tar.gz
| Download URL | implicit_word_network-0.1.0.tar.gz |
|---|---|
| Size | 65.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
21887b7a925fbf1f7bf89e3c25a1a43a4dbc89e7e8e73b1cb44dfadb805667ea
|
|
BLAKE2b-256 checksum How to use checksums |
e8fb454fdb27d0a94d1257e084b4eefda62eb8e6cb7b0e0f41236db8d09c9cc2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 28, 2026.
Transparency logRelease files / implicit_word_network-0.1.0-py3-none-any.whl
| Download URL | implicit_word_network-0.1.0-py3-none-any.whl |
|---|---|
| Size | 76.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1d66b18060fcc08e79d49bca2c0d430292eda00f2db4e2df15cded9ad656ad8a
|
|
BLAKE2b-256 checksum How to use checksums |
e07b0487049b3bf73dade1cf8b65e71d7d05f71de124465e3f1377694fb421c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 28, 2026.
Transparency log