Metadata-Version: 2.4
Name: lebse
Version: 0.2.0
Summary: LeBSE — legal-domain sentence embeddings adapted from LaBSE
Project-URL: Homepage, https://github.com/ahb-sjsu/lebse
Project-URL: Repository, https://github.com/ahb-sjsu/lebse
Project-URL: Issues, https://github.com/ahb-sjsu/lebse/issues
Author: Andrew H. Bond
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: labse,law,legal-nlp,retrieval,sentence-embeddings,simcse
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Legal Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Text Processing :: Linguistic
Requires-Python: >=3.9
Requires-Dist: numpy>=1.24
Provides-Extra: dev
Requires-Dist: black>=24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Requires-Dist: scikit-learn>=1.3; extra == 'dev'
Requires-Dist: ty>=0.0.1; extra == 'dev'
Provides-Extra: eval
Requires-Dist: scikit-learn>=1.3; extra == 'eval'
Requires-Dist: sentence-transformers>=2.7; extra == 'eval'
Provides-Extra: train
Requires-Dist: sentence-transformers>=2.7; extra == 'train'
Requires-Dist: torch>=2.1; extra == 'train'
Description-Content-Type: text/markdown

# LeBSE — Legal-BERT Sentence Embeddings (a legal-domain LaBSE)

[![CI](https://github.com/ahb-sjsu/lebse/actions/workflows/ci.yml/badge.svg)](https://github.com/ahb-sjsu/lebse/actions/workflows/ci.yml)
[![Python](https://img.shields.io/badge/python-3.9%20%7C%203.11%20%7C%203.12-blue.svg)](pyproject.toml)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Checked with ty](https://img.shields.io/badge/types-ty-261230.svg)](https://github.com/astral-sh/ty)

**LeBSE** adapts Google's [LaBSE](https://huggingface.co/sentence-transformers/LaBSE) to the
register of U.S. case law, so that legal sentences and opinions land in a better-organized
embedding space than the general-purpose base model — while keeping LaBSE's 109-language alignment.

It is a drop-in `sentence-transformers` model: same API, same 768-dim output, same tokenizer.

```python
from sentence_transformers import SentenceTransformer
m = SentenceTransformer("ahb-sjsu/lebse")          # or a local path
v = m.encode(["The district court lacked subject-matter jurisdiction over the claim."])
```

## Why

General sentence encoders are trained on web text; their geometry is anisotropic (embeddings pile
into a narrow cone) and tuned to everyday semantics, not the dense, formulaic register of judicial
writing. LeBSE re-tunes the geometry on real opinions so that legally-related text is measurably
closer and the space is more isotropic — useful for legal retrieval, clustering, near-duplicate and
boilerplate detection, citation recommendation, and as a feature extractor for downstream legal NLP.

## How it's trained (v2, citation-supervised)

Citation-**supervised** contrastive fine-tuning, SPECTER-style: positive pairs are (citing opinion
body, cited opinion body) drawn from the CourtListener citation graph, and `MultipleNegativesRanking
Loss` uses the rest of the batch as negatives. Base model: `sentence-transformers/LaBSE`. Corpus:
U.S. federal opinions from the [CourtListener / Free Law Project](https://www.courtlistener.com/help/api/bulk-data/)
bulk data (public domain). No case outcomes are used.

```bash
# lebse-train = SimCSE (v1) baseline; lebse-train-citation = the v2 citation-supervised model.
lebse-train-citation --pairs pairs_train.jsonl --batch 96 --max-seq-len 128 --epochs 2 --out ./lebse
```

> **v1** was unsupervised SimCSE and did *not* beat base LaBSE (it's kept in `MODEL_CARD.md` for the
> record). The published weights are **v2** (citation-supervised), which does — decisively.

## Rigorous evaluation

Two held-out protocols with **opinion-level** splits (train/eval opinions are disjoint), so any gain
is generalization: (1) **citation retrieval** — the trained relation, on held-out opinions; and
(2) **docket-lineage retrieval** — an *independent* relation (a district opinion and its appellate
reviewer, matched by docket number) the model never trained on. Each reports a paired bootstrap 95%
CI on the AUROC gain.

**Held-out results (v2, citation-supervised):**

| eval | base LaBSE | **LeBSE-v2** | Δ AUROC (95% CI) |
|------|-----------|--------------|------------------|
| citation retrieval (trained relation, held-out) | 0.765 | **0.971** | **+0.206 [+0.190, +0.223]** |
| docket-lineage (independent relation, unseen) | 0.545 | **0.562** | **+0.018 [+0.004, +0.031]** |

LeBSE-v2 dramatically improves citation-type relatedness and transfers a small-but-significant amount
to an independent legal relation (district↔appellate lineage) it never trained on. See
[`MODEL_CARD.md`](MODEL_CARD.md) for the full protocol and honest caveats. (v1 used unsupervised
SimCSE and did *not* beat LaBSE — kept in the model card for the record.)

```bash
LEBSE_DSN="dbname=courtlistener" python eval.py --n 4000 --pairs 3000 --lebse ./lebse
```

## Files

| file | purpose |
|------|---------|
| `train.py` | SimCSE fine-tune of LaBSE on legal sentences |
| `eval.py`  | held-out, citation-graph-based comparison vs base LaBSE |
| `MODEL_CARD.md` | intended use, training data, metrics, limitations |
| `requirements.txt` | pinned deps |

## License

Apache-2.0 (matching the LaBSE base). Training data is U.S. federal case law (public domain).
See `LICENSE`.

## Citation

```bibtex
@software{bond_lebse_2026,
  author = {Bond, Andrew H.},
  title  = {LeBSE: Legal-Domain Sentence Embeddings adapted from LaBSE},
  year   = {2026},
  url    = {https://github.com/ahb-sjsu/lebse}
}
```
