Две недели назад я выложил сюда разбор: прогнал 60 тысяч составов продуктов через свой алгоритм и посчитал, сколько на полке зелёного, жёлтого и красного. Получилось 43 / 38 / 18.

Статью прочитали 7,6 тысяч человек. И вот что забавно , комментарии оказались полезнее самой статьи. Мне за два дня накидали четыре дыры, из которых про две я знал и стыдливо молчал, а про две не думал вообще.

Разбираю по порядку. Без отмазок — где дыра, там дыра.

Дыра 1. Соли в данных почти нет

Самое обидное. Формула штрафует за натрий, порог стандартный:

соль (в пересчёте на NaCl) на 100 г:
  < 0.3 г   →  0
  0.3–1.5 г → -1
  > 1.5 г   → -2

Проблема в том, что натрий заполнен примерно у трети товаров в базе. У остальных двух третей поля просто нет. И алгоритм в этом случае не штрафует.

То есть молчание в данных трактуется как «соли нормально». Это не нейтральная позиция, это подарок производителю. Колбаса, у которой натрий не указан, выглядит чище колбасы, которая честно написала 2,1 г. Косяк, чего уж.

Почему так вышло: в ТР ТС 022/2011 таблица пищевой ценности обязательна, а вот натрий в неё отдельной строкой не входит. Пишут по желанию. По моей выборке — не пишет никто, кроме крупных брендов и импорта.

Что с этим делать, я пока не знаю. Варианты, которые вижу:

  1. Штрафовать за отсутствие данных. Плохо: накажем честные продукты без соли — воду, крупу, масло.

  2. Достраивать по категории. Условно: «колбаса варёная → медиана 1,9 г». Это уже домысел, а домыслы у меня один раз уже стрельнули (об этом ниже).

  3. Показывать явно: «по соли данных нет». Честно, но пользователю у полки от этого ни тепло ни холодно.

Пока склоняюсь к третьему плюс медленно добираю натрий парсером с сайтов производителей.

Дыра 2. Сто грамм — это не порция

Классический пример от комментатора: кетчуп. По соли и сахару на 100 г он красный. Но кетчупа кладут ложку — грамм пять. И эта ложка обеспечивает съедание 200 граммов совершенно зелёной гречки.

Формально я прав, по жизни — нет.

Честный фикс требует таблицы типовых порций по категориям. Для российской полки я такой таблицы не нашёл. У USDA и EFSA порции есть, но под свои рынки — сколько там американец кетчупа наливает, я догадываюсь, и цифра эта расчитывается явно не на нашу гречку.

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

Промежуточное решение — категорийная метка «продукт-приправа», у которой вердикт считается, но подаётся с оговоркой. Не гениально, зато не враньё.

Дыра 3. Домысел о насыщенных жирах (эту я нашёл сам, и она была хуже всех)

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

Под раздачу попадали сыр, орехи, оливковое масло, рыба, сырники. Я прогнал диагностику локально на мастер-файле парсера и чуть со стула не упал: 43% всех красных держались на этом домысле. 6245 товаров были красными ни за что.

Починил так: домысел теперь штрафует вдвое слабее реальных данных, и в разбор пишется метка sat_fat>5_est — видно, что цифра оценочная.

было:  нет данных → жир × 0.30 → штраф как за факт   (-2)
стало: нет данных → жир × 0.30 → штраф ополовинен    (-1) + метка "оценка"

Пересчёт всей базы после правки: было 37/39/24, стало 42/39/19.

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

Дыра 4. Я оцениваю вещество, а не его законность в этой категории

Эту мне нашли не здесь, а на Пикабу, и она самая неприятная.

Есть партии продуктов, которые заворачивают на границе из-за добавки. Например, лапша быстрого приготовления с рибофлавином (Е101). По токсикологии рибофлавин — это витамин B2, никакого вреда, и мой алгоритм такую лапшу спокойно красит в жёлтый.

А запрет там не про токсикологию вообще. Он про три другие вещи:

  • Фальсификация. Жёлтый цвет лапши традиционно даёт яичный желток или дорогая твёрдая пшеница. Кинул краситель в дешёвую муку на воде — и визуально получил «яичную» премиум-лапшу.

  • Суммарная доза. Норма ADI считается на весь суточный рацион. Если разрешить подсластители в снеках, которые едят пачками, суммарное потребление становится неконтролируемым.

  • Матрица продукта. Бензойная кислота в бруснике связана с клетчаткой и полифенолами, и усваивается иначе, чем чистая бензойная в сладком геле.

Ни одного из этих трёх соображений в моей формуле нет. Я смотрю на вещество и его профиль риска, а перечни ТР ТС 029/2012 разрешают добавку не вообще, а под конкретную категорию продукта и под конкретную норму.

Причём в справочнике на сайте это как раз написано по каждому коду — где разрешён, где исключён, какая ADI: разборы 243 добавок. А в самом алгоритме категория не участвует. Справочник и формула разошлись, и я это проморгал.

Чинится, судя по всему, только приделыванием категории продукта к каждой карточке, что бы правила можно было вешать на категорию, а не на вещество. У меня категория сейчас есть примерно у половины базы. Значит сначала категории, потом уже категорийные правила.

Что я из этого забираю

Формула у меня арифметическая и открытая — сахар, соль, насыщенные жиры, добавки, суммируем штрафы, порог красного минус три. Это её сила: любой может пересчитать руками и поймать меня за руку. Что и произошло.

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

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

Отдельное спасибо тем, кто написал, что универсальная формула вообще не нужна, а нужен профиль: «мне нельзя глютен», «ищу без сахара», «ограничиваю натрий». Это независимо предложили два человека, и это ровно то, что у меня записано в план как платная часть. Приятно, когда пользователи придумывают твой роадмап за тебя )