Въведение

За да обработваш данни за AI, направи три неща подред: (1) дефинирай какъв проблем решаваш и как ще измериш успеха, (2) изгради повторяем pipeline за почистване, трансформации и етикетиране, и (3) заключи процеса с версии, проверки за качество и защита от data leakage. Обработката на данни е мястото, където печелиш или губиш 80% от качеството на модела.

В реални проекти „данните“ рядко идват чисти: липсващи стойности, разнородни формати, дубликати, шум, пристрастия, несъответствие между training и продукция. В тази статия ще ти дам практична рамка за data processing, която работи за класически ML (таблични данни), за текст (LLM/RAG), и за смесени източници.

Най-скъпата грешка е да правиш cleaning на ръка и без документация, защото после не можеш да повториш резултата.

Стъпка 1: Определи задачата, изхода и метриката

Започни с 5 ясни отговора:

  • Какъв е типът задача: класификация, регресия, ранкиране, извличане на информация, RAG?
  • Как изглежда целевата променлива (label) или „правилен отговор“?
  • Как ще измериш успеха: accuracy/F1, AUC, RMSE, MRR/Recall@k, human eval?
  • Какъв latency/разход е приемлив в продукция?
  • Какво е минималното покритие на данните (например последните 12 месеца)?

Това диктува кои трансформации са нужни. Пример: за churn модел важат времеви прозорци и „as-of“ правила; за RAG важи chunking и deduplication на съдържание.

Стъпка 2: Събери данните и документирай произхода (lineage)

Дори малък проект печели от „паспорт“ на данните:

  • Източници: DB таблици, логове, CSV, API, документи
  • Период и честота на обновяване
  • Полета и дефиниции (data dictionary)
  • Кои трансформации се правят и къде (SQL, Python, dbt)
  • Правила за достъп (PII, роли)

Ако работиш в ЕС и/или моделът е в регулаторно чувствителен домейн, трябва да си дисциплиниран и за data governance. В EU AI Act (изисквания за high-risk системи) се акцентира върху качество на training/validation/test данните, подготовка (labeling/cleaning/updating) и проследимост на произхода.

Стъпка 3: Почистване (cleaning) и нормализация

Тук целта е да сведеш данните до последователен формат.

Таблични данни (SQL/CSV)

Провери:

  • Дубликати по ключове (едно събитие записано два пъти)
  • Липсващи стойности (NULL, празен string, „N/A“)
  • Нереалистични стойности (например отрицателни цени)
  • Разнородни единици (лв/евро, кг/г, UTC/локално време)
  • Категории с правописни варианти („Sofia“, „София“, „SOFIA“)

Често полезни техники:

  • Стандартизация на време (UTC) + ясно поле за timezone
  • Winsorization/клипване на екстремни стойности (ако домейнът позволява)
  • Imputation стратегии (със флаг „импутирано“)

Текстови данни (документи, тикети, чатове)

Провери:

  • Език (bg/en смесване) и кодировки
  • Шум: подписи, цитирани имейли, шаблони
  • PII: имена, телефони, ЕГН, адреси
  • Дубликати и near-duplicates

Практика: преди embeddings/RAG, извлечи „същинския“ текст и отдели метаданни (заглавие, дата, автор, продукт).

Стъпка 4: Етикетиране (labeling) и качество на анотациите

Ако имаш supervised задача, label-ите са критични.

Минимални правила:

  • Напиши гайд за анотация (1-2 страници) с примери
  • Дай ясни дефиниции за класовете
  • Мери съгласие между анотатори (ако имаш двама)
  • Преглеждай случайна извадка (spot checks)

Когато етикетите идват от поведение (кликове, покупки), помни:

  • Има bias (потребителите виждат само това, което им показваш)
  • Има delayed feedback (покупка след дни)

По-добре 5 000 реда с чисти labels, отколкото 200 000 със съмнителни.

Стъпка 5: Разделяне на train/validation/test без data leakage

Data leakage е когато информация от бъдещето или от теста „изтича“ в обучението и ти дава фалшиво високи резултати.

Практични правила:

  • Раздели преди да fit-ваш трансформации (scaling, encoding, imputation)
  • За времеви данни: split по време (train в миналото, test в бъдещето)
  • За клиенти/устройства: split по entity (един и същ клиент да не е и в train, и в test)

Ако работиш със scikit-learn, използвай Pipeline/ColumnTransformer, за да гарантираш, че трансформациите се учат само върху training частта.

Стъпка 6: Трансформации и feature engineering (структуриран ML)

Най-честите трансформации:

  • One-hot/target encoding за категориални полета
  • Scaling/standardization за числови
  • Лог трансформация за силно скосени разпределения
  • Агрегации по прозорец (последни 7/30/90 дни)
  • Text features (TF-IDF) или embeddings (ако е нужно)

Добра практика: пази отделно „raw“ слой и „features“ слой. Това помага за дебъг и за повторяемост.

Стъпка 7: Валидации, версии и MLOps дисциплина

Pipeline без проверки е покана за проблеми.

Добави автоматични проверки:

  • Схема: типове колони, allowed values, диапазони
  • Статистика: средни, % липсващи, брой уникални
  • Дрифт: сравнение на дистрибуции между train и продукция
  • Проверки за PII (ако не трябва да присъства)

Версионирай:

  • Данните (snapshot-и или partition-и по дата)
  • Feature pipeline-а (код + конфиг)
  • Модела (артефакт + метаданни)

Практичен минимум:

  • Един dataset_version идентификатор
  • Един features_version идентификатор
  • Лог на основни метрики и входни статистики

Съвети за по-добри резултати

  • Дръж всички трансформации в един pipeline (а не „малко в SQL, малко на ръка“).
  • Изолирай PII и работи с минимално необходимите полета.
  • Започни с проста baseline обработка, после усложнявай.
  • Ползвай „data tests“ още от първата седмица: ще хванат регресии след промени в източниците.

Чести грешки, които да избягваш

  • Fit-ваш scaler/encoder върху целия dataset преди split.
  • Използваш бъдеща информация (например „следваща покупка“) като feature.
  • Смесваш различни дефиниции на полета между екипи.
  • Не записваш как точно е произведен training dataset.
  • Пренебрегваш bias-а в данните и после се чудиш защо моделът е „несправедлив“.

Често задавани въпроси

1) Как да разбера дали имам data leakage?

Провери split-а (по време/по entity), виж дали метриките „падат драстично“ при правилен split и дали има features, които съдържат бъдеща информация.

2) Какво е минималното, което трябва да документирам за данните?

Източник, период, дефиниции на полетата, трансформации, правила за изключване/включване и версия на dataset-а.

3) Трябва ли да премахвам дубликати?

Почти винаги да, но внимателно: понякога „дубликат“ означава реално повтарящи се събития. Дефинирай ключ за дедупликация.

4) Как да обработвам липсващи стойности?

С комбинация от: (а) домейн правила, (б) имputation стратегия и (в) допълнителен флаг, че стойността е липсвала.

5) Кога да използвам синтетични данни?

Когато имаш малко примери за редки случаи, но само ако можеш да валидираш, че синтетиката не вкарва систематични грешки и не нарушава правила за поверителност.

Примерен pipeline за таблични данни (ETL + tests)

Ако работиш с таблични данни (CRM, транзакции, логове), типичният минимален pipeline изглежда така:

  1. Raw слой (immutable): записваш данните както идват (например raw_events_2026_02_10). Не редактираш исторически партиции.
  2. Staging слой: чистиш формати и типове (дати, числа, валути), стандартизираш категории, махаш очевидни дубликати.
  3. Features слой: правиш агрегации и прозорци (например „брой покупки последни 30 дни“), създаваш целевата променлива, добавяш флагове.
  4. Training dataset export: фиксираш „as-of“ дата и правила, за да няма future leakage.

Data tests (задължителни, автоматични)

Добави тестове, които се пускат при всяко обновяване на данните:

  • Няма неочаквани нови колони (schema drift)
  • Няма празни ключове (customer_id IS NOT NULL)
  • Диапазони: price >= 0, age BETWEEN 0 AND 120
  • Allowed values: status IN ('active','canceled','trial')
  • Уникалност на бизнес ключ (ако е приложимо)
  • % липсващи стойности под праг (например < 5% за критични полета)

Тези проверки може да ги имплементираш като SQL assertions, като тестове в dbt, или като Python валидатор (например с Pandera/Great Expectations стил). Важно е да са автоматични и да блокират pipeline-а при груби аномалии.

Пример (Python) за бърза валидация на вход

import pandas as pd

def validate(df: pd.DataFrame) -> None:
    assert df["customer_id"].notna().all()
    assert (df["price"] >= 0).all()
    assert df["status"].isin(["active","canceled","trial"]).all()
    # мониторинг: аларма ако липсващите скочат
    missing_rate = df["email"].isna().mean()
    assert missing_rate < 0.2

Тук не търсим „перфектни“ проверки, а такива, които ловят катастрофални промени рано.

Специален случай: данни за LLM/RAG (текст, документи, тикети)

При LLM-и най-често обработваш текст. Практики, които реално помагат:

  • Dedup: махни дубликати и близки дубликати, за да не „overfit“-ваш към една и съща формулировка.
  • PII редукция: ако не ти трябва, премахни или маскирай (телефони, адреси, ЕГН, имейли).
  • Сегментация: chunking по смисъл (секции/параграфи), а не по фиксирана дължина „на сляпо“.
  • Контрол на домейн: отдели вътрешни политики от маркетингови текстове, защото имат различна „истина“.
  • Качество на източника: за RAG е по-важно да имаш малко, но авторитетни документи, отколкото огромен шумен корпус.

Регулаторен и организационен контекст (актуално към 2026)

Ако разработваш AI за чувствителни домейни (HR, финанси, здраве, образование), обработката на данни не е само инженерна задача. EU AI Act поставя изисквания за data governance и качество на training/validation/test данните при high-risk системи. Практически това означава: да можеш да покажеш произход, подготовка, критерии за включване/изключване, мерки срещу bias и как обновяваш данните.

Дори да не си в high-risk категория, този подход ти дава по-добра стабилност: по-малко „изненади“ след промени в източниците и по-лесен дебъг, когато метриките паднат.

Мониторинг след деплой (не го пропускай)

Дори перфектно почистен training dataset не гарантира стабилност в продукция. След деплой следи поне:

  • Дрифт в входните фичъри (стойности и разпределения спрямо training)
  • Дял на липсващи стойности и „unknown“ категории
  • Промяна в latency и проценти на грешки в ETL
  • Качество по бизнес метрика (например конверсия, време за обработка, точност на класификация)

Когато метриките паднат, първо провери дали източникът не се е променил (нов формат, нови категории, различен timezone). Накрая, планирай backfill стратегия: ако коригираш cleaning правило, преработи историческите партиции, иначе ще имаш „две истини“ в данните.