Качество информации: свойства, критерии и оценка данных

Качество информации: свойства, критерии и оценка данных Полезное

Качество информации — это степень, в которой сведения пригодны для конкретной задачи: насколько они достоверны, полны, точны, актуальны, понятны и доступны тому, кто принимает решение. Ключевое слово — «для задачи»: один и тот же набор данных может быть качественным для месячного отчета и непригодным для ежедневной рассылки.

Ниже разберем свойства качества информации, разведем близкие термины, переведем свойства в измеримые метрики качества данных и посчитаем их на учебном примере на Python и SQL.

Информация и данные: в чем разница

Термины часто смешивают, поэтому короткий словарь до сравнения:

  • Данные — зафиксированные значения: строка таблицы, запись в логе, показание датчика.
  • Информация — данные, интерпретированные в контексте задачи: «у 30% клиентов нет email» — это уже информация.
  • Свойство качества — характеристика, которую мы хотим от информации (например, полнота).
  • Метрика качества — способ это свойство посчитать (доля заполненных полей, процент дублей).

Школьная информатика описывает качество через свойства информации. Инженерия данных — через измеримые измерения (dimensions) качества данных. Это два взгляда на одно и то же: свойство отвечает на вопрос «что хотим», метрика — «как проверить».

Свойства качества информации

Набор свойств в учебниках немного различается, но чаще всего встречаются следующие.

Свойство Что означает Пример нарушения
Объективность Не зависит от мнения или суждения источника Отзыв «доставка всегда опаздывает» по двум заказам
Достоверность Отражает реальное положение дел В базе адрес, по которому клиент давно не живет
Полнота Достаточна для решения задачи Нет телефона у половины заявок, а задача — обзвон
Точность Степень детализации и близость к истинному значению Температура округлена до 5 градусов
Актуальность Соответствует текущему моменту Прайс-лист прошлого года
Полезность (ценность) Помогает решить конкретную задачу Отчет по регионам, где компания не работает
Понятность Выражена так, что получатель ее понимает Поле st=3 без справочника статусов
Доступность Можно получить и обработать в нужное время Выгрузка есть, но только в виде скана PDF

Эти свойства связаны, но не взаимозаменяемы. Две пары, которые путают чаще всего:

  • Достоверность vs точность. Время «около 14 часов» достоверно, но неточно. Время «14:07:32» с неправильно настроенных часов точно, но недостоверно.
  • Полнота vs актуальность. Таблица может содержать все поля по всем клиентам и при этом описывать состояние двухлетней давности.

Отсюда практический вывод: качество нельзя выразить одной цифрой «вообще». Его оценивают по нескольким свойствам и всегда относительно задачи.

От свойств к метрикам: измерения качества данных

В работе с базами и хранилищами свойства переводят в проверки. Часто опираются на шесть измерений из рамки DAMA UK: полнота, уникальность, своевременность, валидность, точность и согласованность. Более подробная модель описана в стандарте ISO/IEC 25012, но для старта шести измерений обычно хватает.

Измерение Вопрос Как считать
Полнота (completeness) Есть ли значение там, где оно обязательно? Заполненные / все записи
Уникальность (uniqueness) Нет ли дублей одного объекта? Уникальные ключи / все записи
Валидность (validity) Соответствует ли значение формату и правилам? Прошедшие проверку / заполненные
Своевременность (timeliness) Достаточно ли свежие данные? Записи не старше порога / все
Согласованность (consistency) Совпадают ли значения в разных системах? Совпавшие / общие записи
Точность (accuracy) Совпадает ли значение с реальностью? Сверка с эталоном или выборочная проверка

Важная граница: валидность не равна точности. Email oleg@example.com валиден по формату, но может принадлежать не тому клиенту. Проверка формата ловит опечатки, а не ложь. Для точности нужен эталон: первичный документ, ответ клиента, повторное измерение.

Пример: считаем метрики качества данных на Python

Минимальный полный пример на стандартной библиотеке, без сторонних пакетов. Проверено на Python 3.14.

import re
from datetime import date

# Учебная выгрузка клиентов: 6 записей, в них спрятаны типовые дефекты
rows = [
    {"id": 1, "email": "anna@example.com",  "city": "Москва",  "updated": "2026-09-10"},
    {"id": 2, "email": "",                  "city": "Казань",  "updated": "2026-08-30"},
    {"id": 3, "email": "ivan(at)example",   "city": "N/A",     "updated": "2026-09-01"},
    {"id": 4, "email": "oleg@example.com",  "city": "Пермь",   "updated": "2024-02-15"},
    {"id": 4, "email": "oleg@example.com",  "city": "Пермь",   "updated": "2024-02-15"},
    {"id": 5, "email": None,                "city": "Самара",  "updated": "2026-09-20"},
]

MISSING = {None, "", "N/A", "-", "null"}          # что считаем пропуском
EMAIL_RE = re.compile(r"[^@\s]+@[^@\s]+\.[^@\s]+")    # упрощенная проверка формата
TODAY = date(2026, 9, 24)                         # фиксируем дату для воспроизводимости
MAX_AGE_DAYS = 90                                 # порог актуальности - бизнес-правило

def pct(part, whole):
    return round(100 * part / whole, 1)

n = len(rows)
filled_email = [r for r in rows if r["email"] not in MISSING]
filled_city = [r for r in rows if r["city"] not in MISSING]

completeness_email = pct(len(filled_email), n)
completeness_city = pct(len(filled_city), n)
validity_email = pct(sum(bool(EMAIL_RE.fullmatch(r["email"])) for r in filled_email), len(filled_email))
uniqueness_id = pct(len({r["id"] for r in rows}), n)
fresh = sum((TODAY - date.fromisoformat(r["updated"])).days <= MAX_AGE_DAYS for r in rows)
timeliness = pct(fresh, n)

print(f"Полнота email:     {completeness_email}%")
print(f"Полнота city:      {completeness_city}%")
print(f"Валидность email:  {validity_email}% (среди заполненных)")
print(f"Уникальность id:   {uniqueness_id}%")
print(f"Актуальность:      {timeliness}% (не старше {MAX_AGE_DAYS} дней)")

Вывод:

Полнота email:     66.7%
Полнота city:      83.3%
Валидность email:  75.0% (среди заполненных)
Уникальность id:   83.3%
Актуальность:      66.7% (не старше 90 дней)

Разбор по строкам:

  • Полнота email 66.7% — заполнены 4 из 6: пустая строка и None считаются пропуском.
  • Валидность 75% — из четырех заполненных адресов ivan(at)example не проходит формат. Знаменатель — заполненные значения, а не все записи, иначе пропуски посчитаются дважды.
  • Уникальность 83.3% — запись с id = 4 продублирована.
  • Актуальность 66.7% — две записи обновлялись в 2024 году. Порог 90 дней — условие задачи, а не стандарт: для курса валют порог измеряют минутами, для справочника стран — годами.

Регулярное выражение здесь упрощенное: оно ловит грубые ошибки формата, но не проверяет, что почтовый ящик существует. Проверка идет через fullmatch, а не match с ^...$: в Python $ допускает перевод строки в конце, и адрес "anna@example.com\n" из неочищенной выгрузки прошел бы как валидный.

Типичная ошибка: пропуски, которые не выглядят как пропуски

Частая ошибка новичка — считать пропуском только None.

rows = [
    {"email": "anna@example.com", "city": "Москва"},
    {"email": "",                 "city": "Казань"},
    {"email": "ivan(at)example",  "city": "N/A"},
    {"email": "oleg@example.com", "city": "Пермь"},
    {"email": "oleg@example.com", "city": "Пермь"},
    {"email": None,               "city": "Самара"},
]
n = len(rows)
print("email:", round(100 * sum(r["email"] is not None for r in rows) / n, 1))
print("city: ", round(100 * sum(r["city"] is not None for r in rows) / n, 1))

Результат на тех же данных:

email: 83.3
city:  100.0

Полнота city показана как 100%, хотя в одной записи вместо города стоит N/A. Исправление — явный список значений-пропусков (MISSING в основном примере) и договоренность с командой, какие значения им считаются. Этот список — часть определения метрики, его нужно записать рядом с отчетом.

Согласованность между системами на SQL

Согласованность проверяют, сравнивая одно и то же поле в двух источниках. Пример выполнен в SQLite 3.51. Логика запроса переносится в PostgreSQL и MySQL, но в PostgreSQL придется поменять синтаксис подсчета совпадений (об этом после вывода).

CREATE TABLE crm     (client_id INTEGER PRIMARY KEY, city TEXT);
CREATE TABLE billing (client_id INTEGER PRIMARY KEY, city TEXT);
INSERT INTO crm     VALUES (1,'Москва'),(2,'Казань'),(3,'Пермь'),(4,'Самара');
INSERT INTO billing VALUES (1,'Москва'),(2,'Казань '),(3,'Екатеринбург'),(5,'Тула');

-- Согласованность: доля общих клиентов, у которых город совпадает
SELECT
  COUNT(*)                                            AS common_clients,
  SUM(TRIM(c.city) = TRIM(b.city))                    AS same_city,
  ROUND(100.0 * SUM(TRIM(c.city) = TRIM(b.city)) / COUNT(*), 1) AS consistency_pct
FROM crm c
JOIN billing b ON b.client_id = c.client_id;

-- Кто есть в одной системе, но нет в другой (связность)
SELECT 'только в crm' AS side, client_id FROM crm
WHERE client_id NOT IN (SELECT client_id FROM billing)
UNION ALL
SELECT 'только в billing', client_id FROM billing
WHERE client_id NOT IN (SELECT client_id FROM crm);

Вывод sqlite3 -header -column:

common_clients  same_city  consistency_pct
--------------  ---------  ---------------
3               2          66.7
side              client_id
----------------  ---------
только в crm      4
только в billing  5

У клиента 2 в billing город записан с хвостовым пробелом — без TRIM согласованность упала бы до 33.3%, и это был бы дефект формата, а не расхождение по сути. У клиента 3 расхождение настоящее, и запрос не скажет, какая система права: для этого нужен эталон или правило «главной системы» по этому полю.

Сравнение SUM(a = b) работает в SQLite и MySQL, где результат сравнения — число. В PostgreSQL сравнение возвращает boolean, и первый запрос упадет с ERROR: function sum(boolean) does not exist; там пишут COUNT(*) FILTER (WHERE ...) или SUM(CASE WHEN ... THEN 1 ELSE 0 END). Еще одна граница: NOT IN с подзапросом, где встречается NULL, вернет пустой результат, поэтому ключи сравнения должны быть NOT NULL или нужен NOT EXISTS.

Как организовать оценку качества информации

Разовый подсчет полезен, но качество данных деградирует со временем: меняются формы ввода, интеграции, справочники. Рабочий порядок выглядит так:

  1. Сформулировать задачу, для которой нужны данные, и выбрать поля, критичные для нее.
  2. Для каждого поля выбрать измерения и записать правило: что считать пропуском, какой формат валиден, какой возраст допустим.
  3. Задать пороги: например, полнота email не ниже 95% для рассылки.
  4. Автоматизировать проверки и запускать их при каждой загрузке, а не раз в квартал.
  5. Для нарушений определить владельца: кто исправляет источник, а не только отчет.

Если метрики «плохие», а пользователи не жалуются — проверьте, не завышены ли пороги для задачи. Если метрики «хорошие», а в отчетах ошибки — скорее всего, проверяется формат, но не точность: добавьте выборочную сверку с первоисточником.

Выводы

  • Качество информации определяется относительно задачи: одни и те же данные могут быть пригодны для одной цели и непригодны для другой.
  • Основные свойства — объективность, достоверность, полнота, точность, актуальность, полезность, понятность и доступность; достоверность и точность, полнота и актуальность — разные свойства.
  • В инженерии данных свойства переводят в измеримые метрики: полнота, уникальность, валидность, своевременность, согласованность, точность.
  • Валидность формата не гарантирует точность: для точности нужен эталон или сверка с первоисточником.
  • Определение пропуска, пороги и правила — часть метрики; без них одна и та же таблица дает разные «проценты качества».

Где применяется / связь с практикой

Освойте тему на практике

Метрики качества данных нужны аналитикам, инженерам данных и тестировщикам хранилищ: проверки полноты и дублей встраивают в загрузки, согласованность считают при интеграции систем, а пороги актуальности закладывают в SLA отчетов. Как строить такие проверки системно, в пайплайнах и с мониторингом, разбирают на курсе Data Quality. Попробовать формат и темы можно на бесплатных открытых уроках Otus.

FAQ

Можно ли выразить качество данных одним числом?
Можно свести метрики во взвешенный индекс для дашборда, но веса выбираются под задачу, и за одной цифрой легко спрятать провал критичного поля. Для решений полезнее смотреть метрики по отдельности.

Чем качество данных отличается от их очистки?
Оценка качества измеряет и находит проблемы, очистка их исправляет. Без измерения до и после невозможно понять, помогла ли очистка.

Что делать с дублями, у которых разные значения полей?
Выбрать правило слияния: брать значение из главной системы, самое свежее по дате обновления или отправлять запись на ручную проверку. Правило стоит зафиксировать заранее, иначе результат зависит от порядка загрузки.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)