Skip to main content

Centering-Lgram

Discourse cohesion analysis based on Centering Theory (Grosz, Joshi, and Weinstein, 1983). Measures how entities and topics flow across sentences — pronouns, repetitions, entity continuity.

Note: Cohesion (bağdaşıklık) = surface grammatical/lexical links. Coherence (tutarlılık) = deeper semantic unity. Centering Theory models cohesion.


⚠️ What This Tool Does NOT Measure

  • Factual accuracy — a high cohesion score does NOT mean the content is correct
  • Hallucination — a fluent-sounding LLM output can still be completely false
  • Overall quality — cohesion is ONE dimension of text quality, not the whole picture

Correct positioning: Use centering-lgram as a complementary evaluator alongside faithfulness/accuracy checkers. It measures "how smoothly does this read?", not "is this correct?".

What we measure What we DON'T measure
Entity flow across sentences Factual correctness
Pronoun resolution quality Hallucination / faithfulness
Topic continuity / shifts Logical reasoning
Readability (Flesch) Relevance to prompt
Lexical repetition chains Domain accuracy

PyPI Python License Tests


Quick Start

pip install centering-lgram
python -m spacy download en_core_web_sm
from lgram import TextAnalyzer

ta = TextAnalyzer()
r = ta.analyze("AI helps doctors. It speeds up diagnosis. These tools save lives.")
print(r.overall_cohesion)  # 0.0-1.0 (exact value depends on the spaCy model)
print(r.quality)           # "high"

For best results, use the medium model:

ta = TextAnalyzer("en_core_web_md")

Genre Calibration

Empirically derived transition patterns. Method: Tukey's fence (p75 + 1.5×IQR).

Brown Corpus (1960s)

NLTK Brown: 1.1M words, 500 files, 15 categories. n=30/genre, HIGH confidence.

Genre Rough normal (p25–p75) Flag > (Tukey) Continue mean Conf.
Narrative 11.5% – 27.3% 51.0% 49.8% HIGH
Expository 16.7% – 33.3% 58.2% 29.2% HIGH
Essay 11.5% – 27.7% 52.0% 30.7% HIGH

Modern Corpus (2020s) — n=30/genre, HIGH confidence

Genre Rough normal (p25–p75) Flag > (Tukey) Continue mean Conf.
Narrative 0.0% – 25.0% 62.5% 25.0% HIGH
Expository 0.0% – 25.0% 62.5% 32.3% HIGH
Essay 0.0% – 25.0% 62.5% 20.3% HIGH

Note: Single-author corpus. Stylistic homogeneity may narrow distributions.

Cross-Validation: Wikipedia (multi-author, 2024)

n=12, MEDIUM confidence. Small sample — treat as observational, not conclusive.

Genre n Rough normal Flag > Continue Conf.
Expository (Wikipedia) 12 23.0% – 34.6% 52.0% 34.5% MEDIUM

Wikipedia's 52% flag threshold is broadly consistent with Brown's 58%. Direction is as expected (multi-author corpora cluster together, single-author is the outlier). However, at n=12 this is an observation, not a validated claim. Two caveats: (1) Wikipedia's strict editing guidelines may make it a distinct sub-genre, not representative of general 2020s expository writing. (2) The 6% gap could be measurement noise, temporal change, or genre artifact — the current data cannot distinguish between these explanations.

Findings

  1. Rough-Shift >50% is abnormal — all corpora agree. Flag thresholds: 51-63%.
  2. Wikipedia cross-validates the multi-author finding — Brown (58%) and Wikipedia (52%) cluster together, while the single-author corpus (63%) diverges. Consistent with the stylistic homogeneity hypothesis. However, n=12 precludes strong conclusions about temporal stability.
  3. Wikipedia is not "general 2020s writing" — its strict editing guidelines may constitute a distinct sub-genre. More diverse modern sources needed.

Calibration is reproducible: python -m lgram.brown_calibration

⚠️ Reliability note: Scores depend on the underlying embedding model. For production use, pick ONE model (recommended: en_core_web_md) and standardize on it. Compare texts only within the same genre — cross-genre comparison is meaningless because different genres have different natural transition patterns.


Core Concepts

Centering Theory tracks three discourse centers per utterance:

Center Notation Definition
Forward Centers Cf Entities ordered by grammatical salience
Backward Center Cb Entity linking to previous utterance
Preferred Center Cp Highest-ranked Cf

Five transition types between utterances:

Transition Rule Quality
Establish First utterance —
Continue Cb(Ui) = Cb(Ui-1) = Cp(Ui) Best
Retain Cb(Ui) = Cb(Ui-1) ≠ Cp(Ui) Good
Smooth-Shift Cb(Ui) ≠ Cb(Ui-1) = Cp(Ui) OK
Rough-Shift Cb(Ui) ≠ Cb(Ui-1) ≠ Cp(Ui) Poor

API — TextAnalyzer (High-Level)

from lgram import TextAnalyzer

ta = TextAnalyzer()                    # default: en_core_web_sm
ta = TextAnalyzer("en_core_web_md")    # better vectors
ta = TextAnalyzer(use_sentence_transformers=True)  # best quality

Core Analysis

Method Description
analyze(text) Full analysis → TextReport (sentences, paragraphs, transitions, entities)
analyze_batch(texts, labels) Compare multiple texts with rankings
analyze_llm(response, prompt?) LLM output quality: high/medium/low + prompt comparison

Cohesion Metrics

Method Source Description
entity_grid_score(text) Barzilay & Lapata 2005 Entity role persistence (S/O/X/-) across sentences
lexical_chain_score(text) Halliday & Hasan 1976 Noun repetition + similarity chains
build_cohesion_graph(text) Graph-based Sentence adjacency graph (density, centrality, communities)
cohesion_trend(text) Sliding window Cohesion change across text (improving/declining/stable)
cohesion_heatmap(text) Matrix N×N sentence similarity with weak pair detection
combined_score(text) Hybrid Cohesion × 0.6 + Readability × 0.4

Segmentation & Quality

Method Description
texttile_segments(text) Hearst 1994 topic segmentation
hybrid_boundaries(text) Centering + TextTiling intersection (high confidence)
suggest_improvements(text) Find weak points + fix suggestions
annotate_weak_points(text) Mark <<<WEAK>>> at cohesion breaks
diff_cohesion(original, revised) Compare two versions
readability_score(text) Flesch Reading Ease + statistics

Export

Method Output
to_dict(report) JSON-serializable dict
to_json(report) JSON string
to_summary(report) Human-readable report

API — EnhancedCenteringTheory (Low-Level)

from lgram import EnhancedCenteringTheory
import spacy

nlp = spacy.load("en_core_web_sm")
ct = EnhancedCenteringTheory(nlp)

state = ct.analyze_utterance("John went to the store.")
ct.update_discourse("He bought milk.")

result = ct.evaluate_cohesion(["John went.", "He bought milk.", "The store was busy."])

Key methods: compute_forward_centers, compute_backward_center, determine_transition, extract_clauses, detect_boundaries, validate_sequence, visualize, compare_texts, stream_start/feed/flush, save/load, reset.


CLI

centering-lgram analyze --text "John went to the store. He bought milk."
centering-lgram clauses --text "She left because she was tired."
centering-lgram full --text "John left. He was tired because he worked late."
centering-lgram score --text "Alice met Bob. She greeted him."
centering-lgram info
centering-lgram version

How It Works

Salience Ranking

Cf ordered by: grammatical role (S=4 > O=3 > other=2 > poss=1) + POS (PRON=3 > PROPN=2 > NOUN=1) + position + entity type (PERSON/ORG/GPE bonus) + pronoun antecedent bonus.

Backward Center (5-level cascade)

  1. Possessive scan — "his"/"her" → matched person entity
  2. Direct match — entity appears in both Cf lists
  3. Pronoun resolution — gender-aware (he→male, she→female)
  4. Coreference — entity type matching + vector similarity fallback
  5. Compound plural — multiple persons → "they"

Gender-Aware Pronoun Resolution

120+ name gender map (English + Turkish) + title detection (Mr/Mrs) + suffix heuristics. Male pronoun "he" does NOT match female entity "Alice".

Clause Detection

Dependency parse: main, conj, advcl, ccomp, acl, relcl. Separator tokens (commas, conjunctions) assigned to following clause.


Architecture

lgram/
  __init__.py              # Package exports
  analyzer.py        924   # TextAnalyzer (17 methods)
  benchmark.py       290   # CohesionBenchmark (4 tests)
  cli.py             238   # 6 CLI commands
  core.py              7   # Re-export hub
  utils.py            20   # Logging
  models/
    __init__.py         7   # Sub-package exports
    centering_theory.py 1122 # Core engine
tests/
  test_lgram.py       209   # 15 core tests
  test_edges.py       312   # 34 edge case tests
docs/
  RESEARCH.md                # Literature survey
  IMPLEMENTATION_PLAN.md     # Implementation plan

Dependencies: spacy>=3.4.0 only. Optional: sentence-transformers for MiniLM.


Use Cases

Domain Application
LLM Evaluation Cohesion scoring for GPT/Claude/Llama output
Education Essay scoring, writing assistant feedback — CAEAS EFL essay feedback tool
Linguistics Discourse analysis research
Content Quality Blog/news fluency audits
Translation Cross-language cohesion comparison
Dialogue Conversation flow naturalness
Forensics Statement consistency analysis

License

MIT — see LICENSE. Copyright (c) 2025 Ilker Atagun.

Release files for centering-lgram 2.3.1

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

Source distribution (sdist)

Source distribution for centering-lgram 2.3.1
File Size Uploaded
centering_lgram-2.3.1.tar.gz 134.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for centering-lgram 2.3.1
File Interpreter ABI Platform
centering_lgram-2.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 265.7 kB

Release files / centering_lgram-2.3.1.tar.gz

Download URL centering_lgram-2.3.1.tar.gz
Size 134.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4220196311abaf71f30ef7ef2d3d34c0ae986489788a756b162082bdb40e95f5
BLAKE2b-256 checksum
How to use checksums
23a30917aee336a28a3ec455ca72b9aea6be769f9c157faa31e97d6d2df9b184
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / centering_lgram-2.3.1-py3-none-any.whl

Download URL centering_lgram-2.3.1-py3-none-any.whl
Size 131.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b24a765ce5236ff8c72905b6947c5653b561730451429832aa274878b30d8e8
BLAKE2b-256 checksum
How to use checksums
09b8873d986778ca8b7de8dc4d21f0b80ee2ded1ecd058fe60fc1a78b760fb57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

2.3.1 This release

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.0.0

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.50

2 release files

1.0.49

2 release files

1.0.48

2 release files

1.0.47

2 release files

1.0.46

2 release files

1.0.45

2 release files

1.0.44

2 release files

1.0.43

1 release file

1.0.42

2 release files

1.0.41

2 release files

1.0.40

2 release files

1.0.39

2 release files

1.0.38

2 release files

1.0.37

2 release files

1.0.36

2 release files

1.0.35

2 release files

1.0.34

2 release files

1.0.33

2 release files

1.0.32

2 release files

1.0.31

2 release files

1.0.30

2 release files

1.0.29

2 release files

1.0.28

2 release files

1.0.27

2 release files

1.0.26

2 release files

1.0.25

2 release files

1.0.24

2 release files

1.0.23

2 release files

1.0.22

2 release files

1.0.21

2 release files

1.0.20

2 release files

1.0.19

2 release files

1.0.18

2 release files

1.0.17

2 release files

1.0.16

2 release files

1.0.15

2 release files

1.0.14

2 release files

1.0.13

2 release files

1.0.12

2 release files

1.0.11

2 release files

1.0.10

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

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