Искал пальмовое масло в 110 тысячах составов и нашёл его в витамине A. Почему поиск по слову врёт

У меня есть база составов продуктов, парсер тянет её из открытых источников уже полгода. Сейчас в ней 110 тысяч штрихкодов, у которых есть и название, и текст состава. На этой базе я считаю всякое для постов, и вот на прошлой неделе решил посчитать пальмовое масло. Задача на две минуты, казалось бы: grep по слову “пальм”, деление на общее число, готово.
Получилось 5,9% по всей базе. Нормально, похоже на правду. А потом я разбил по категориям и в детском питании увидел 10%. Каждая десятая смесь или каша с пальмой? Ну, сенсация же. Уже заголовок для поста придумал.
Хорошо, что перед публикацией я открыл выборку глазами. Правило у меня такое с прошлого раза, когда “без сахара” в поиске цеплял всё подряд.
Что было в выборке
Первая строка: молочная смесь, в составе “ретинола пальмитат”. Это витамин A. Вторая: каша, “аскорбилпальмитат” - антиокислитель Е304, производная аскорбинки. Третья: снова смесь, “2-пальмитоил” - это про структуру жира в детских смесях, там специально делают так, чтобы пальмитиновая кислота стояла в средней позиции молекулы, как в грудном молоке. Ни в одной из трёх пальмового масла не было!
Ушёл считать заново. Регулярка пальм(?!ит) вместо голого пальм - и цифры сразу другие:
по всей базе: 6 543 товара наивно, 6 012 строго. Ложных 531, около 8% от найденного;
детское питание: 215 наивно, 63 строго. Было 10,1%, стало 3,0%.
То есть треть сенсации, если честно, а две трети - витамин A и антиокислитель.
Среди 531 ложного срабатывания: аскорбилпальмитат - 316, разные другие пальмитаты (цетил и прочее, это косметика и БАД, они тоже в базе) - 94, ретинола пальмитат - 50, пальмитиновая кислота - 48, пальмитоил - 19. По брендам ложных больше всего у Беллакта, Nestle, Nutrilak, Kabrita, Nutrilon - вот вам и “детское питание с пальмой”.
Полез проверять остальное
Раз одно слово так подвело, я прогнал по базе ещё несколько, которые часто ищут в составах. Считал уникальные штрихкоды: сколько находит наивный поиск и сколько остаётся, если вычесть очевидно чужие вхождения.
Ищем | Наивно | Аккуратнее | Лишних | Кто виноват |
|---|---|---|---|---|
мёд | 9 149 | 1 403 | 7 746 | медь. Микроэлемент в смесях и витаминах |
соя | 14 575 | 6 536 | 8 039 | соевый лецитин и соевое масло |
орех | 8 594 | 6 936 | 1 658 | мускатный орех |
сахар | 46 722 | 46 374 | 348 | “без сахара”, сахарозаменитель, сахарный колер |
какао | 10 798 | 10 473 | 325 | “заменитель масла какао” |
молоко | 26 789 | 26 571 | 218 | кокосовое, миндальное, овсяное |
Мёд - мой любимый. Из 9 тысяч “медовых” составов 8 тысяч - это медь в витаминных премиксах. Ищешь мёд для аллергика, находишь Nutrilon.
С соей, кстати, спорно. Лецитин - соевый, и для аллергика это может быть важно, так что тут “лишние” в кавычках… Смотря что вы ищете: сою как ингредиент или сою как аллерген. А регулярка этого не знает, ей надо сказать.
Что я из этого вынес
Ничего нового, вроде, но каждый раз наступаю заново. Поиск по подстроке в тексте состава - это не поиск ингредиента. Состав пишется людьми, там “масло пальмовое” и “пальмовое масло”, “пальмоядровое”, “фракции пальмового”, “олеин”, и рядом ретинола пальмитат, который к пальме отношения не имеет, зато к букве “пальм” - самое прямое.
Нормальное решение - словарь ингредиентов с нормализацией, у меня он есть для Е-кодов (там своя история с латиницей и кириллицей в букве Е, писал об этом). Для обычных слов пока обхожусь регулярками с исключениями и одним правилом, которое, короче, дороже любого кода: перед тем как публиковать цифру, открыть 20 случайных строк из выборки и прочитать глазами.
Две минуты. А сенсацию про детское питание я бы иначе выпустил, и кто-нибудь в комментариях принёс бы мне пачку смеси с ретинола пальмитатом.
Скрипты подсчёта лежат рядом с базой, регулярки в тексте. Если у кого-то есть свой список таких ловушек в русских составах - интересно, что ещё я не вижу?
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.