# 🪰 Uzum Fly: поиск товаров через нейронные связи мухи [Интерактивная страница](https://recsysfly.vyroslo.ru/) · [Выполненный ноутбук](notebooks/uzum_fly.ipynb) · [Источники и права](THIRD_PARTY_NOTICES.md) Uzum Fly вырос из шутки команды RecSys: «можно ли засунуть мозг мухи в рекомендации?». На странице муха **не покупает товары для себя**. Её обонятельный контур превращён в способ искать товары, похожие на недавние интересы покупателя. Можно выбрать одну из шести вымышленных сессий или собрать свою, переключить проводку, поставить лайк или дизлайк и увидеть результат. В расчёте участвуют **измеренные связи FlyWire v783** между проекционными нейронами и клетками Кеньона. При этом «запах» товара придуман нами: это проекция текстового эмбеддинга. Модель не обучена на кликах или покупках Uzum и не подключена к производственной рекомендательной выдаче. ## За минуту: весь путь ~~~mermaid flowchart LR A[24 252 товара: название и категория] --> B[Текстовый эмбеддинг: 384 числа] B --> C[Искусственный запах: 51 канал] C --> D[Связи FlyWire: PN → 4 678 KC] D --> E[234 активные KC] S[История сессии] --> C E --> F[Поиск пересечений: 200 кандидатов] F --> G[Полка: 12 карточек] L[Лайк и дизлайк] --> H[Изменение весов KC → MBON] H --> G ~~~ 1. Название и категория кодируются мультиязычной моделью paraphrase-multilingual-MiniLM-L12-v2 в 384-мерный вектор. 2. PCA сжимает вектор до 51 компоненты. Каждая назначается одной гломеруле; нелинейность и нормализация дают искусственный запах. Это наше сопоставление, а не умение мухи понимать товары. 3. По измеренной матрице PN→KC вычисляется активность 4 678 клеток Кеньона. Остаются 5% наиболее активных — **234 KC**, разреженный код товара. 4. Сессия превращается в смесь запахов просмотренных товаров. Её KC-код сравнивается с кодами каталога; инвертированный индекс возвращает 200 товаров с наибольшим числом общих KC. 5. Полка содержит 12 разных названий. До обратной связи порядок задаёт только пересечение кодов. После лайков к оценке добавляется изменение MBON-валентности. На странице доступны три вычислительных варианта: измеренная проводка FlyWire, перемешанная с сохранением числа связей каждого нейрона, и случайный FlyHash. Переключатель меняет результат расчёта. ## Модель подробнее ### Товар → запах Строка входа: «название | категория L2 | листовая категория». [Скрипт кодирования](scripts/rebuild_embeddings_from_catalog.py) восстанавливает эмбеддинги из каталога репозитория и публичного чекпойнта. [Адаптер](flyrec/odor.py) обучает PCA на каталоге, отображает 51 компоненту на гломерулы, применяет нелинейность к ORN и нормализацию антеннальной доли к PN. По умолчанию самые вариативные компоненты назначаются гломерулам с наибольшей суммой PN→KC-связей. Это сильный инженерный выбор. В контроле назначения перемешиваются: качество измеренной проводки заметно падает. ### Клетки Кеньона → кандидаты [Подграф](flyrec/connectome.py) содержит 51 гломерулу, 4 678 KC и 297 727 синапсов PN→KC после порога агрегации. Вход каждой KC нормируется; гомеостаз подстраивает её типичную активность на каталоге. Правило top-5% оставляет 234 победителя. Это **статический контур**, а не спайковый запуск полного мозга на каждый товар. Для каждой KC хранится список товаров, где она активна. Оценка кандидата равна числу общих KC, делённому на 234. Индекс ищет top-200 среди 24 252 товаров. Просмотренные товары исключаются, а одинаковые названия разных продавцов не занимают несколько мест на полке. ### MBON → обратная связь Начальные веса KC→MBON взяты из FlyWire. Холинергические и глутаматергические выходы грубо интерпретируются как «подойти» и «уйти». Лайк умножает веса активных KC на стороне избегания на 0,65; дизлайк делает то же на стороне приближения: ~~~text score = общие_KC / 234 + 2,5 × (MBON_после_лайков − MBON_исходный) ~~~ Вычитание исходного ответа принципиально: **до лайков MBON не меняет порядок полки**. Правило вдохновлено дофаминовой пластичностью. Нейроны DAN, пути PAM/PPL1 и компартменты не исполняются. Обратная связь действует лишь в текущей сессии страницы; пользовательский профиль не сохраняется. ## Что настоящее на экране | Элемент | Как устроен | |---|---| | 200 кандидатов, 12 карточек, запах сессии и активные KC | Считаются на сервере по выбранной проводке и сессии | | Карта 8 072 нейронов | Координаты и классы клеток из FlyWire v783 | | Подсветка ORN, PN, KC и агрегированный ответ MBON | Выход статического контура; MBON учитывает лайки | | Подсветка LN, APL и DAN | Условные индикаторы этапов, не вычисленные разряды | | Спайки Brian2 после сборки полки | Предварительно рассчитанная запись LIF-модели Shiu et al. для исходных персон FlyWire; выдачу она не строит | | Покупатели | Шесть вымышленных сессий из названий товаров или своя сессия | Фото на странице — миниатюры товаров с публичного CDN Uzum. На сервере заранее уменьшены и сохранены фото всех кандидатов шести встроенных сессий для трёх вариантов проводки — **1 663 товара**. Кеш переживает релизы. Произвольные товары кешируются после первого обращения; фотографии не участвуют в выборе. ## Научный результат и его предел [Ноутбук](notebooks/uzum_fly.ipynb) и [скрипт оценки](experiments/offline_eval.py) проверяют узкую задачу: по KC-коду восстановить 100 ближайших соседей **того же текстового эмбеддинга, из которого получен вход**. Взяты 1 000 запросов и пять seed для случайных контролей. mAP показывает сохранение близости исходных текстовых векторов; это не метрика качества рекомендаций. | Метод | mAP | |---|---:| | Плотный поиск по исходному эмбеддингу, эталон | 1,000 | | Плотный вектор после сжатия до 51 гломерулы | 0,562 | | Перемешанная проводка с теми же степенями нейронов и весами каждой KC | **0,530** | | Измеренная проводка FlyWire | 0,518 | | Случайный FlyHash | 0,491 | | SimHash по 51 каналу, 234 бита | 0,427 | | FlyWire при случайной раскладке компонент по гломерулам | 0,415 | Измеренный узор связей в этом опыте **не выиграл** у корректного перемешанного контроля. Часть результата FlyWire определяется нашим назначением компонент наиболее связанным гломерулам. Сравнение с SimHash не выравнивает память: полный KC-код занимает 4 678 бит, SimHash — 234. Из этой таблицы нельзя вывести прирост кликов, заказов или превосходство при равной цене. Для отдельной проверки был запущен код полной LIF-модели Shiu et al. в Brian2. При испытанных слабом и сильном запахах активировалось около 72–74% KC: такая конфигурация не дала нужного разреженного кода. Совпадение наиболее спайкующих KC со статическим кодом близко к случайному. Причина высокой активности не установлена без опыта без стимула и абляции рекуррентных связей. Поэтому товары выбирает статический контур, а запись Brian2 показана отдельно. ## Путь к настоящему RecSys Нужен следующий опыт: согласованные user/item-эмбеддинги, история пользователя только **до** момента прогноза и его действия **после** как метки. Нужны временной holdout, сравнение с текущим ANN и случайной/перемешанной проводкой при одинаковой памяти и стоимости, добавочный Recall@200 к существующим источникам и качество после неизменённого ранкера. Реальные сессии здесь пока не использовались. Если опыт подтвердит пользу, муху можно рассматривать как **дополнительный retrieval-источник**: product_id, fly_score и версия модели идут в общий пул кандидатов. Сайт не является производственным сервисом Uzum. ## Локальный запуск Нужен Node.js с поддержкой import.meta.dirname; проект проверен на Node 22. Каталог и готовые артефакты статического контура лежат в репозитории: ~~~bash git clone https://github.com/d3xr/uzum-fly.git cd uzum-fly node server.mjs # http://localhost:4173/ ~~~ Индекс трёх вариантов строится при старте. Сервер слушает только 127.0.0.1. Если CDN Uzum недоступен из вашей сети, названия товаров остаются, а фото заменяются заглушками. Пересчёт исследовательских артефактов требует Python 3.11: ~~~bash uv venv --python 3.11 .venv uv pip install --python .venv/bin/python -r requirements.txt PYTHONPATH=. .venv/bin/python scripts/rebuild_embeddings_from_catalog.py PYTHONPATH=. .venv/bin/python scripts/export_fly_index.py PYTHONPATH=. .venv/bin/python experiments/offline_eval.py PYTHONPATH=. .venv/bin/python -m unittest discover -s tests -v ~~~ Файл эмбеддингов не хранится в Git. Версии чекпойнта и библиотек могут слегка изменить числа при пересборке. Сырой коннектом можно получить командой PYTHONPATH=. .venv/bin/python -m flyrec.connectome; он скачивается из публичных источников в локальный кеш. Спайковый эксперимент запускается отдельно через experiments/lif_validation.py и требует минут CPU на стимул. ## Карта репозитория | Путь | Содержание | |---|---| | flyrec/ | Подграф, адаптер запаха, KC-код, retrieval, MBON и метрики | | lib/fly.mjs | Статическая модель на Node.js для сайта | | server.mjs | API, снимки анимации, поиск и кеш миниатюр | | scripts/ | Пересборка эмбеддингов и индекса, манифест и подготовка фото | | data/catalog.json и data/fly/ | Каталог и производные артефакты | | public/ | Интерфейс, стили, 3D-сцена, карта нейронов | | notebooks/uzum_fly.ipynb | Выполненные графики | | tests/ | Проверки перестановки рёбер и поиска соседей | API: /api/fly/meta.json, /api/fly/search.json?q=, /api/fly/sniff.json?p=gamer&v=flywire, /api/rooms/uzum-fly/snapshot.json. Параметр s задаёт ID товаров своей сессии, l и d — лайки и дизлайки, v — flywire, shuffled или random. ## Данные, авторство и права - Каталог — исторический срез публичных карточек за июль 2026: ID, названия, категории и URL фото. Цен, остатков, заказов и пользовательских действий нет. Текущая доступность товаров не проверяется. - FlyWire v783 и аннотации использованы с атрибуцией; [полный список источников](THIRD_PARTY_NOTICES.md). Новый MaleCNS Google/Janelia — другой набор данных, в вычислении этой версии он не используется. - Клиентская сцена переработана из CashbackFly по сообщённому владельцем проекта разрешению. Права на сторонний код, изображения, шрифты, данные и бренд остаются у правообладателей. Открытый просмотр исходников не выдаёт автоматической лицензии на повторное использование. - Код проектов из [awesome-fly](https://github.com/cobanov/awesome-fly) не переносился; этот каталог помог выбрать контрольные вопросы. Гипотеза основана на [Dasgupta et al., Science 2017](https://www.science.org/doi/10.1126/science.aam9868), данные и спайковая проверка — на [FlyWire](https://flywire.ai/) и [Shiu et al., Nature 2024](https://www.nature.com/articles/s41586-024-07763-9).