Реализация автоматической классификации документов по типу

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1566 услуг
Реализация автоматической классификации документов по типу
Средний
~3-5 дней
Часто задаваемые вопросы

Направления AI-разработки

Этапы разработки AI-решения

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    901
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1119
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    853

Реализация автоматической классификации документов по типу

Классификация документов — первый этап в Document Processing Pipeline: прежде чем извлекать данные, система должна понять, что за документ перед ней. Счёт-фактура, накладная, паспорт, водительские права, акт выполненных работ — для каждого типа свой экстрактор. Точность классификации напрямую влияет на качество всего pipeline.

Мультимодальная классификация

Лучший подход — одновременно использовать визуальные признаки (как выглядит документ) и текстовые (что написано):

from transformers import LayoutLMv3ForSequenceClassification, LayoutLMv3Processor
import torch
import torch.nn as nn

class DocumentClassifier:
    def __init__(self, model_path: str, doc_types: list[str]):
        self.processor = LayoutLMv3Processor.from_pretrained(model_path)
        self.model = LayoutLMv3ForSequenceClassification.from_pretrained(
            model_path,
            num_labels=len(doc_types)
        )
        self.doc_types = doc_types
        self.model.eval()

    @torch.no_grad()
    def classify(self, image_path: str) -> dict:
        from PIL import Image
        image = Image.open(image_path).convert('RGB')

        encoding = self.processor(
            image, return_tensors='pt',
            truncation=True, max_length=512
        )

        outputs = self.model(**encoding)
        probs = torch.softmax(outputs.logits, dim=-1).squeeze()

        top_idx = probs.argmax().item()
        return {
            'document_type': self.doc_types[top_idx],
            'confidence': float(probs[top_idx]),
            'all_scores': {
                self.doc_types[i]: float(probs[i])
                for i in range(len(self.doc_types))
            }
        }

Обучение без LayoutLM: EfficientNet + BERT

Для быстрого прототипа без доступа к большим моделям:

import timm
from transformers import AutoTokenizer, AutoModel

class LightweightDocClassifier(nn.Module):
    def __init__(self, num_classes: int):
        super().__init__()
        # Visual encoder
        self.visual = timm.create_model('efficientnet_b2',
                                         pretrained=True, num_classes=0)
        # Text encoder
        self.text_encoder = AutoModel.from_pretrained('DeepPavlov/rubert-base-cased')
        self.tokenizer = AutoTokenizer.from_pretrained('DeepPavlov/rubert-base-cased')

        # Fusion
        vis_dim = self.visual.num_features  # 1408
        text_dim = 768
        self.fusion = nn.Sequential(
            nn.Linear(vis_dim + text_dim, 512),
            nn.GELU(),
            nn.Dropout(0.3),
            nn.Linear(512, num_classes)
        )

    def forward(self, image_tensor, input_ids, attention_mask):
        vis_features = self.visual(image_tensor)
        text_out = self.text_encoder(input_ids, attention_mask)
        text_features = text_out.pooler_output  # [CLS] token

        combined = torch.cat([vis_features, text_features], dim=-1)
        return self.fusion(combined)

Типовые классы документов

Домен Классы документов
Бухгалтерия Счёт, накладная, акт, счёт-фактура, договор, доверенность
KYC/AML Паспорт, СНИЛС, ИНН, права, загранпаспорт
Медицина Направление, рецепт, выписка, результат анализа
Юриспруденция Исковое заявление, решение суда, договор, доверенность
Логистика Накладная, CMR, таможенная декларация, коносамент

Коллекция признаков для классификации

Для повышения точности — дополнительные признаки помимо визуальных и текстовых:

def extract_document_features(image_path: str, ocr_text: str) -> dict:
    return {
        # Структурные признаки
        'has_table': detect_tables(image_path),
        'has_signature': detect_signature_zone(image_path),
        'has_stamp': detect_stamp(image_path),
        'has_photo': detect_person_photo(image_path),

        # Текстовые паттерны (регулярные выражения)
        'has_inn': bool(re.search(r'\bИНН\b', ocr_text)),
        'has_kpp': bool(re.search(r'\bКПП\b', ocr_text)),
        'has_passport_series': bool(re.search(r'\d{4}\s\d{6}', ocr_text)),
        'has_invoice_number': bool(re.search(r'№\s*\d+', ocr_text)),

        # Метаданные
        'aspect_ratio': get_aspect_ratio(image_path),
        'orientation': detect_orientation(image_path),
    }

Метрики на российских документах

Типичная точность на корпусе российских документов (25 классов):

Метрика Значение
Top-1 Accuracy 94–97%
Macro F1 92–96%
Recall на редких классах 85–91%

Сложные случаи: документы одного типа в разных форматах (разные банки, разные поставщики), плохое качество сканов, ламинированные документы.

Задача Срок
5–10 классов, достаточно данных 2–3 недели
20–50 классов, разные форматы 4–7 недель
Continuous learning (добавление новых классов) 6–10 недель