Skip to main content

Interpretable multi-dimension text quality metric with combiner

Project description

lens-eval

PyPI Python License

An interpretable, learned text-quality metric — for RAG, machine translation, and dialogue.

lens-eval scores text along four transparent dimensions — semantic, nli, naturalness, emotion — and learns from human judgments how to weigh them for the job at hand. The same machinery re-ranks RAG answers, scores machine translation, and rates dialogue — and it always reports the coefficients, so you can see why a text scored the way it did. It's small, runs on both CPU and GPU, and is fully interpretable.

A clear use case is RAG: you retrieved a passage, generated a few candidate answers, which one do you serve? Assemble the grounded prompt your pipeline already builds, then let a pretrained metric rank the answers against it. No training, no LLM judge:

from lens_eval import LENS

prompt = f"Using the following guideline, answer the question.\nGuideline: {context}\nQuestion: {question}"

metric = LENS.load("foudil/lens_focus")          # pretrained, from the Hugging Face Hub
scores = metric.score(candidate_answers, references=[prompt] * len(candidate_answers))
Question:   How much paracetamol can I take for a 39°C fever?
Retrieved Context:  For adults, paracetamol 500–1000 mg every 4–6 hours, max 4 g/day.

Candidate answers, ranked by lens_focus (higher = better grounded answer):
  0.87  Based on the guideline, an adult can take 500–1000 mg every 4–6 hours, max 4 g/day.
  0.35  I'm not a doctor, so I can't say anything about doses.                 ← evasive
  0.26  You should take 2000 mg every two hours until the fever is gone.       ← wrong dose
  0.02  A fever can be uncomfortable. Make sure to rest and stay hydrated.     ← off-topic

The grounded answer wins decisively and the off-topic one sinks. lens_focus was trained on RewardBench-2's Focus task and outranks many strong LLM-as-a-judge models on it — at a fraction of the cost. Full script: examples/rag_rerank.py.

Install

pip install 'lens-eval[encoders]'  # score raw text (transformer encoders included)
pip install lens-eval              # core only: combiner + your own feature matrix
pip install 'lens-eval[all]'       # everything (EBM/GBM combiners, HTML reports, ...)

The core install is intentionally light (numpy / scipy / scikit-learn). The encoders extra adds the transformer encoders that turn raw text into features; skip it if you already have a feature matrix.

Pretrained metrics on the Hub

Load any of these with LENS.load("owner/repo") — no fitting required:

Metric Task Score from text with
foudil/lens_focus RAG / best-answer selection (RewardBench-2 Focus) score(answers, references=[prompt]*n)
foudil/lens_wmt_da machine-translation quality (WMT DA) score(translations, references=refs)
foudil/lens_uses_knowledge, lens_engaging, lens_maintains_context, lens_understandable, lens_natural knowledge-grounded dialogue facets (TopicalChat-USR) combine several reference signals — see DOCS

Train your own

Have human ratings for your own domain? Fit a combiner on them. You need at least 50 rows.

from lens_eval import LENS

# Candidate texts, their references, and human quality scores.
hyps = ["the cat sat on the mat", ...]   
refs = ["a cat is on the mat", ...]
y    = [4.0, ...]                             # e.g. 1–5 Likert, or 0–100 DA scores

lens = LENS().fit(texts=hyps, references=refs, scores=y)

scores = lens.score(new_hyps, references=new_refs)   # array of quality scores
order  = lens.rank(candidates, references=refs)       # best-first indices
delta  = lens.compare(a, b, references=refs)          # >0 means `a` is better

lens.report()                                         # what it learned + diagnostics
lens.save("./my-lens")

Running on a GPU? from lens_eval import configure; configure(device="cuda") first.

What it does

  • Three task modes, auto-detected from the targets you pass:
    • scores=regression (continuous, bounded, ordinal, or binary)
    • pairs=pairwise (winner/loser index pairs)
    • ranks= + groups=ranking
  • Auto model selection. Cross-validates a ladder of combiners (glmglm_interactionsebmgbm), gated by sample size, and keeps the simplest one within 1 SE of the best.
  • Interpretable by construction. Coefficients, drop-column ablation, per-dimension contributions, and a text or HTML report (lens.report_html("report.html")).
  • Bring your own features. Pass features= (a NumPy array or DataFrame) to skip encoding — useful when your dimension scores already live in a CSV, or come from custom reference signals.
  • Save, load, and share locally or via the Hugging Face Hub.

Command line

lens-eval fit   --texts hyp.txt --refs ref.txt --scores scores.csv --output ./my-lens
lens-eval score --model ./my-lens --texts new.txt --refs ref.txt --output preds.csv
lens-eval report ./my-lens --html report.html

--texts/--refs take one item per line (.txt) or the first column of a .csv; --scores is a one-column CSV. Pass --features features.csv to any command to skip encoding.

How it works

Each dimension is a cosine similarity between L2-normalised embeddings (higher = better); naturalness defaults to a reference-free signal (similarity to a learned centroid). The combiner is the only learned part: lens-eval validates your inputs, infers the target type and link, cross-validates each candidate combiner, applies the 1-SE rule to favour the simplest adequate model, refits it on all your data, and computes diagnostics, all inside fit().

Requirements

  • Python ≥ 3.9
  • The encoders extra to featurize raw text
  • To train: at least 50 labelled rows (fewer than 200 restricts selection to the linear combiner). Reference-mode dimensions need references at both fit and score time.

Documentation

  • Full documentation — every argument, task mode, the combiner ladder, encoder configuration, the multi-reference dialogue features, persistence, and the CLI.
  • examples/rag_rerank.py — the runnable RAG demo above.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lens_eval-0.3.1.tar.gz (67.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lens_eval-0.3.1-py3-none-any.whl (53.9 kB view details)

Uploaded Python 3

File details

Details for the file lens_eval-0.3.1.tar.gz.

File metadata

  • Download URL: lens_eval-0.3.1.tar.gz
  • Upload date:
  • Size: 67.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lens_eval-0.3.1.tar.gz
Algorithm Hash digest
SHA256 6651e23522ea747d631923d3d0e2e23e92cc3bd7219c7e76b50370ed335016dd
MD5 8c6d58b9d9c5c1884bbe6d41ae1ee4d0
BLAKE2b-256 716baddf7681667c65896038ca968a0a8b5eaf3f205ae0679fd96b38ecd2ac00

See more details on using hashes here.

Provenance

The following attestation bundles were made for lens_eval-0.3.1.tar.gz:

Publisher: Publish.yml on foudil09/lens-eval

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lens_eval-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: lens_eval-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 53.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lens_eval-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bc1f250edb85a2dc0bfe28cc152fbbf74d45833b5af023da23e8e3cba50354d8
MD5 8c7726fc556c22ccf8f9bed080ee523e
BLAKE2b-256 63a25a340e74ac11cf7a8136b4b8477f6d6319425b6408b86e574c9eefc290b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for lens_eval-0.3.1-py3-none-any.whl:

Publisher: Publish.yml on foudil09/lens-eval

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page