BERT and Masked Language Models
A model trained by blanking out words and making it guess them, using the words on both sides. That pre-training produces context-aware representations you can fine-tune on a few thousand labelled filings.
Prerequisites: Word Embeddings and Word2Vec, The Transformer Architecture
The trouble with Word Embeddings and Word2Vec is that a word gets one vector forever. Charge in "a one-off charge to earnings" and charge in "the SEC filed a charge" collapse into a single averaged point, which is exactly wrong for anyone reading financial text, where the same word swings between accounting jargon and legal jargon sentence to sentence.
BERT's answer is to compute the representation of a word after looking at the sentence it sits in. Feed in "a one-off charge to earnings" and the vector for charge comes out near writedown. Feed in "the SEC filed a charge" and the same input word comes out near allegation. The representation is a function of the whole context, not a lookup.
The training trick that makes this possible is a cloze test — the fill-in-the-blank exercise from school. Take a sentence, hide about one word in seven, and make the model guess what was hidden using everything around it. Nobody labels anything; the corpus is its own answer key. Do that a few hundred million times over books, news and filings and the model is forced to learn grammar, world knowledge, and the fact that charge means different things in different neighbourhoods.
BERT reads both directions at once. A left-to-right model predicting the next word only ever sees the past. Filling a hole in the middle of a sentence lets the model use the words after it too, which is why BERT-style models are strong at understanding text and unsuited to generating it.
What "masked language modelling" actually does
Each input sentence is tokenised, and roughly of the tokens are selected for prediction. The model — a stack of transformer layers built on The Self-Attention Mechanism — produces a vector for every position, and at each selected position a small output layer scores every word in the vocabulary. Training pushes the score of the true word up and everything else down.
A second detail matters more than it looks. Of the selected tokens, only are actually replaced by a [MASK] placeholder. are swapped for a random word, and are left exactly as they were. The reason is that [MASK] never appears when you later use the model on real text, so a model that only ever computed good representations at mask positions would be useless in practice. Forcing it to sometimes correct a wrong word, and sometimes confirm a right one, keeps every position honest.
Worked example: scoring the blank
Suppose the sentence is "margins badly [MASK] the estimate" and the model's output layer produces these raw scores, or logits, for four candidate words: beat , missed , matched , fell .
Convert them to probabilities with a softmax — exponentiate each, then divide by the total:
These sum to , so
The remaining two get and . In plain English: the model is fairly sure the blank is "beat". But the true word here is missed, because of the adverb badly. The training loss is the negative log of the probability assigned to the truth:
A confident wrong answer is expensive, and the gradient from that loss is what teaches the model that badly flips the polarity of what follows. Repeat across a corpus and the model learns the pattern without anyone writing a rule.
Worked example: how much signal per pass
Take a training passage of tokens. Selecting gives
to predict. Of those, become [MASK] — about tokens — while roughly are replaced by a random word and are left untouched.
So a single pass over 512 tokens produces only 77 learning signals. A left-to-right model predicting every next token gets 512 from the same passage, nearly seven times more. That arithmetic is the honest cost of bidirectionality: BERT-style models need substantially more compute per unit of text, and it is why masked models are usually smaller than their generative cousins for a given training budget.
Using it on financial text
Pre-training is done once, expensively, by someone else. What you do is fine-tuning: bolt a small classifier onto the special [CLS] position that summarises the whole passage, then train on your own labelled data — a few thousand annotated sentences from earnings calls is often enough, versus the hundreds of thousands a from-scratch model would need. Typical jobs are sentiment on a per-sentence basis, risk-factor classification in 10-K filings, and pulling structured events out of press releases.
A general-purpose BERT has read very little accounting language, so a domain-adapted variant like FinBERT — further pre-trained on filings and calls before fine-tuning — usually beats it. See FinBERT and Domain-Adapted Models.
BERT is an encoder: it reads and scores, it does not write. Asking it to generate a summary is a category error — that job belongs to Large Language Models. The related trap is the context limit: standard BERT handles 512 tokens, and a 10-K runs to hundreds of thousands. You must chunk the document and aggregate, and how you aggregate is a modelling decision that quietly drives most of your signal quality.
Before fine-tuning anything, check whether the pre-training corpus post-dates your backtest period. A model that has read the news it is being asked to predict will look spectacular and be worthless.
Related concepts
Practice in interviews
Further reading
- Devlin et al., BERT: Pre-training of Deep Bidirectional Transformers (2019)
- Jurafsky & Martin, Speech and Language Processing (ch. 11)