All projects

Mailroom-Corpus-EDA

Data engineering · dataset build, audit & publishing

The mailroom projects all depend on one dataset. This repository is how I built it from public sources, cleaned it, checked it, and published it without letting the labels leak.

At a glance

3,302 documents in 5 classes and 55 strata, from CUAD, MAUD, SEC EDGAR, Enron email and four insurance sources

13,753 of 13,753 contract clause annotations whose character offsets match the document text exactly

7 pipeline phases, from download to a correspondence-intent audit, rerun with one command

The problem

I could not find a public dataset that looks like a mailroom: contracts, merger agreements, corporate filings, emails and insurance claims arriving together. The only way to get one was to assemble it from sources that were never meant to sit side by side. They differ in format, licence, labelling, length and quality.

Assembling the pieces is the smaller job. The harder part is being able to say, for every document, where it came from, what its label means, who produced the label, and whether a model scored on it could have seen the answer.

Approach

The dataset is built once from public sources, and then the repository audits the published result. Every phase works from the published data, downloaded from the Hugging Face Hub, and recomputes its numbers, so the report is a check on the dataset and not a description of it.

The design rule that shaped the most work is label separation. The main configuration a model reads has four columns: a filename, the document text, a prompt and a metadata blob. It has no label column. All ground truth lives in a second configuration that is joined on filename. A model working on the first configuration cannot see an expected class, an intent or a clause annotation.

What I built

Results

Two horizontal bar charts over the five document classes. Left: documents per class, with insurance claims at 1,100, correspondence at 1,000, contracts at 600, corporate records at 450 and merger agreements at 152. Right: distinct subclasses per class, with contracts at 26, corporate records at 10, correspondence at 8, insurance claims at 6 and merger agreements at 5.

Documents per class on the left; distinct subclasses per class on the right.

The corpus is imbalanced, and the audit says so plainly. The largest class is 7.2 times the smallest. At the level of the 55 strata the ratio is 557, because one merger-agreement stratum has a single document. The split rule puts a document in the test set when the md5 of its filename modulo 10 is zero, which is reproducible but not stratified. Ten strata end up with no test documents.

Horizontal bars of test-set share for each of the 55 strata with a dashed line at 10%. Ten strata at the top have no test documents, four more, drawn in red, fall well short of it, and the rest run from about 6% to 24%.

Test share for each of the 55 strata, against the 10% the split rule aims for.

Heads up. The dataset is built for evaluating a mailroom pipeline. It is not a training set, and its 90/10 split is a way to sample reproducibly, not a train and test design. The 91 SEC EDGAR contracts have no clause annotations. The Enron emails are real messages from named people, so I handle them conservatively, and any use of them should too.

What I learned

Stack

Python pandas PyArrow Hugging Face Hub Plotly matplotlib pytest