Как я готовился к Честному знаку и разработал подход к нормализации данных. b2b.. b2b. Big Data.. b2b. Big Data. Data Mining.. b2b. Big Data. Data Mining. автозапчасти.. b2b. Big Data. Data Mining. автозапчасти. аналитика.. b2b. Big Data. Data Mining. автозапчасти. аналитика. ИИ.. b2b. Big Data. Data Mining. автозапчасти. аналитика. ИИ. искусственный интеллект.. b2b. Big Data. Data Mining. автозапчасти. аналитика. ИИ. искусственный интеллект. нормализация данных.. b2b. Big Data. Data Mining. автозапчасти. аналитика. ИИ. искусственный интеллект. нормализация данных. честный знак.

Примечание: Это первая статья из цикла, в которой я делюсь бизнес-смыслами и подходом к решению проблемы. Во второй статье планирую подробно разобрать техническую реализацию.

Вступление: Кот в мешке

Я работаю в компании, которая занимается автозапчастями. Не буду называть бренд, но представьте любой крупный интернет-магазин запчастей — у нас всё примерно так же.

Десять лет всё работало. Поставщики присылали прайсы, менеджеры загружали. В 90% случаев клиенты искали товар по артикулу — просто вбивали номер и получали результат. Оставшиеся 10% запросов — это названия вроде «хомут бмв х5». И поиск как-то справлялся.

Да, в базе была каша: один и тот же товар мог называться «Хомут винт. BMW X5/E81» и «Хомут крепления топливного шланга 12мм для BMW». Но артикулы вывозили, а на остальное закрывали глаза.

А потом мы узнали про Честный знак.

Проблема: 200 миллионов слепых котят

В 2026 году в автозапчастях вводится обязательная маркировка. Звучит скучно, пока не начинаешь разбираться.
Чтобы маркировать товар, нужно точно знать, что это за товар. Какая категория? Какие характеристики? Подпадает ли он под маркировку?
И тут мы полезли в свою базу.

200 миллионов номенклатур. Это не шутка, это реальная цифра за 10 лет работы.

И только 5% из них привязаны к категориям. Остальные 95% — это просто строки. Иногда осмысленные («Хомут винтовой 12-15 мм»), иногда — полная каша («BMW E81 12MM хомут крепл 1 шт»).

Мы не знали, что продаём. Буквально. Мы как котята, которые тыкаются в миску — вроде что-то съедобное, но что именно — непонятно.

Попытка решить вручную: 400 000 человеко-дней работы

Первая мысль — нанять студентов. Пусть сидят и вручную проставляют категории.

Посчитали: один человек обрабатывает 500 позиций в день. 200 млн / 500 = 400 000 человеко-дней.

Переведём в более понятные единицы:

  • При 250 рабочих днях в году: ~1 600 лет работы одним человеком

  • С командой из 100 человек: ~16 лет

  • С командой из 1 000 человек: ~1,6 года

Тысяча человек — это целый завод. С зарплатой 50 тыс — 50 млн в месяц только на зарплату, без налогов, без оборудования, без соцпакета.

Отбой. Ищем другой путь.

Рождение идеи: Вечера вместо сериалов

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

Взял выборку из 10 тысяч наших «грязных» названий. Поставил задачу: научиться из строки:

«Хомут винтовой крепления топливного шланга 12-15ММ 1 E81/82/87/88/F20, 3 E36/46/90/F30, 5 E39/60, 7 E38/65, X1 E84, X3 E83/F25, X5 E53/70, X6, Z3»

понимать:

  1. что это за предмет (хомут винтовой)

  2. какие у него характеристики (12-15 мм)

  3. для каких машин подходит (BMW 1, 3, 5, X5, X6…)

  4. и главное — к каким категориям это относится

Как дошёл до ИИ (и почему не сразу)

Этап 1. Регулярки и надежда

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

Написал. Работало на 10 примерах. На 100 — начало сбоить. На 1000 — понял, что так не вывезу. Слишком много вариантов написания, слишком много исключений, слишком много ручной работы под каждого поставщика.

Этап 2. Словари и регулярки (и почему они сдохли)

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

Регулярки работали, но их становилось всё больше. Сначала 10, потом 50, потом 200. Каждая новая регулярка замедляла обработку. Замерил: на 10 тысячах записей скорость упала в 3 раза. На 100 тысячах — в 10 раз.

Регулярки умерли. Они просто не масштабировались.

Этап 3. Aho-Corasick (алгоритм, который спас)

Тогда вспомнил про Aho-Corasick — это алгоритм для одновременного поиска множества подстрок за один проход текста. Сделал словари: «хомут» → «хомут», «хомутик» → «хомут», «clamp» → «хомут», «хомут винтовой» → «хомут винтовой».

Скорость вернулась. Мог искать 1000 паттернов за то же время, что раньше искал 1. Но качество упёрлось в потолок. Словари не покрывали всех вариантов написания, особенно когда в строке была каша из цифр, букв и служебных символов.

Этап 4. Подключил ИИ (и здесь началось интересное)

Когда понял, что правила и словари не покрывают всех случаев, решил попробовать нейросети. И тут ждал сюрприз.

Оказалось, что:

  1. Дорогие модели (GPT-4, Claude) работают отлично, но стоят денег

  2. Дешёвые модели работают так себе

  3. Есть локальные модели, которые можно дообучить под нашу специфику через LoRA — и они работают почти как дорогие, но за копейки

  4. А для 80% простых задач ИИ вообще не нужен — хватает тех же регулярных выражений или тривиальных преобразований

Этап 5. Комбинация инструментов

Разделил задачи по сложности и под каждую подобрал свой инструмент:

  1. Базовые операции (trim, lowercase, collapse_whitespace и тд.) — для приведения строк к единому виду

  2. Regex — для простых замен с чёткими паттернами (например, замена 5W-20 на 5w20 или удаление лишних символов)

  3. Aho-Corasick — для массовых замен по словарям (синонимы, бренды, модели)

  4. Локальные модели (LoRA) — для извлечения сущностей в типовых случаях

  5. Тяжёлые модели (OpenAI, YandexGPT) — только для самых сложных случаев, где нужно реальное понимание контекста

Этап 6. Всё это нужно было собрать в систему

И вот здесь родилась ключевая идея: пайплайны. Последовательность шагов, где каждый шаг делает что-то одно. Первый шаг — очистка мусора. Второй — извлечение характеристик. Третий — определение предмета. Четвёртый — маппинг на категории.

И чтобы это можно было настраивать без программистов — сделал визуальный конструктор.

Инсайты, которые родились в процессе

Инсайт 1. Не все поля нужно обрабатывать одинаково

В JSON-объекте товара есть десятки полей: артикул, бренд, название, описание, цена, остатки, характеристики. Мне нужно чистить только название и иногда описание. Остальные поля трогать нельзя — артикул должен остаться артикулом, бренд — брендом.

Пришлось придумать field selector’ы — механизм, который говорит: «примени это преобразование только к конкретному полю, а остальные поля оставь как есть». Без этого я бы поломал все данные.

Инсайт 2. Предметы и категории — это разные вещи

Сначала пытался заставить ИИ сразу определять категорию. Это плохо работало, потому что категория — вещь условная. Один и тот же предмет может лежать в разных категориях в зависимости от магазина.

Сделал иначе: ИИ вытаскивает предмет (хомут винтовой, прокладка, болт). А уже потом, через матрицу соответствий «предмет → категории», товар автоматически маппится на те категории, где этот предмет чаще всего встречается. Если предмет может относиться к нескольким категориям — берём лучшее пересечение.

Инсайт 3. ИИ должен быть сменным

Когда начинал, думал: привяжусь к OpenAI, и всё будет хорошо. А потом пришли юристы с работы и сказали: «А если данные не должны покидать РФ?»

Пришлось делать архитектуру, где можно подключить любую модель в два клика:

  • OpenAI (и всё совместимое)

  • YandexGPT (через Yandex Cloud — данные остаются в РФ)

  • Локальные модели (через Ollama или свои сервера)

  • Самописные (если вдруг)

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

Инсайт 4. Скрипты должны уметь ходить наружу

Стандартных экшенов (trim, lowercase, regex, aho) хватает для 80% задач. Но всегда есть 20%, где нужно что-то своё: сходить в CRM, проверить товар по API поставщика, подтянуть цену из внешней системы.

Добавил в Rhai (безопасный скриптовый язык) возможность делать HTTP-запросы прямо из пайплайна:

let response = http_get("https://api.supplier.ru/check/" + value.sku);
if response.status == 200 {
  value.verified = true;
  value.supplier_price = response.body.price;
} else {
  value.verified = false;
}
value
Как я готовился к Честному знаку и разработал подход к нормализации данных - 1

Что это даёт:

  • Можно обогащать данные в реальном времени

  • Можно проверять товары по внешним справочникам

  • Можно интегрироваться с чем угодно без доработки платформы

И всё это безопасно — Rhai работает в песочнице, никаких системных вызовов, только HTTP наружу с явного разрешения.

Инсайт 5. Масштабирование под ИИ-нагрузку

200 млн записей — это много. А ещё есть ИИ-обработка, которая может длиться секунды на одну запись. Если запустить всё последовательно, буду чистить базу до пенсии.

Особенность архитектуры — Rust-бэкенд потребляет минимум ресурсов и достаточно шустрый. Поэтому его масштабирование обходится дёшево. А провайдеры ИИ-моделей обычно не выставляют жёстких rate limit’ов — можно слать очень много запросов параллельно.

Kubernetes позволяет масштабировать обработку горизонтально: хочу обрабатывать быстрее — добавляю поды. Сейчас один под обрабатывает ~150 000 батчей в 6 часов при лимите CPU всего 300m (30% одного ядра). Технически можно увеличить лимиты и обрабатывать больше на одном поде, но мне удобнее масштабироваться через добавление подов — это даёт лучшую отказоустойчивость и упрощает управление ресурсами. Десять подов — 1.5 млн батчей в 6 часов. И это на тяжеловесных моделях.

Главное, что это линейно масштабируется. Хоть 200 млн обработаю.

Результат: Цифры, которые не стыдно показать

Через несколько месяцев вечерней работы получился работающий прототип. Прогнал через него 1 млн наших записей и получил:

Метрика

Значение

Точность обработки

96% (проверяли ручной выборкой)

Определение предмета

>85% (с нуля)

Категоризация

78% товаров получили категорию через маппинг предметов

Экономия vs ручная работа

до 75%

Пример того, что было и что стало:

Было (одна строка из прайс-листа поставщика):

"OC222 Фильтр масл._A-R 156 2.4TDi 97-> / Volvo 340/440/460/480 1.4/1.7/1.6D 79-95"
Как я готовился к Честному знаку и разработал подход к нормализации данных - 2

После прохода через:

{
  "article": "W9171",
  "brand": "MANN",
  "raw_name": "OC222 Фильтр масл._A-R 156 2.4TDi 97-> / Volvo 340/440/460/480 1.4/1.7/1.6D 79-95",
  "name": "Фильтр масляный",
  "subjects": [
    "масляный фильтр",
    "фильтр"
  ],
  "features": [
    "a-r",
    "двигатели 2.4 tdi",
    "двигатели 1.4",
    "двигатели 1.7",
    "двигатели 1.6d"
  ],
  "applicability": [
    {
      "brand": "VOLVO",
      "model": "340",
      "year": "1979-1995",
      "brand_info": {
        "name": "Volvo",
        "cyrillic_name": "Вольво",
        "country": "Швеция"
      }
    },
    {
      "brand": "VOLVO",
      "model": "440",
      "year": "1979-1995",
      "brand_info": {
        "name": "Volvo",
        "cyrillic_name": "Вольво",
        "country": "Швеция"
      },
      "model_info": {
        "name": "440",
        "cyrillic_name": "440",
        "class": "C"
      }
    },
    {
      "brand": "VOLVO",
      "model": "460",
      "year": "1979-1995",
      "brand_info": {
        "name": "Volvo",
        "cyrillic_name": "Вольво",
        "country": "Швеция"
      },
      "model_info": {
        "name": "460",
        "cyrillic_name": "460",
        "class": "C"
      }
    },
    {
      "brand": "VOLVO",
      "model": "480",
      "year": "1979-1995",
      "brand_info": {
        "name": "Volvo",
        "cyrillic_name": "Вольво",
        "country": "Швеция"
      },
      "model_info": {
        "name": "480",
        "cyrillic_name": "480",
        "class": "C"
      }
    }
  ]
}
Как я готовился к Честному знаку и разработал подход к нормализации данных - 3

И теперь, имея предметы, через матрицу соответствий автоматически отношу этот товар к категориям:

  • Фильтры (основная)

  • Масляная система (дополнительная)

Эта универсальная система категоризации теперь позволяет точно определить, какие товары подлежат маркировке по «Честному знаку». Правила маркировки привязаны к категориям товаров и их свойствам, и теперь, когда мы знаем категории всех 200 миллионов позиций, можем автоматически применять эти правила. Раньше мы не могли этого сделать — не знали, к каким категориям относятся 95% товаров. Теперь система проверяет каждую позицию по матрице соответствий «категория → необходимость маркировки» и формирует чёткий список.

Что даёт чистая база кроме маркировки

Когда привёл 200 млн записей в порядок, осознал, что открыл новые возможности для монетизации, о которых раньше не подозревал.

Раньше: База была чёрным ящиком. Мы знали, что что-то продаётся, но что именно — могли понять только по артикулам и брендам, которые помнили менеджеры.

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

1. Какие бренды у нас вообще продаются и на какие машины?

Раньше информация о бренде бралась из поля “brand” в прайсе. Мы знали, что “ABS” — это бренд запчастей, но не знали статистику: какая категория товаров, на какие машины, какого года выпуска и т.д. Теперь мы точно знаем распределение:

Ранг | Бренд          | % от всех позиций
----------------------------------------
1    | HYUNDAI        | 9.0%
2    | TOYOTA         | 8.2%
3    | VOLKSWAGEN     | 6.6%
4    | BMW            | 6.0%
5    | KIA            | 5.4%
6    | AUDI           | 4.9%
7    | MERCEDES-BENZ  | 4.8%
8    | RENAULT        | 4.5%
9    | NISSAN         | 4.0%
10   | FORD           | 4.0%
11   | MITSUBISHI     | 3.4%
12   | CHEVROLET      | 2.6%
13   | SKODA          | 2.6%
14   | VOLVO          | 2.6%
15   | OPEL           | 2.2%
16   | LADA           | 3.7%
17   | MAZDA          | 1.9%
18   | CITROEN        | 1.7%
19   | CHERY          | 1.6%
20   | PEUGEOT        | 1.6%
Как я готовился к Честному знаку и разработал подход к нормализации данных - 4

Что мы видим: Корейские бренды (Hyundai, Kia) в сумме дают почти 15% ассортимента — это характерная особенность нашего ассортимента. А Lada даёт 3.7% — не так много, как можно было подумать.

2. Что именно мы продаём? (ТОП предметов)

Теперь мы знаем, какие товары составляют основу нашего ассортимента:

Ранг | Предмет               | % от всех позиций
----------------------------------------
1    | фильтр                | 6.7%
2    | прокладка             | 4.1%
3    | колодки               | 3.1%
4    | тормозные колодки     | 2.9%
5    | масло                 | 2.4%
6    | подшипник             | 2.4%
7    | моторное масло        | 2.3%
8    | воздушный фильтр      | 2.1%
9    | датчик                | 2.1%
10   | фара                  | 2.0%
11   | опора                 | 1.9%
12   | кольцо                | 1.8%
13   | сальник               | 1.8%
14   | масляный фильтр       | 1.8%
15   | кронштейн             | 1.7%
16   | накладка              | 1.6%
17   | ремень                | 1.5%
18   | сайлентблок           | 1.5%
19   | диск                  | 1.5%
20   | бампер                | 1.4%
Как я готовился к Честному знаку и разработал подход к нормализации данных - 5

Что мы видим: Фильтры (всех типов) в сумме дают около 10% ассортимента. Это товары с высокой оборачиваемостью — их нужно держать в стоке всегда.

А вот “колодки” и “тормозные колодки” — это не одно и то же. В нашей системе классификации это разные уровни детализации:

  • Предмет первого ранга (“колодки”) — общая категория товара

  • Предмет второго ранга (“тормозные колодки”) — более конкретное определение с указанием назначения

Это работает по принципу иерархической классификации: система извлекает из названия ключевые сущности (subjects) разного уровня детализации. “Колодки” — это общий тип товара, а “тормозные колодки” — уже конкретизированный вариант с указанием системы автомобиля.

Нормализация помогла нам увидеть эту структуру и правильно классифицировать товары по уровням детализации, что критически важно для точной аналитики и управления ассортиментом.

3. Какие модели автомобилей самые популярные?

Через применимость мы теперь знаем, под какие модели у нас больше всего запчастей:

Ранг | Модель        | % от всех связок
----------------------------------------
1    | SOLARIS       | 1.0%
2    | LOGAN         | 1.0%
3    | A3            | 1.0%
4    | CAMRY         | 0.9%
5    | RIO           | 0.8%
6    | OCTAVIA       | 0.8%
7    | GOLF          | 0.8%
8    | ELANTRA       | 0.7%
9    | PASSAT        | 0.7%
10   | ACCENT        | 0.7%
11   | POLO          | 0.7%
12   | A4            | 0.7%
13   | COROLLA       | 0.7%
14   | SPORTAGE      | 0.7%
15   | DUSTER        | 0.6%
16   | 3             | 0.6%
17   | SANTA FE      | 0.6%
18   | TUCSON        | 0.6%
19   | AVEO          | 0.6%
20   | FOCUS         | 0.6%
Как я готовился к Честному знаку и разработал подход к нормализации данных - 6

Что мы видим: Ожидаемо лидируют бюджетные модели (Solaris, Logan, Rio) ��� они составляют основу нашего ассортимента.

Но есть две интересные находки:

  • Audi A3 на 3-м месте — неожиданно высоко

  • Toyota Camry на 4-м месте — подтверждает репутацию надёжного седана, который долго служит и требует обслуживания

Особенно интересен случай с Audi A3. Почему так высоко в рейтинге запчастей? Несколько причин:

  1. Массовость в своём сегменте: A3 — самый доступный Audi, его продавали огромными тиражами. За 10+ лет выпуска накопился большой парк.

  2. Возраст парка: Многие A3 первого и второго поколений (выпуска 1996-2012 годов) уже требуют серьёзного обслуживания. Владельцы готовы вкладываться в ремонт, так как покупка нового премиум-автомобиля обходится дороже.

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

Что касается Camry — это классический случай “вечной” машины. Её ремонтируют десятилетиями, потому что конструкция проверена временем, а стоимость обслуживания разумная.

4. Какие года выпуска самые ходовые?

Мы проанализировали все связки “товар — модель авто” и посмотрели, для каких лет выпуска чаще всего подбирают запчасти:

Формат года | % от всех связок
----------------------------------------
2006-       | 5.1%
2010-       | 4.1%
2007-       | 4.0%
2004-       | 3.9%
2005-       | 3.5%
2011-       | 3.4%
2008-       | 3.2%
2012-       | 3.2%
2003-       | 2.9%
2009-       | 2.7%
2002-       | 2.2%
2015-       | 2.0%
2013-       | 1.9%
2000-       | 1.8%
2014-       | 1.7%
Как я готовился к Честному знаку и разработал подход к нормализации данных - 7

Что мы видим: Пик приходится на 2006-2010 годы — это машины, которые уже вышли из гарантии, но ещё не отправились на свалку. Для них нужны запчасти, и владельцы готовы платить. Машины младше 2015 года (2.0%) пока редко попадают в наш ассортимент — либо ещё на гарантии, либо ремонтируются у официальных дилеров. А вот машины 2000-2003 годов (ещё 2-3%) — это уже “олдтаймеры”, для которых запчасти ищут коллекционеры и энтузиасты.

5. Какие предметы в каких категориях лежат?

Мы видим, что “фильтр” может быть масляным, воздушным, топливным, салонным. “Колодки” бывают тормозными (передние/задние), а бывают — стояночного тормоза.

Это позволяет умнее строить навигацию по сайту и перекрёстные рекомендации. Например, если человек купил масляный фильтр, ему скорее всего нужно и масло (2.4% ассортимента) — и мы можем предложить это сразу.

6. Аналитика для закупок

Теперь мы понимаем, что для Hyundai Solaris (самая популярная модель) чаще всего покупают:

  • масляные фильтры (каждые 10-15 тыс км)

  • тормозные колодки (каждые 30-40 тыс км)

  • сайлентблоки (после 60-80 тыс км)

Значит, эти позиции должны быть в стоке всегда. А вот, скажем, фары для Audi A3 покупают реже, но когда покупают — готовы ждать под заказ.

7. Прогнозирование спроса

Имея чистые данные за несколько лет, можно строить модели:

  • зимой растёт спрос на свечи накала (для дизелей) и антифризы

  • перед летом — на кондиционеры и радиаторы

  • при росте курса валют — на бюджетные аналоги (корейские бренды выходят на первый план)

Цифры, которые мы получили

Что измерили

До нормализации

После

Товаров с известным брендом

~0%

>85%

Товаров с известной моделью

~0%

>85%

Товаров с известной категорией

5%

78%

Возможность аналитики по спросу

почти 0

есть по всем разрезам

От эксперимента к подходу

Когда я показал результат коллегам, они сказали: «Это работает. Надо внедрять». Внедрили. Система обрабатывает наши данные до сих пор.

А потом я посмотрел по сторонам и понял: такая проблема не только у нас. У любого, кто торгует сложными товарами (автозапчасти, стройматериалы, одежда, электроника) — та же беда. Поставщики присылают кто во что горазд, менеджеры правят руками, база превращается в свалку.

И Честный знак придёт ко всем.

Поэтому я решил систематизировать свой подход. Доработал интерфейс, добавил визуальный конструктор пайплайнов (чтобы любой аналитик мог настраивать без программистов), упаковал в Kubernetes.

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

Техническая реализация (для технарей)

Если коротко:

  • Ядро: Rust (безопасность, скорость, предсказуемость)

  • API: gRPC (строгая типизация, streaming)

  • Фронтенд: Nuxt + визуальный конструктор

  • Инфраструктура: Kubernetes (горизонтальное масштабирование, self-healing)

  • Хранилище: PostgreSQL (конфиги, история, задачи)

  • Скриптинг: Rhai (изолированная среда)

  • ИИ: Адаптеры под OpenAI, YandexGPT, локальные модели

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

  • Field selector’ы для точечной обработки полей

  • Aho-Corasick для быстрых множественных замен

  • JSON Schema для валидации

  • Регулярные выражения

  • Типовые операции смены регистров, удаления пробелов

  • Произвольный код RHAI с расширением функционала стандартной библиотеки

  • Полная поддержка работы в РФ (Yandex Cloud)

Что дальше

Этот подход начался как внутреннее решение конкретной проблемы. В процессе работы над ним родилось много инсайтов о том, как подходить к нормализации данных в современных условиях.

Если тема нормализации данных, подготовки к Честному знаку или работа с большими объёмами неструктурированной информации вам интересна — давайте обсудим в комментариях или личных сообщениях. Мне интересно узнать, с какими похожими проблемами сталкиваетесь вы и какие подходы находите эффективными.

Особенно было бы полезно услышать от тех, кто:

  • Работает с похожими объёмами данных

  • Уже сталкивался с необходимостью маркировки товаров

  • Имеет опыт внедрения ИИ-решений для обработки текстов

  • Пытался решать подобные задачи другими способами

Также планирую написать вторую, более техническую статью, где подробно разберу архитектуру решения, особенности реализации на Rust, работу с Kubernetes и нюансы интеграции разных ИИ-моделей.


P.S. Долго не решался написать статью — это моя первая попытка поделиться опытом. Писал, чтобы рассказать о решении сложной задачи нормализации данных и обсудить подходы, которые могут оказаться полезными другим разработчикам и аналитикам. Если что-то сделал не так или упустил — сори, буду рад конструктивной критике в комментариях.

Автор: IgorBatanov

Источник

Rambler's Top100