bin: дискретизация числовых значений

Дискретизация числовых значений (bin) в Vega-Lite и Vega

Бинирование (binning) — преобразование непрерывной числовой шкалы в набор дискретных интервалов. В контексте Vega-Lite это один из базовых механизмов подготовки данных для визуализаций распределений, прежде всего гистограмм, тепловых карт и агрегированных диаграмм плотности.

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

  • визуализация становится «шумной»;
  • распределение трудно интерпретировать;
  • отдельные значения перегружают ось категорий.

Бинирование решает эту проблему, группируя значения в интервалы фиксированной или вычисляемой ширины.

Базовая концепция bin в Vega-Lite

В Vega-Lite бин задаётся прямо внутри канала поля (encoding) с помощью свойства bin.

Минимальная форма:

{
  "mark": "bar",
  "encoding": {
    "x": {
      "field": "value",
      "type": "quantitative",
      "bin": true
    },
    "y": {
      "aggregate": "count",
      "type": "quantitative"
    }
  }
}

Здесь:

  • bin: true включает автоматическое разбиение диапазона;
  • Vega-Lite сам выбирает параметры интервалов;
  • результатом является гистограмма.

Как работает биннинг внутри Vega-Lite

При включении bin происходит трансформация данных:

  1. вычисляется диапазон значений (min, max);

  2. диапазон делится на интервалы;

  3. каждому значению присваивается интервал;

  4. создаются вспомогательные поля:

    • bin_start
    • bin_end

Эти поля можно использовать для точного контроля отображения.

Управление параметрами bin

Биннинг можно настраивать явно, заменяя true объектом.

Количество интервалов: maxbins

"bin": {
  "maxbins": 20
}

maxbins задаёт верхнюю границу количества интервалов. Фактическое число может отличаться в зависимости от «красоты» шкалы.

Особенности:

  • Vega-Lite стремится к «человеческим» границам (1, 2, 5, 10);
  • итоговое число bins может быть меньше maxbins;
  • используется эвристика выбора шага.

Фиксированный шаг: step

"bin": {
  "step": 5
}

step задаёт фиксированную ширину интервала.

Используется, когда:

  • важна точная интерпретация шкалы;
  • требуется сопоставимость нескольких графиков;
  • необходимо строгое разбиение (например, по 10 единиц).

Ограничение диапазона: extent

"bin": {
  "extent": [0, 100]
}

extent фиксирует диапазон бининга. Значения вне диапазона могут игнорироваться или попадать в крайние интервалы.

Применение:

  • унификация нескольких графиков;
  • обрезка выбросов;
  • сравнение распределений.

Привязка шкалы: anchor

"bin": {
  "anchor": 0
}

anchor задаёт точку привязки интервалов. Полезно, если важно, чтобы границы bins начинались от конкретного значения.

Пример: интервалы должны быть кратны 10, начиная с 0.

Управление «красотой» шкалы: nice

"bin": {
  "nice": true
}

nice включает автоматическую подгонку границ к удобным числам.

Пример:

  • вместо 3.1415–97.23 → 0–100;
  • упрощает восприятие осей.

Использование bin в гистограммах

Классический сценарий — построение гистограммы.

{
  "data": {"url": "data.csv"},
  "mark": "bar",
  "encoding": {
    "x": {
      "field": "value",
      "type": "quantitative",
      "bin": {"maxbins": 30}
    },
    "y": {
      "aggregate": "count",
      "type": "quantitative"
    }
  }
}

Ключевая идея:

  • x разбивается на интервалы;
  • y считает количество элементов в каждом интервале.

Явные поля bin_start и bin_end

Vega-Lite создаёт вспомогательные поля, которые можно использовать напрямую:

{
  "transform": [
    {
      "bin": true,
      "field": "value",
      "as": "binned_value"
    }
  ]
}

В Vega (низкоуровневый слой) появляются:

  • binned_value_start
  • binned_value_end

Это позволяет:

  • строить кастомные оси;
  • использовать интервалы в tooltips;
  • комбинировать с другими трансформациями.

Биннинг по нескольким измерениям

Bin может применяться не только к оси X.

Пример: тепловая карта

{
  "mark": "rect",
  "encoding": {
    "x": {
      "field": "x",
      "type": "quantitative",
      "bin": true
    },
    "y": {
      "field": "y",
      "type": "quantitative",
      "bin": true
    },
    "color": {
      "aggregate": "count"
    }
  }
}

Здесь:

  • пространство разбивается на сетку;
  • каждая ячейка агрегирует количество точек.

Особенности взаимодействия bin с агрегатами

Bin почти всегда используется вместе с агрегированием:

  • count
  • sum
  • mean
  • median

Логика:

  1. данные разбиваются на интервалы;
  2. внутри интервала применяется агрегация.

Пример:

"y": {
  "field": "price",
  "bin": true,
  "aggregate": "mean"
}

Результат:

  • средняя цена по каждому диапазону.

Влияние типов шкал

Bin корректно работает только с:

  • quantitative (числовые данные);
  • иногда с датами (timeUnit используется отдельно, но концептуально похоже).

Не применяется к:

  • nominal;
  • ordinal.

Взаимодействие bin с scale

При биннинге Vega-Lite автоматически адаптирует шкалу:

  • дискретная ось (band scale) вместо continuous;
  • метки ставятся по границам интервалов;
  • подписи могут быть округлены.

Пример поведения:

  • без bin: значения 1, 2, 3, 4…
  • с bin: диапазоны 0–10, 10–20, 20–30…

Типичные ошибки при использовании bin

Несоответствие агрегирования

Ошибка:

"x": {"field": "value", "bin": true},
"y": {"field": "value", "type": "quantitative"}

Проблема:

  • нет агрегации;
  • данные дублируются по интервалам;
  • визуализация теряет смысл.

Конфликт step и maxbins

Если заданы одновременно:

  • step имеет приоритет;
  • maxbins игнорируется.

Неправильный extent

Если extent меньше реального диапазона данных:

  • часть значений теряется;
  • распределение искажается.

Производительность binning

Биннинг выполняется на этапе трансформации данных:

  • в Vega-Lite — при компиляции спецификации;
  • в Vega — как transform pipeline.

Особенности:

  • линейная сложность O(n);
  • хорошо масштабируется до сотен тысяч точек;
  • при больших датасетах критично уменьшает визуальную нагрузку.

Сравнение bin и timeUnit

Хотя оба механизма создают интервалы, различия принципиальные:

  • bin — числовые интервалы;
  • timeUnit — временные (дни, месяцы, годы).

Пример timeUnit:

"timeUnit": "month"

Пример bin:

"bin": {"step": 10}

Использование bin в Vega (низкоуровневый уровень)

В Vega bin задаётся как transform:

{
  "type": "bin",
  "field": "value",
  "as": ["start", "end"],
  "maxbins": 20
}

Результат:

  • явное управление полями;
  • возможность сложных пайплайнов трансформаций;
  • более детальная настройка по сравнению с Vega-Lite.

Практические паттерны

Гистограмма плотности

  • bin + count
  • стандартный способ анализа распределений

Сравнение распределений

  • фиксированный step
  • одинаковый extent для нескольких датасетов

Аномалии и выбросы

  • small bins + ограниченный extent
  • визуализация хвостов распределения

Двумерное распределение

  • bin по X и Y
  • color = count

Поведение при пустых бин-интервалах

Если в интервале нет данных:

  • Vega-Lite может не рисовать соответствующую колонку;
  • при необходимости используется impute или фиксированные domain значения шкалы.

Роль bin в аналитических интерфейсах

Биннинг часто является скрытым, но критически важным элементом:

  • формирует восприятие распределения;
  • влияет на интерпретацию плотности;
  • задаёт уровень детализации анализа;
  • определяет баланс между точностью и читаемостью.