Model or dataset
hiDaDeng/cntext avatar
hiDaDeng/cntext

cntext: a Python library for Chinese social science text analysis and WEPA semantic projection

cntext is a Python library for social science text analysis, offering word frequency, sentiment, word embeddings, and semantic projection to measure constructs like attitudes and psychological states from Chinese text.

465 stars43 forksPythonMIT

At a glance

What is it?
cntext bundles file readers, dictionary sentiment scoring, word embeddings and the Word Embedding Projection Approach into one Python package. It is built for researchers who need reproducible construct measurement from Chinese or English text, not for production NLP pipelines.
Who is it for?
Adopt cntext if you are a social scientist who needs dictionary scoring, readability metrics and embedding-based construct scores in one Python package, and if you are willing to build and validate your own anchor dictionaries. Do not adopt it if you need a maintained production NLP service, GPU-scale training, or a library whose every function is covered by tests and docs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 138 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What cntext is for, and who should reach for it

cntext is a Python package for computational social science. Its stated audience is researchers who work with text data and need file reading, dictionary-based analysis, word frequency statistics, readability, similarity, word embeddings, semantic projection, plotting and LLM-assisted structured text analysis. The pyproject.toml description is narrower and older: it calls the package a Chinese text analysis library that can perform word frequency statistics, dictionary expansion, sentiment analysis, similarity, readability, co-occurrence analysis and social computing on attitude, prejudice and culture. The README has moved on from that framing. It now foregrounds the Word Embedding Projection Approach, or WEPA, described in a manuscript titled Measuring Psychological Constructs from Social Media Text Using the Word Embedding Projection Approach.

That shift matters for adoption. If you want a general-purpose Chinese NLP toolkit, cntext still offers one: jieba tokenisation, YAML sentiment dictionaries, readability scores, word2vec and GloVe training, and Chinese font handling for matplotlib. If you want to measure a construct such as goal commitment or attitude from text, the WEPA workflow is the part the repository is now organised around, including a WEPA-DEMO directory with three reproducible workflow files and a reviewer entry point at WEPA-DEMO/01-WEPA-Intro.md.

The package is not a service and not a pretrained model. It is a toolbox. You supply the corpus, the dictionaries and, in the embedding case, the trained vectors.

How WEPA turns anchor words into a text score

WEPA represents a psychological or social construct as a semantic axis inside a word-embedding space. The axis is defined by two sets of theory-based anchor words: a positive pole and a negative pole. A text is then projected onto that axis, and the resulting position becomes a text-based indicator of construct-related linguistic salience.

The README is explicit about the data flow. First you load a trained embedding model with ct.load_w2v. Then ct.generate_concept_axis takes the positive and negative anchor words and returns an axis. Then ct.project_text takes that axis and a text and returns a score. The README also states that ct.wepa is a one-line shortcut equivalent to the expanded three-step workflow, accepting wv, text, poswords, negwords, lang and a cosine parameter.

Two design choices are worth naming. The axis is built from words, not from labelled examples, so the measurement is only as good as the anchor dictionary and the embedding space it sits in. And the score is a projection, which means it is relative to the axis, not an absolute quantity. The README says WEPA scores should be interpreted as indicators of construct-related linguistic salience, and should not be read as direct observations of latent psychological states, clinical diagnoses, causal effects, or proof of strict measurement invariance. That is an unusually clear boundary statement, and it should be taken literally.

The Mind module goes further than the single score. It lists semantic_centroid, generate_concept_axis, wepa, project_text, sematic_projection, project_word, sematic_distance, divergent_association_task, discursive_diversity_score and procrustes_align. Procrustes alignment is the piece that matters if you want to compare embeddings trained on different corpora or at different times, because it rotates one space onto another before comparison.

Installing cntext and running the minimal WEPA example

The README gives two installation paths. The released package installs from PyPI, and the repository itself installs in editable mode for local development. Recommended Python versions are 3.9 to 3.12, which is tighter than the ^3.8 floor declared in pyproject.toml and the >=3.5 in setup.py. Treat the README range as the one that is actually supported.

bash
pip install cntext --upgrade

The upgrade flag matters here because the released version and the repository version do not match. The most recent release listed is 1.7.9 from 2022-09-09, while pyproject.toml and setup.py both declare version 2.2.1. If you install from PyPI and then read the README, you may be looking at documentation for code you do not have. For local development from the repository, the README gives:

bash
pip install -e .

The repository ships a minimal example that the README says does not require external datasets, large embedding files, or internet access. It builds a tiny in-memory embedding object, defines positive and negative anchor words for a goal-commitment construct, and constructs a semantic axis:

bash
python examples/wepa_minimal_example.py

If your system uses python3, the README gives the python3 form of the same command. Running it should print a WEPA score without any downloads. That is the fastest way to confirm the embedding and projection path works before you point it at a real corpus.

For a real run, the README shows loading a trained embedding file and passing a sentence with anchor words. The expanded form is the one to copy, because it lets you inspect the axis:

python
import cntext as ct

wv = ct.load_w2v('outputs/corpus-Word2Vec.200.15.bin')
axis = ct.generate_concept_axis(
    wv=wv,
    poswords=["commit", "persist", "focus"],
    negwords=["quit", "avoid", "delay"],
)

score = ct.project_text(
    wv=wv,
    text="I will persist and focus on this goal",
    axis=axis,
    lang="english",
)

The lang parameter appears in both the expanded call and the one-line ct.wepa call. The README does not enumerate the accepted values beyond the english example, so check the source before passing anything else.

Where cntext breaks down or is the wrong choice

The anchor dictionary is the weak point, and the README says so. It states that anchor-word dictionaries are context-specific measurement resources, that they should be developed from theory, reviewed by domain experts, and validated empirically before being used in new platforms, languages, or cultural contexts. There is no built-in validation harness for that. You bring the theory and the validation.

Embedding dependency is the second constraint. Every WEPA score depends on a word-embedding model you trained or obtained elsewhere. If your corpus is small, domain-specific, or mostly code-switched, the vectors will be poor and the projection will inherit that noise. The README does not document how to diagnose a bad axis, and it does not document rollback or versioning of dictionaries.

The release history is the third signal. The most recent release in the repository metadata is 1.7.9, dated 2022-09-09, while the package metadata declares 2.2.1. The last push to the default branch was on 2026-05-03. So the code moves, but the release channel lags far behind it, and anyone pinning cntext==1.7.9 from PyPI is running a package that predates the WEPA work entirely. For a measurement instrument, that gap is a reproducibility problem, not just a packaging annoyance.

Finally, cntext is the wrong tool for anything latency-sensitive or multi-tenant. It pulls in matplotlib, pyecharts, gensim, PyMuPDF, networkx, ollama, openai and instructor. That is a research environment, not a slim service dependency.

cntext against a general NLP pipeline such as spaCy plus a sentiment model

The obvious alternative for English-heavy work is a general NLP pipeline: spaCy for tokenisation and vectors, plus a transformer sentiment or embedding model for scoring. The difference in approach is fundamental. A transformer pipeline learns a representation from a pretrained model and then you fine-tune or prompt it. cntext's WEPA does the opposite: you declare the construct as an axis between two word lists, and the embedding space is only the coordinate system.

That makes cntext more transparent and more fragile at the same time. Transparent, because the anchor words are readable and a reviewer can argue with them. Fragile, because the axis is only as good as those words. A transformer classifier hides its decision boundary but is less sensitive to a single bad anchor term.

There is also a Chinese-specific difference. cntext ships jieba, opencc-python-reimplemented for traditional-to-simplified conversion, and Chinese font handling for matplotlib. A spaCy pipeline needs separate components for all three. If your corpus is Chinese and your method is dictionary-based measurement, cntext removes a lot of plumbing. If your corpus is English and your method is supervised classification, the plumbing is not the hard part and cntext adds little.

Maintenance cost, licence and upgrade risk

cntext is MIT licensed, declared in both pyproject.toml and setup.py. MIT is permissive: you can use, modify and redistribute it, including in closed work, provided the copyright notice and permission notice are retained. That is a description of the licence text, not legal advice; check the LICENSE file for the exact wording.

The upgrade cost is real. The dependency list is long and some pins are tight. setup.py pins scikit-learn==1.5.0, numpy==1.26.4 and gensim==4.3.2, while pyproject.toml uses caret ranges. Two files disagree about the same dependencies, and setup.py is the one pip will use if you install from source with setuptools. A numpy pin at 1.26.4 will conflict with any project already on numpy 2.x, and gensim==4.3.2 is similarly restrictive.

The version skew between the 1.7.9 release and the 2.2.1 metadata means you should decide early whether you depend on the released package or on a git checkout. If your paper reports results, record the commit hash, not just the version string, because the two do not correspond.

Editorial conclusion

Adopt cntext if you are a social scientist who needs dictionary scoring, readability metrics and embedding-based construct scores in one Python package, and if you are willing to build and validate your own anchor dictionaries. Do not adopt it if you need a maintained production NLP service, GPU-scale training, or a library whose every function is covered by tests and docs. Before committing, run python examples/wepa_minimal_example.py to confirm the embedding path works on your machine, then check that ct.load_w2v accepts the embedding file you actually have, since the README does not document the accepted binary formats.

Frequently asked questions

What is an example of context?

In cntext the relevant sense of context is the corpus and embedding space a measurement sits in. The README states that anchor-word dictionaries are context-specific measurement resources and should be validated empirically before being used in new platforms, languages, or cultural contexts.

What is another word for context?

cntext does not define the term. The package uses word_in_context in its Stats module and word_in_context is listed among the functions for examining how a term appears in surrounding text.

What is the significance of context?

For cntext the significance is that a WEPA score depends on the embedding space and the anchor words, both of which are context-specific. The README warns the score is an indicator of construct-related linguistic salience, not a direct observation of a latent psychological state.

What does it mean to give context to something?

The README does not address this phrasing. Its nearest concept is the lang parameter passed to ct.wepa and ct.project_text, which tells the library which language to tokenise.

Official sources

  1. hiDaDeng/cntext on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes