10 min read

NER Services in Business: From Theory to Practice

How named entity recognition automates business processes inside a bank. Practical Python examples with working code.

NER Services in Business: From Theory to Practice

"Transfer Me to a Manager"

A simple sentence. Six words. And the NER system has to figure out: is this "transfer money" or "put me through to a manager"? Is "manager" a name, a job title, or a type of operation? Context decides. But context is exactly what machines handle worst.

A client writes into the bank's chat: "Hello, my name is Alexey Petrov, I want to transfer 50,000 rubles to my wife's account." Four entities to process: name, amount, currency, operation type. A call-center operator extracts them intuitively. But an operator handles one request at a time, gets tired, makes mistakes, goes to lunch. At thousands of requests an hour, manual processing doesn't scale.

Named Entity Recognition is the automatic extraction of structured entities from unstructured text. In a banking context, this isn't an academic exercise. It's the difference between operators typing data in by hand and a system that pre-fills the request card in milliseconds.

NER pipeline: from text to structured entities

Why It's Harder Than It Looks

At first glance, it's a job for a regular expression. At second glance, no.

Names. "Alexey Petrov" — easy. "A. Petrov" — already harder. A surname in an oblique case (Russian inflects them) needs lemmatization to recover the base form. "Lyosha called me about a transfer" — you have to realize that "Lyosha" is a name (a nickname for Alexey). "petrov alexey," lowercase and unpunctuated — the regex gives up.

Amounts. "50,000 rubles" — obvious. "Fifty thousand" — spelled-out numerals need converting. "Poltinnik" (slang for a fifty) — slang. "50k" — internet format. "Fifty thousand bucks" — a combination. Each variant is its own pattern, and there are infinitely many of them.

Currencies. "Rubles," "rub.," "bucks," "wooden ones" (a Russian nickname for the ruble) — all the same ruble. Plus multiple currencies in a single sentence.

Intents. "I want to transfer," "send it to my card," "drop it on the account" — transfer. "Put me through to a manager" — routing. Without context, you can't tell them apart.

Three Approaches: A Comparison

CriterionRule-basedML modelsHybrid
PrecisionHigh (on known patterns)Medium–highHigh
RecallLow (only explicit patterns)HighHigh
Development timeDaysWeeks to monthsWeeks
Needs labeled dataNoYes, lotsPartially
MaintenanceRules grow and conflictRetraining the modelRules + retraining
DebuggingTransparentBlack boxPartly transparent
Robustness to new formatsLowHighMedium–high

Rule-based: Fast Start, Slow Death

You write rules, regexes, dictionaries. For each entity type — a set of patterns. When a rule fires wrong, you know exactly why and you can fix it. For extracting a tax ID, a phone number, a standard amount format — it's the perfect tool.

But six months in, the rule system turns into a monster. A new input format means a new rule. Rules conflict. Changing one breaks three others. We had a set of several hundred rules just for extracting amounts — and every new edge case added more fragility.

ML: Powerful, but Expensive

You train a model on labeled data: here's the text, here are the entities. The model generalizes — it handles variants that weren't in the training set. Resilience to typos, unusual phrasings, slang.

The problems: you need labeled data, and a lot of it. In a bank, that means working with personal data — compliance hell. The model is a black box: when it makes a mistake, figuring out why and explaining "why" to the business is a non-trivial task. And you need infrastructure for training and inference.

Hybrid: What Actually Works in Production

Rules handle the obvious cases with high precision. ML picks up the rest. The pipeline: text passes through a rule-based module that extracts entities with high confidence. Whatever isn't recognized goes to the ML model. The output is a merged result prioritized by confidence score.

This is exactly the approach we used. We started with rules — a fast result and baseline accuracy. As we accumulated labeled data, we brought in ML.

The Python Stack for Russian NER

The ecosystem of NER tools for Russian is mature. Here's what we used.

spaCy — an NLP framework. Tokenization, lemmatization, POS-tagging, basic NER out of the box. The ru_core_news_sm model is a starting point, but banking-specific work needs fine-tuning.

import spacy

nlp = spacy.load("ru_core_news_sm")
doc = nlp("Алексей Петров хочет перевести 50000 рублей")

for ent in doc.ents:
    print(f"{ent.text} -> {ent.label_}")
# Алексей Петров -> PER
# 50000 рублей -> MONEY

The basic example works. But "Lyosha wants to toss over a fifty" — not anymore. Here you need fine-tuning or a hybrid approach.

pymystem3 — a wrapper for Yandex's Mystem. The best morphological analyzer for Russian in my experience. When you need to recognize that "Petrovu" is the dative case of "Petrov":

from pymystem3 import Mystem

m = Mystem()
lemmas = m.lemmatize("Передайте Петрову документы")
# ['передавать', ' ', 'петров', ' ', 'документ', '\n']

pymorphy2 — a morphological analyzer for normalizing word forms. Reducing to the base form, determining gender, number, case. Works in tandem with spaCy.

Our production pipeline: text is tokenized by spaCy, morphology is enriched via pymystem3, the rule-based module extracts hard patterns (tax IDs, phone numbers, standard amounts), and the ML model handles everything else.

Cases From Production

Extracting Full Names

One of the hardest tasks in Russian. A name can appear in any case, in any order (surname-first-patronymic, first-last, first only), abbreviated or not.

Our approach: a dictionary of Russian first and last names (on the order of three hundred thousand entries) combined with morphological analysis. Pymystem3 flags a noun with proper-name features. Rules check the context: "my name is" or "I" before the word raises the probability that it's a name.

Amounts and Currencies

We wrote a numeral converter that handles dozens of variants: from "five hundred twenty-three rubles forty kopecks" to "523.40 rub." and "523r40k." A separate problem is thousands separators: "50 000" vs "50,000" vs "50000."

The currency dictionary — over a hundred spellings for twenty major currencies, slang included.

The "Manager" Case

Detecting intent isn't just entities but understanding what the client wants. "I want to transfer" — transfer. "Show me my balance" — balance_inquiry. "Block my card" — card_block.

The rule-based approach works surprisingly well here — a bank's set of operations is finite. We built a taxonomy of about fifty intent types, each with a set of trigger phrases. ML adds handling for the non-standard phrasings.

The Incident That Taught Us

March 2023. Monitoring shows the NER service's precision dropping from 94% to 78% over a week. Recall, meanwhile, didn't budge. What happened?

It turned out marketing had launched a customer promo. Requests were suddenly full of phrases like "I want to sign up for Multicard Plus with 5% cashback." NER started classifying "Multicard Plus" as a full name — "Multicard" matched the capitalized-proper-noun pattern, and "Plus" got tagged as a surname.

Rules that had worked flawlessly for six months broke on new context. We added the bank's product dictionary to the rule-based module's exclusions. It took a day. But the fact itself: a NER system you don't feed current context degrades silently. Metric monitoring isn't optional — it's a necessity.

Metrics vs. Reality

Lab numbers: precision 94%, recall 91%. Production is lower, because real clients write with typos, without punctuation, in a mix of Russian and English. And they launch promos with products whose names the NER system takes for people's names.

But the key business metric isn't the model's accuracy — it's the reduced load on operators. The NER service pre-fills the request card: client name, request type, key parameters. The operator just confirms or corrects. Request handling time dropped noticeably. And that's a metric the business understands and pays for.

Three Things I Learned

Start with rules, scale with ML. Rules give a fast result and baseline accuracy. Bring in ML once you've accumulated labeled data. Not the other way around — ML without data is money in the fire. We started rule-based and closed roughly seventy percent of the cases in the first two weeks. The remaining thirty — non-standard phrasings, slang, typos — piled up over three months, until we'd gathered enough labeled examples for the ML model. Had we started with ML straight away, we'd have spent three months with no working product, explaining to the business why "the model is still learning."

Invest in data, not models. The quality of the labeled dataset sets the ceiling. A simple model on clean data beats a complex one on dirty data. Always. We spent a month on labeling: two analysts, clear guidelines, cross-validation. Boring? Hellishly. But when we plugged in ML, the model delivered acceptable results right away. Colleagues on an adjacent team who cut corners on labeling and fed the model whatever they had — their precision came out fifteen points lower.

NER is a pipeline, not a model. Tokenization, normalization, rule-based extraction, ML extraction, post-processing, validation. Every link affects the result. And every one can break unnoticed the moment marketing launches its next promo.

Deploying NER in a Bank: A Special Kind of Pain

Writing a NER service is half the job. Running it inside a bank's infrastructure is the other half — and it's harder than the first.

First: everything on-premise. No clouds, no external APIs. This is one of the circles of fintech-development hell you'd better be ready for. The model, the data, inference — it all runs inside the perimeter. That means: you stand up the training infrastructure yourself, you configure the GPU servers yourself (if there are any at all), you track model versioning yourself. In the cloud you press a button and get an endpoint. In a bank you file a resource-allocation ticket, wait two weeks, and get a server with the wrong CUDA version installed.

Second: compliance. Labeled data contains clients' personal information. Every dataset goes through sign-off with security. Every data access is logged. You can't just copy an export to your work laptop and label it in a convenient tool — everything happens inside an isolated perimeter, in a special environment, with a limited set of tools. We labeled data in an interface we built ourselves, because not a single external labeling tool passed the security review.

Third: latency. The NER service sits on the critical path of handling a client request. A client writes into the chat — the system has to pre-fill the card in milliseconds. Not seconds — milliseconds. And an ML model, even a light one, delivers tens of milliseconds on CPU. We optimized inference with ONNX Runtime, batched requests, cached results for common phrases. Every millisecond is operator UX, and operator UX is request handling time, and handling time is money.

Fourth: degradation monitoring. A model doesn't break with a bang. It quietly starts making mistakes — and you find out when operators start complaining that "the system is spouting nonsense again." We built a monitoring pipeline: precision and recall computed on a sample every day, alerts when they drop below a threshold, a weekly report for the business. Automation doesn't replace manual checks, but it at least gives you a chance to catch a problem before the client does.

NER in a bank isn't an ML problem. It's an engineering problem wrapped in compliance, latency requirements, and a reality where marketing launches promos without warning IT. Those who are ready for it build a product. Those who aren't build a prototype that never makes it to production.


Original article: NER Services in Business on Habr

Yours, DPUPP

Related Articles