Русский
Русский
English
Статистика
Реклама

Vk

Анонс как дата-саентисты в ВК делают рекламу эффективной

27.12.2020 14:05:39 | Автор: admin

Завтра, 28 декабря в 20:00 у нас выступает Артем Попов тимлид команды VK Performance Advertising.

Артем руководит командой, которая занимается задачами, связанными с Data Science в рекламе. Их задача делать рекламу в ВК эффективнее и выгодней.

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

Артем расскажет про интересные задачи для дата-саентистов в мире рекламы.



О чем пойдет речь на эфире


  • рекламные технологии: какие интересные вещи есть в рекламе
  • рекламные аукционы, как они устроены и какие там есть интересные задачи
  • что интересного происходит в дизайне аукционов
  • в чем сложность предсказания отклика пользователя, например, клика на рекламу, подписки на сообщество или покупки в интернет-магазине
  • стратегии проведения рекламных компаний
  • ML in production: с каким трудностями и каким сложностями сталкиваются новички в продуктовых командах, которые долго занимаются одним и тем же продуктом
  • как меняется жизнь разработчика после попадания в такую команду и как надо работать, чтобы все было хорошо
  • как быть классным разработчиком ML-продуктов с точки зрения софт-скиллов
  • какие сложности на разработчка накладывает то, что ML сфера предположений и ты не знаешь, как именно придешь к результату
  • чего не хватает ребятам, которые на старте карьеры приходят заниматься задачами связанными с Data Science

Как не пропустить эфир?


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


До встречи в эфире!





Подробнее..

Как дата-саентисты в ВК делают рекламу эффективной

04.01.2021 16:19:24 | Автор: admin
Еще в прошлом году у нас выступал Артем Попов, тимлид команды VK Performance Advertising. Делимся с вами расшифровкой эфира и записью.




Меня зовут Артем, я руководитель performance advertising в ВК. Наша команда занимается тем, что, с одной стороны, делает рекламу в ВК эффективнее, выгоднее для рекламодателей, интереснее для пользователей. Это большая продуктовая цель.

С другой стороны, технически, мы команда ML-инженеров, довольно обычных разработчиков, которые много времени занимаются задачами, связанными с data science и ML. Сегодня я хочу поговорить про эти две темы, потому что обе они мне интересны, я о них люблю поговорить. Я очень рассчитываю на то, что у нас будет живое общение; если кто-то смотрит трансляцию, будет интереснее, если вы будете писать вопросы.

В целом, я хочу разделить нашу беседу на два блока. В первом я расскажу о разных задачах, которые встречаются в рекламе в пересечении с data science. То есть, почему реклама может быть интересной областью для ML-специалиста, для специалиста в области data science. С другой стороны, я хочу поделиться своим опытом перехода в инженерный ML-проект, тем, чему я учился те четыре года, которые занимался ML в рамках инженерной истории. И рассказать про то, какие вещи встречаются в больших компаниях, но про которые не рассказывают на разных курсах; какие есть скиллы, которым тяжело научиться, когда ты учишься data science или ML в рамках университета или онлайн-образования. Постараюсь уделить каждой теме по полчаса.

Сначала расскажу про рекламу, рекламные технологии, computational advertising как поле для исследований, научной и инженерной деятельности то есть, область знаний; какие задачи там бывают, и почему прикольно ими заниматься, когда есть NLP и прочие хайповые штуки, а про рекламу не так часто говорят.

Общая задача звучит так: у нас есть набор рекламодателей. Ими могут быть любые пользователи, которые хотят продвинуть знание о своем продукте, своем бизнесе. У них у всех есть свои собственные, различные цели. Кто-то желает просто показать свою рекламу как можно большему количеству человек; например, у условной Кока-колы задача сделать так, чтобы все знали про их бренд, чтобы все помнили, что такой напиток есть, что сейчас новый год, и нет другой альтернативы, кроме этого напитка, если вы идете в магазин. Другой хороший пример Fairy: сколько вы знаете других моющих средств, кроме него? Это все brand awareness; крупные рекламодатели ставят цель сделать так, чтобы у всех в голове осталось знание о том, что существует определенный продукт.

Есть другие цели. Например, более прикладные, так называемые performance-цели. Это когда рекламодатель хочет, чтобы вы перешли за рекламой и сделали какое-то действие. Например, зашли на сайт и оставили заявку на кредит. Или купили что-то в интернет-магазине. И так далее.
В целом, задача рекламы приносить новых пользователей какому-то бизнесу (так называемых лидов) и делать так, чтобы эти пользователи делали что-то полезное для рекламодателя и приносили прибыль его бизнесу.

У нас есть площадка место, где мы позволяем показывать рекламу. В случае с ВК это лента; в случае какого-то другого сайта это может быть, например, баннер. Цель площадки заработать денег на рекламе, она продает внимание пользователей за деньги. Благодаря этому ВК остается бесплатным проектом; можно было бы придумать другие модели монетизации, но рекламная модель хорошо работает для подобного сервиса.

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

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

У нас есть три силы: пользователь, рекламодатель и площадка. Мы должны наладить между ними такое взаимодействие, чтобы каждая из них выполняла свои цели. Представьте: вы заходите на сервис ВК, открываете ленту и видите то место, куда мы вставляем рекламу. Есть много рекламодателей, которые претендуют на этот ресурс и хотят, чтобы показали именно их рекламу но как выбрать ту рекламу, которую нужно показать в каждый конкретный момент каждому пользователю?

Стандартный способ, который активно используется в рекламе это онлайн-аукцион. Возможно, вы видели различные варианты аукциона в реальной жизни или на Ebay, например: это может быть ситуация, когда каждый может сделать ставку. Один пользователь говорит я ставлю 10 рублей, приходит другой ставит 20, третий 100, и так далее. Но аукционы рода кто больше заплатил, тот и выиграл непрактично проводить в интернет-среде, поэтому используются аукционы закрытого типа. В таком случае каждый из участников делает ставку молча. Образно говоря, все бумажки со ставками складываются в котел, а потом кто-то приходит, разбирает их, находит бумажку с самым большим числом и говорит ты победил.

Допустим, есть два рекламодателя например, Nike и Coca-Cola. Один из них готов заплатить за каждый показ 5 копеек, а другой 10. Второй выигрывает, и дальнейшее развитие истории зависит от типа аукциона. В рекламе встречается два основных типа: аукцион первой и второй цены. В аукционе первой цены победитель платит ту цену, которую он назвал. Например, Coca-Cola говорит: Я заплачу 10 копеек, не видя ставок других пользователей; аукцион говорит ОК, 10 копеек. Nike говорит: 5 копеек, Coca-Cola выигрывает и платит 10 копеек.

Однако есть еще аукцион второй цены: в этом случае победитель должен заплатить ровно столько денег, сколько нужно, чтобы победить все остальные ставки. В нашем случае может использоваться шаг в 1 копейку, например. Представьте ситуацию: приходят те же Coca-Cola и Nike. Coca-Cola говорит: Я готов заплатить 100 рублей за показ, а Nike говорит: Я готов заплатить 1 копейку. И Coca-Cola будет очень обидно узнать о том, что она могла бы победить, заплатив 2 копейки вместо 100 рублей. Аукцион второй цены считается более честным по отношению ко всем участникам.

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

В аукционе первой цены нужно придумывать хитрую стратегию, думать вот, такие-то рекламодатели могут поставить столько-то, но в аукционах второй цены этого делать не надо. Каждый ставит ту ставку, которую готов заплатить по максимуму. Если ты победил ты платишь ровно столько или меньше; если нет значит, ты не готов был платить больше. Это великолепное свойство такого типа аукционов, которое распространилось из теории на повсеместное использование в рекламных системах.

Однако, не тут-то было. Казалось бы, с точки зрения теории, аукцион второй цены очень хорош, и его свойства позволяют ему быть очень практичным. Но на деле, когда мы сталкиваемся с реальными системами, оказывается, что есть несколько моментов, обеспечивающих популярность аукционов первой цены почему-то люди предпочитают использовать именно их, а не аукционы второй цены. Один из двух главных моментов, про которые хочется сказать это то, что аукцион второй цены непрозрачен. То есть, когда рекламный аукцион устраивает какая-то площадка, о которой вы ничего не знаете вы просто участвуете как рекламодатель она говорит вам, что ваша ставка в (допустим) 10 копеек выиграла, и вы должны заплатить вторую цену пусть это будет 9 копеек. Эта вторая цена непрозрачна; непонятно, откуда она взялась. В целом, площадка может легко обманывать рекламодателя, делая так называемые фейковые ставки. Есть и честные механизмы дополнительных ставок например, reverse price: вы заявляете, что конкретный аукцион нельзя продать дешевле, чем за 9 копеек, и появляется такая честная ставка. Но прозрачность очень важна, и ее отсутствие отталкивает рекламодателей. Когда вы не знаете, что происходит под капотом рекламной системы, снова приходится придумывать какие-то стратегии: нельзя просто брать и использовать подход с установкой только тех цен, которые вы готовы заплатить.

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

Хочется рассказать о моментах, возникающих на фоне задач дизайна аукционов как можно дизайнить их интереснее, полезнее и так далее. Я хочу упомянуть два пункта. Во-первых, в аукционе вроде бы все должно происходить, исходя из максимальной ценности, максимального количества денег, которые заработает рекламная сеть, продавая место; однако на деле ценность, которая продается в аукционе, может для площадки выражаться по-разному не только в сумме, которую готов заплатить рекламодатель. Например, нам очень важно, чтобы пользователей не бесила наша реклама желательно, чтобы она была полезна для них. В рамках задачи дизайна аукциона приходится придумывать дополнительные метрики для ранжирования рекламы. Получается ряд метрик: ожидаемая прибыль, вероятность негативной реакции пользователя и так далее.

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

В ВК мы еще только подбираемся к этой задаче; задач у нас очень много, и еще одна большая часть задач, которые есть в рекламе, уже стоит ближе к ML. Из-за того, что мы должны выполнять различные цели рекламодателей, нам нужно предсказывать, с какой вероятностью пользователь совершит то или иное действие, чтобы использовать это знание в формировании стратегии ставок на аукционе.

То есть, рекламодатель говорит: я хочу как можно больше покупок в моем магазине, потрать мой бюджет максимально хорошо. Мы, как рекламная площадка, думаем, как выделять тех пользователей, которые с высокой вероятностью купят что-то в магазине. Возникает типичная ML-задача. Бинарная классификация: 1 пользователь перешел по рекламе и что-то сделал хорошее (купил), 0 пользователь проигнорировал рекламу. Нам надо, исходя из этой задачи, построить бинарную классификацию, где на выходе мы используем вероятность полезного события как кусочек дальнейших вычислений того, какую ставку мы будем использовать на аукционе. Задача звучит очень банально в терминах ML вроде бы, бери и делай. Но в реальной жизни у такой задачи бывает множество сложностей, и я расскажу о нескольких. Главная из них это то, что реклама обычно является высоконагруженным проектом. Как по данным, так и по нагрузке. Нужно очень быстро отвечать на запрос. Окно, допустим, в 100 миллисекунд и нужно успеть ответить. Исходя из этого, на нас накладываются определенные ограничения конкретно, на то, как инженерно могут работать те модели, которые мы используем для предсказания рекламы. Можно придумать много прикольных штук, сделать сложные нейросети, которые через несколько слоев выделяют нелинейные взаимодействия между фичами, но в жизни требуется, чтобы это все работало очень быстро.

Обучается это на больших объемах данных. Задача получается высокомасштабная, с терабайтными датасетами. Исходя из этого, обычно приходится заниматься такими вещами, как распределенные вычисления, распределенное обучение модели, думать о том, какие модели вообще использовать. В рекламе традиционно используются линейные модели, типа логистических регрессий или градиентного бустинга; иногда переходят на более крутые штуки, вроде factorization machines. То есть, выбор моделей велик, но обычно используются довольно простые из-за большой нагрузки.

Другой, близкий к ML момент: у нас используются данные, которые экстремально несбалансированы по фидбеку. На 10000 нулей приходится одна единица. Как в этих условиях обучать машины ML это хороший вопрос. Приходится использовать разные трюки; основной это именно формулировка задачи: не пытаться предсказывать, будет ли клик (покупка) или нет, например, а использовать подходы, связанные с вероятностями, сглаживать по максимуму данные, у которых низкая кардинальность, и так далее. Многое можно придумать, но сложность в том, что в задаче редко происходят позитивные события.

Когда вы переходите по рекламе и что-то покупаете, вы не всегда делаете это сразу. То есть, очень часто целевые события, которых хотят рекламодатели, происходят с большой задержкой. Это может быть не только покупка например, это может быть регистрация в игре и прокачка персонажа до 10 уровня, или одобрение заявки на кредит. Такие вещи могут происходить через несколько дней. И, когда нам нужно обучать модели, которые, по объявлению, прямо сейчас должны сказать, что пользователь что-то сделает, но, по факту, позитивный фидбек мы получаем только через несколько дней после того, как что-то произошло, и это создает дополнительные проблемы. Чтобы разбираться с этими проблемами, есть несколько разнообразных решений, которые придумали в науке и в практике. Такая забавная сложность.

Еще один момент: когда пользователь видит рекламы определенных продуктов, он может соприкасаться с ними из различных маркетинговых каналов. Например, вы вышли на улицу увидели рекламный щит Такси ВКонтакте; стали листать ленту там тоже реклама Такси ВКонтакте, зашли в другой сервис и там тоже реклама Такси ВКонтакте, от рекламного сервиса Яндекса или Google. Вы говорите да я понял уже, ставите приложение. И после этого Яндексу, ВК, Google, рекламному щиту нужно разобраться, чье участие в этом процессе в полезном для рекламодателя действии составляет сколько процентов.

Этот процесс называется атрибуция вопрос распределения того, какой контакт с рекламодателем настолько сильно повлиял на ваше решение сделать целевое действие. Обычно используются простые модели например, last click attribution: последняя реклама, на которую вы кликнули, получает все призы. Но тогда оказывается, что заниматься первым холодным контактом показом рекламы пользователю, не знакомому с продуктом невыгодно. Исходя из этого, есть много разнообразных моделей ML (в том числе), которые позволяют лучше распределить профит с показов. Там используются, в том числе, фишки типа attention, некоторые более интересные штуки из нейронных сетей. Прикольная задача. И ее цель, по итогу торговаться на аукционе лучше, правильнее, корректнее и так далее.

Чем лучше вы понимаете, кто повлиял на итоговое решение о покупке, тем лучше вы понимаете, сколько в каждый момент поставить. По итогу вся индустрия идет к пониманию того, что работать с предсказанием вероятности того, что вы что-то купите, менее эффективно, чем работать с идеей степени влияния на решение о покупке. Возможно, вы и так уже были готовы купить настольную игру, на сайт которой вы зашли. Но интернет-реклама начинает вас догонять. Может быть, этой рекламы бы и не было, если бы все изначально решили, что вы и так купите эту игру, и дополнительная реклама не нужна вы уже сделали свое решение. Я вспоминаю термин incrementality testing, и все это еще связано с такой областью ML, как causal inference. То есть, мы переходим от задачи предсказания вероятности совершения целевого действия на предсказание влияния то есть, разницы вероятности того, что вы купите, увидев рекламу, минус того, что вы и так уже купили. Это тоже очень прикольный переход, переход на новую идею о том, как работать, как предсказывать какие-то события.

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

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

Теперь я перейду к ML in production. Вот вы прошли курсы по машинному обучению, или проучились в университете. Вы отличный специалист по Kegel, допустим, и офигенно щелкаете задачи по анализу данных на соревнованиях. Вы приходите в реальную компанию, где итеративно, последовательно развивается большой продукт. И здесь происходит некоторый слом. Оказывается, что у вас просто нет многих скиллов, которыми хотелось бы владеть на тот момент, когда вы приходите в индустрию. Вас никто этому не учил и не объяснял, как это работает в реальности; какие в индустрии сложности, как это не похоже на решение задач с четкой формулировкой. Если в области программирования про это еще рассказывают довольно много, то в области data science недостаточно.

С какими трудностями сталкиваются новички в продуктовых командах, которые долгое время работают над одним и тем же продуктом например, делают рекламу в ВК эффективной? Под новичками я имею в виду себя, в том числе; я четыре года этим занимаюсь и до сих пор чувствую себя нубом. Это очень сложная вещь, и в ней интересно разбираться.
Первый момент, про который хочется сказать это желание приступить к имеющейся задаче сразу с каким-то крутым прогрессивным методом, который можно найти в науке; желание придумать космолет, который сразу все сделает классно. В реальной жизни, в области продуктовой разработки, data science это место, где мы очень слабо можем предсказывать, какой метод в итоге сработает. Очень тяжело работать с изначальными продуктовыми требованиями, потому что вы не знаете путь решения проблемы.

У вас есть формулировка задачи: например, сделать систему автоматической модерации, которая должна решать какие-то изначальные проблемы. Можно побежать и найти какую-то супер-топовую статью, в которой задача решается идеально, накрутить трансформеров. А можно сделать простую эвристику, которая будет смотреть на то, сколько раз мы одобряли данного рекламодателя ранее, брать долю этого числа, сравнивать с 70%, например, и говорить: этот часто раньше одобрялся. Такая штука может сразу очень сильно помочь бизнесу, принести полезную информацию. А сложная система делается долго, и не факт, что она окупится. В data science надо очень быстро приходить к такой идее: вы постоянно работаете в режиме гипотез, не знаете, что сработает, и для того, чтобы сокращать риски и как можно быстрее доносить ценность итоговому пользователю и бизнесу, нужно заниматься задачами от простого решения к сложному. Зачастую заниматься, начиная с эвристик, без всякого ML для него может и не быть данных. Это может коробить data scientist-а, которому интересно крутить нейронные модели. Но без этого не получить изначальный baseline шажочек, от которого можно отталкиваться. Можно очень долго заниматься тем, что вообще не сработает.

Самая сложная вещь и необычность работы в индустрии это то, что после того, как вы сделали модель, выкатили ее в production, ее жизнь только начинается. Ее нужно активно поддерживать и менять. С моделью, пока она живет, происходит большое количество разнообразных изменений. Во-первых, есть такая вещь как training serving skew.

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

Во-вторых, в любой момент может какой-то признак, или сама модель, начать работать неправильно, неадекватно. У вас есть хранилище, в котором хранятся признаки; что-то поменялось, вместо нулей начали литься null, вместо -1 стали возвращаться другие значения; или кто-то умножил эти значения на 100, потому что думал, что это проценты, а не доли. И ваша модель резко начинает работать неправильно. Вам нужно эти изменения как-то замечать. Самое прикольное качество ML-модели это молчаливая ошибка; она никогда не скажет, что что-то пошло не по плану она всегда выдаст какой-то результат, в зависимости от того, что вы ей дали. Garbage in, garbage out. За этим надо как-то следить. Исходя из этого, есть гигантское количество моментов, которые нужно отслеживать во время работы модели в production. Нужно выстраивать систему мониторинга, следить, чтобы распределение признаков сильно не менялось, и так далее. Надо понимать, что модель может в любой момент выдать полную дичь, и как-то жить в этих условиях. Что, если эти результаты напрямую снимают деньги с наших пользователей делают ставки на аукционе рекламы, или торгуются на бирже, или еще что-то? Есть большое количество способов того, что с этим делать, но про это в первую очередь важно думать.

Как, исходя из этого, меняется жизнь data scientist-а, который приходит в среду, где надо итеративно развивать модели? Как мне кажется, нужно в первую очередь быть хорошим инженером, а уже во вторую хорошим researcher-ом. Потому что твой код и твои выводы, инсайты, которые ты получаешь в ходе исследования и анализа, твои модели все, что является продуктом твоей работы data scientist-а будет использоваться не 2, и не 10 раз. Много людей будет смотреть на то, как выстроены эксперименты, как получены результаты, почему, где, как что работает, и как это используется в production. Поэтому то, чего по максимуму не хватает в людях, которые приходят в индустрию с нуля например, из университета, увлекшись темой data science, или аналитики, или ML это инженерные скиллы. В первую очередь data scientist это подвид разработчика. Он тоже работает с кодом, он тоже работает с чем-то, что работает потом в production в изменяемой среде, что используют люди. Твой код будут читать. Тебе нужно будет придумывать эффективные, хорошо поддерживаемые и тестируемые решения. Это та часть, которой большому количеству кандидатов не хватает. Поэтому, если вы начинающий человек в data science, уделите большое внимание скиллам разработчика. Тому, как писать эффективный, понятный, хорошо поддерживаемый код; инженерным решениям для того, чтобы эффективно выстраивать процессы обмена данными. Это все вам сильно поможет в карьере.

Второй совет и вторая штука, которая отличает крутых data scientist-ов от тех, которым тяжело работать это погружение в продуктовый контекст и в инженерную часть окружения вашей модели. Допустим, вы разрабатываете модель, и вам, как data scientist-у, легко сказать: Мое дело разрабатывать модель, все остальное за пределами моей ответственности. Я обучаю модельки, это мое дело. Встроит их бэкэндер, подготовит данные дата-инженер, оттестирует тестировщик, продукт-менеджер решит, как применять. Но огромное количество выводов и способов того, как сделать модель круче и ценнее, находится за пределами процесса разработки самой модели. Пример: если вы ранжируете поисковую выдачу, то вы ранжируете документы, поступающие извне; есть какой-то отбор кандидатов. Если вы знаете, как этот отбор работает, то вы можете легко понять, что узкое место в работе это не то, что модель плохо работает, а то, что на вход подаются неправильные, неинтересные, неполные документы. С другой стороны, если вы знаете, что в вашем продукте ваша модель может, при определенных обстоятельствах, работать не так, как хотелось бы, но сделать эту работу лучше очень сложно, то можно поменять продукт под модель. Можно сказать: теперь продукт устроен по-другому, теперь не пользователь вызывает модель, а модель вызывает какой-то автоматический инструмент, который координирует несколько параметров, за которыми пользователь не может следить. Идея в том, что можно менять продукт под модель, а не наоборот. Если вы погружены в эти области, то вы, как data scientist и ML-инженер, можете приносить колоссальную прибыль и пользу вашему продукту и вашим пользователям.

Возвращаясь к вопросу о том, что ML это сфера предположений. Мы никогда не знаем, как конкретно прийти к классно работающему продукту, нам приходится пробовать разные пути к финальному решению. Поэтому нужно немного по-другому выстраивать workflow работы. Зачастую людям, особенно инженерам в начальные периоды развития карьеры, кажется, что всякие менеджерские фишки SCRUM, Agile это все фигня, и они не работают. Хотя зачастую они действительно не работают, потому что используются в неправильном контексте. Например, если вы когда-нибудь попадете в data science-команду, работающую по SCRUM, вам станет тяжело и больно. Внезапно окажется, что рисерч стал тяжело прогнозируемым, и вы не будете знать, как вы придете к результату, а тут двухнедельные итерации, еще что-то, в общем, менеджмент генерирует ненужную фигню. Рабочие процессы, в рамках которых вы работаете, должны помогать вам, а не мешать. То есть, когда в data science берут и прикладывают методы из обычной софтверной разработки, это не всегда получается эффективно.

Поэтому я хочу отдельно сказать: если вы работаете data scientist-ом, и вам приходится взаимодействовать с разными людьми заказчиками, коллегами, кооперироваться по работе то вам хорошо бы озаботиться пониманием того, как лучше выстроить процесс совместной работы, самоорганизованную деятельность команды. Хороший способ понять, как это делать я бы рекомендовал обратиться в сообщество, которое называется LeanDS. Там собрались такие люди, которым интересно понять, как лучше выстраивать процессы работы над ML-задачами в условиях продуктовой разработки. Оттуда можно узнать много прикольных штук, которые люди уже придумали, и разные специалисты используют в разных компаниях. И из того, что я бы посоветовал, в первую очередь надо перейти к подходу, когда вы все задачи формулируете через продуктовые гипотезы. Когда вы не знаете, что принесет результат, но прикидываете: я думаю, что такая-то штука поможет настолько-то продвинуть пользовательские задачи, прокачать метрики, и за такое-то время это можно проверить. С такими гипотезами гораздо проще работать. Исходя из такого непонятного флоу работы, где очень тяжело прогнозировать, сколько времени займет ваша задача, когда вы придете к результату, и каким способом, на мой взгляд, очень хорошо работает Kanban. Я не буду долго про это рассказывать, просто посоветую: попробуйте посмотреть на сообщество LeanDS. Посмотрите их материалы. Я думаю, всем, кто работает в data science и сталкивается с процессами, которые перекочевали из обычной разработки, будет интересно понять, что можно делать по-другому и как использовать процессы в свою пользу.

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

Во-первых, как я уже говорил, инженерные навыки для data scientistа очень важны. Не менее, чем навыки, связанные с ML, анализом данных, теорией вероятности и так далее. В первую очередь желаю вам быть крутым инженером, во вторую рисерчером. Второе: очень многим не хватает четкого скилла переформулирования бизнес-задачи в data science-задачу. Это отдельный скилл. Это ситуация, когда нужно понять, чего конкретно от вас хочет заказчик ну, назовем так человека, который хочет, чтобы что-то круто работало. Возвращаясь к примеру с автомодерацией: чего конкретно он хочет? Ведь задачу автомодерации можно поставить очень по-разному, с разными конкретными вещами, которые мы хотим сделать лучше в нашей системе. Исходя и задачи, по-разному формулируется data science-задача; исходя из data science-задачи, по-разному формулируются оптимизируемые метрики, способ подбора датасета, оценки качества и так далее. Этот скилл очень ценен для всех data scientist-ов. Допустим, заказчик говорит, что у него модераторы не справляются с потоком обработки задач на проверку того, хороша ли реклама или ее нужно забанить с определенной тематикой. Потом вы узнаете, что есть множество разных причин бана, и при модерации надо четко их описывать, чтобы рекламодатель мог исправить рекламу. Исходя из этого, вы решаете, что надо делать какую-то многоклассовую классификацию, которая будет генерировать текст объяснения причины, и задача будет очень сложной. Но подождите может быть, задачу можно переформулировать по-другому. И оказывается, что можно концентрироваться не на том, чтобы отклонять рекламу, а на том, чтобы выбирать нужную рекламу. Если реклама хорошая ее можно просто пропускать, если плохая ее можно отдавать живым модераторам, и никакого объяснения не нужно генерировать. Исходя из этого, вы понимаете: если нужно сконцентрироваться на том, что хорошее, что можно пропускать, то надо понять, как управлять этим делом этим потоком объявлений, который будет проходить через вашу систему. Вы понимаете: ага, исходя из этой задачи, я могу выбрать ROC AUC как подходящую мне метрику, она хорошо описывает зависимость между точностью работы модели и количеством объявлений, которое будет автоматически проходить через нашу систему. И так далее. То есть, исходя из этого диалога условного заказчика и вас, как специалиста, вы можете сильно упростить свою задачу, хорошо понимая, как переформулировать бизнес-задачу в data science-задачу.

Я хотел бы рассказать об еще одной штуке, которая очень помогает. Это понимание того, какие конкретно сигналы передаются в модель, которую вы разрабатываете, в виде признаков, и как она их обрабатывает. Это скилл, который напрямую относится к компетенции команды ML-разработчиков. Почему-то очень многие кандидаты, по моему опыту, исповедуют подход ML все съест положил все в градиентный бустинг, и так сойдет. Я утрирую, но, в целом, очень классно, когда вы четко понимаете, что признак, который вы используете, несет в себе ровно ту информацию, которую вы передали, а не ту информацию, которую вы планировали передать.
Например, вы решили, что хорошим показателем того, что пользователь реагирует на рекламу, будет соотношение кликов и показов. То есть, берем количество увиденной рекламы за все время и количество кликов на рекламу, делим одно на другое и получаем показатель пользователя. В одном случае он говорит, что пользователь любит кликать на рекламу, в другом что он вообще не кликает. И передаем это число в нашу модель градиентный бустинг или линейную регрессию. Потом может возникнуть мысль: у модели же нет способа отличить тех пользователей, по которым у нас много статистики, от тех, кого мало. Единица в показателе может означать не то, что пользователь всегда кликает на рекламу, а то, что у него был всего один показ. Возникает вопрос: как представить эту фичу в таком виде, чтобы модель отличала большое количество статистики от малого? Первое, что приходит в голову положить в модель количество показов объявления. Можно просто положить количество показов, но зависимость нашей уверенности в статистике от количества показов рекламы у пользователя нелинейная. Получается, что нужно класть не просто показы, а квадрат или логарифм показов. Потом оказывается, что, если у нас линейная модель, то эти две фичи никак друг с другом не взаимодействуют. Нельзя будет делать схемы вида если у пользователя такое-то количество статистики, то мы верим ей на столько-то, используем фичу с таким-то весом. Такие связи линейная регрессия не умеет строить, но градиентный бустинг умеет. Или можно переформулировать фичу. Можно вместо сырой статистики сглаживать ее, использовать подходы из байесианских переходов, добавить какое-то априорное знание того, как пользователи кликают в среднем, и с помощью определенной формулы их смешать. И так далее. Получается, что очень важно понимать, какой конкретно сигнал вы передаете в качестве признака.

И второе очень важно знать, как этот признак будет использоваться в модели. В линейной регрессии он будет использоваться по одному, в градиентном бустинге по-другому, а, если это нейронная сеть, то она работает с другим видом данных, и как там работает контекст.
Необязательно знать, как конкретно работает модель, но нужно интуитивное понимание того, что возможно, а что нет. Это классный скилл для ML-специалиста. Если вы спросите меня, как работает какой-нибудь конкретный алгоритм в градиентном бустинге, то мне будет тяжело объяснить в деталях, но на пальцах у меня это получится. И в большинстве практических ситуаций этого достаточно, чтобы эффективно пользоваться инструментом.

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

Я хочу сказать еще может быть, мне помогут; у меня есть два выступления на митапах. Одно посвящено тому, какие data science-задачи можно делать в рекламе (и вообще, почему data science-специалистам рекламные технологии могут быть интересны как плацдарм для применения своих скиллов с интересными инженерными вызовами). А второй рассказ про ловушки, в которые мы попадали как команда ML-разработчиков системы, про то, как мы из них выбирались, и то, как вам не попадать в те же ловушки, в которые попадали мы из-за отсутствия накопленного опыта. Хочется этим опытом поделиться. Я думаю, тут можно много полезных вещей для себя выяснить.

И еще до этого я говорил про сообщество LeanDS, посвященное data science-процессам, управлению проектами data science в ML. Тоже очень советую посмотреть на их материалы, ребята делают очень крутые штуки.

Случалось ли строить полную модель воронки продаж?


На самом деле, нам не случалось этим заниматься. Но здесь очень важно, чтобы внешний рекламодатель все очень хорошо настраивал. Поэтому воронками продаж хорошо заниматься, когда вы data scientist со стороны рекламодателя. Допустим, вы работаете в крупной компании, которая работает с большим количеством маркетинговых каналов, и пытаетесь построить аналитику, которая позволит вам хорошо понять, как конкретно разные маркетинговые каналы работают, как хорошо выстраиваются воронки продаж и так далее. Нам же, со стороны ВК как системы для рекламодателей, при работе с такими штуками очень важно, чтобы у рекламодателя все было хорошо настроено. Чтобы рекламные пиксели всегда отдавали правильную информацию о том, как пользователь зашел на сайт, добавил что-то в корзину и купил. И дальше мы должны использовать эту информацию для того, чтобы делать рекламные стратегии лучше и эффективнее. Хочется этим позаниматься; мы практически этим не занимались, потому что настройка таких систем зачастую тяжело дается для рекламодателя. Наверно, проще заниматься этим, когда есть полный контроль.

И такой вопрос: как связать сущности (задать признаки) при построении модели?


Например, посетитель сайта -> клиент

Наверно, хорошо просто исходить из какой-то предыдущей активности пользователя. В целом, это делается разными способами; я могу рассказать про один, который используется при построении рекламных систем, называется он look-alike. Возможно, вы про него слышали. Это ситуация, когда мы говорим: вот пользователи, которые посетили наш сайт, и вот те, которые что-то купили. Давайте посмотрим на то, какие пользователи наиболее похожи на тех, которые что-то купили, и меньше похожи на тех, кто ничего не сделал. Когда мы обучаем такую модель, где 1 это те, кто купил, 0 те, что ничего не сделал, а условно 0.5 это те, кто зашли на сайт, мы можем научиться ранжировать всех пользователей нашей системы по похожести на потенциального клиента. Мы можем использовать это знание в нашей модели и рассказывать клиенту о том, какие признаки, с точки зрения модели, отделяют клиентов от простых посетителей.

Подробнее..

Как написать простого бота для ВК и Телеграм

23.02.2021 18:07:11 | Автор: admin


Мы уже упоминали, как мы предоставляем бесплатные для студентов, чтобы они учились программировать. Один из наших подопечных Павел сделал простеньких телеграм и ВК ботов для FAQ. Они очень просте, тем не менее, начинающему программисту не помешают комментарии опытных ребят поэтому публикуем его рассказ Павел будет рад, если в комментариях ему дадут советы.

Я студент Новосибирского Государственного Технического Университета, не так давно мы с парочкой моих друзей реализовали во всех возможных областях научной деятельности. Мы помогаем сводить заинтересованных преподавателей и студентов всех ВУЗов Сибири, чтобы проектная научная деятельность развивалась по территории Сибири и РФ.

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

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

Я использовать Python версии 3.6 просто потому, что он самый простой для меня. Кодил в PyCharm Community Edition. Весь код опубликован на. Удачи!

1. Предварительные приготовления для телеграм-бота


1.1 Получение токена от Bot Father в телеграмме


Первым делом, нам нужно зарегистрировать нашего бота в Telegram.

Для этого, в поисковике телеги ищем BotFather

далее, делаем всё также, как показано на скриншотах:



После нажимаем на команду /newbot или же прописываем вручную.



Надо придумать уникальное имя для бота, придумываем и получаем соответствующий токен.



1.2 Переходим в любой редактор кода и создаем файл


Перед созданием данного файла, нам нужно выбрать директорию, в котором будет реализован весь функционал бота. Если вы используете PyCharm Community/Professional Edition, то предлагаю просто создать новый проект, и писать там весь функционал бота.

Если Вы используете любой другой редактор, такой как Sublime Text 3, например, то Вам самостоятельно придётся создать директорию, создать виртуальное окружение, и работать из консоли со всеми предварительными тестами. Во избежание трудностей, предлагаю скачать продукт PyCharm Community Edition от компании JetBrains, с помощью данного продукта можно обойти действия, описанные в предыдущем абзаце, так как данный продукт сделает их самостоятельно, от Вас потребуется только указать путь до интерпритатора Python в конфигурациях PyCharm, с помощью которого и будет работать Ваш бот.

В данном файле () будет храниться только токен, который нам дал BotFather, поэтому пишем:

token = "Здесь хранится Ваш токен".

1.3 Cоздаём главный файл


Делаем cледующие импорты и для соответствующих библиотек, в консоли прописываем закоментированные строчки:

import configimport telebot # pip install telebotfrom telebot import types # pip install pyTelegramBotAPI

Далее, нам необходимо использовать наш токен:

bot = telebot.TeleBot(config.token)

Этим действиям мы устанавливаем то, что мы будем накручивать функционал именно для того бота, для которого нам и дал токен BotFather.

2. Разворачиваем функционал


Начнём с того, что для того, чтобы пользователю запустить бота, нам необходимо прописать команды для старта они могут быть разными, например, /start или /go и вообще любыми, какими Вы сочтёте нужными.

Для обработки команд нам потребуется message_handler, с помощью которого и будет реализован весь функционал обработки команд для старта и завершения, если Вы сочтёте нужным добавить завершение. Как только придёт команда /go или /start, message_handler с соответствующими командами сравнит, совпадают ли строки и если совпадают, то обработает соответствующей функцией.

Каждая функция, как и в примере сейчас, должна принимать один параметр сообщение от пользователя, которое будет обработано соответствующей функции в обёртке декоратора. А также, каждая функция (или связка функций) должна возвращать соответсвующее сообщение от бота.

Итак:

@bot.message_handler(commands=['go', 'start']) # Обработка команды для стартаdef welcome(message):sti = open(path+'stiker.tgs', 'rb')bot.send_sticker(message.chat.id, sti)markup = types.ReplyKeyboardMarkup(resize_keyboard=True)item3 = types.KeyboardButton("Приложения")item2 = types.KeyboardButton("Мероприятия")item1 = types.KeyboardButton('О нас')markup.add(item1, item2, item3)bot.send_message(message.chat.id,"Добро пожаловать, {0.first_name}!\\n\\nЯ - <b>{1.first_name}</b>, бот команды Projector в НГТУ, ""создан для того, ""чтобы помочь Вам влиться в нашу команду,""просто узнать что-то о нас или же просто пообщаться и весело провести время.\\n\\n""<i>Have a nice time</i>".format(message.from_user, bot.get_me()),parse_mode='html', reply_markup=markup)

В этой функции реализовано сразу два действия: отправка приветственного сообщения и создание встроенной клавиатуры ReplyKeyboardMarkup, которая будет открыта, пока мы не завершим выполнения бота соответсвующей командой. Об этом будет сказано ниже.

Итак, пройдёмся по строчкам:

В строках 20-21: открывается стикер по тому пути к директории, в которой я его сохранил, после чего отправляется.

Строки 22-28: создаем встроенную клавиатуру, добавляя туда три элемента.

Строки 30-37: описано создание и отправка приветственного сообщения

Как вы можете заметить, метод send_message в строке 30, позволяет использовать HTML, для форматирования текста.

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

# RUNif __name__ == "__main__":try:bot.polling(none_stop=True)except ConnectionError as e:print('Ошибка соединения: ', e)except Exception as r:print("Непридвиденная ошибка: ", r)finally:print("Здесь всё закончилось")

Сделаем первый запуск! Для этого, в PyCharm-е нажмём зеленую кнопку старт в правом верхнем углу или же, можно запустить из консоли командой: python



Результат первого запуска:



2.1 Обработка нажатия на кнопки и создание inline keyboard


Так любое сообщение это текст, то мы будем обрабатывать именно текстовые сообщения.

Сделаем следующее и аналогично разберём по строчкам:

@bot.message_handler(content_types=["text"])def go_send_messages(message):if message.chat.type == 'private':if message.text == 'Приложения':keyboard = types.InlineKeyboardMarkup(row_width=1)itemboo = types.InlineKeyboardButton(text="Тыщ на кнопку и ты уже в Google", url="<https://www.google.ru>")itemboo1 = types.InlineKeyboardButton('Рандомное число', callback_data='good2')itemboo2 = types.InlineKeyboardButton("Калькулятор", callback_data='bad2')itemboo3 = types.InlineKeyboardButton("Хочу узнать погоду в моем городе/стране", callback_data='good3')itemboo4 = types.InlineKeyboardButton("Как твои дела?", callback_data='bad4')keyboard.add(itemboo, itemboo1, itemboo2, itemboo3, itemboo4)bot.send_message(message.chat.id,"{0.first_name}, окей, смотри, что у нас есть тут:\\n".format(message.from_user),reply_markup=keyboard)elif message.text == "Мероприятия":one_markup = types.InlineKeyboardMarkup(row_width=1)ite1 = types.InlineKeyboardButton("Ближайшие мероприятия", callback_data="one")ite2 = types.InlineKeyboardButton("Проведенные мероприятия", callback_data="two")ite3 = types.InlineKeyboardButton("Волонтерство на мероприятие", callback_data="three")ite4 = types.InlineKeyboardButton("Действующие проекты в НГТУ", callback_data="fourth")ite5 = types.InlineKeyboardButton("Мероприятия Межвузовского центра", callback_data="five")one_markup.add(ite1, ite2, ite3, ite4, ite5)bot.send_message(message.chat.id, "{0.first_name}, у нас <u>ежемесячно</u> проводится множество ""мероприятий,\\nмы постарались разбить их на следующие составляющие:".format(message.from_user), parse_mode="html", reply_markup=one_markup)

Строка 339 обработчик любых текстовых сообщений

Строка 341 предназначена для того, чтобы сказать, что если данное сообщение предназначено боту, то сравни эту строку с теми, что здесь обрабатываются и отправь ответ.

Строки 344 351 создаём инлайновую клавиатуру InlineKeyboardMarkup и помещаем в эту клавиатуру 5 элементов, которые также можно будет обработать по установленной callback_data. Элементы данной клавиатуры будут расположены друг под другом, так как в строке 344, мы установили row_width = 1, что обозначает самую широкую грань одной кнопки, поэтому они и будут расположены друг под другом.

Строки 353-355 отправляют текст, вместе с нашей Inline Keyboard.

В условиях ниже представлены аналогичные представления обработки сообщений.

Итак, сделаем запуск:

2.2 Обработка InlineKeyboardButton


Как было сказано выше, каждый элемент InlineKeyboardButton имеет параметр callback_data, и именно по этим параметрам будет обрабатываться каждая кнопка. Для этого нам потребуется обработчик инлайновой клавиатуры callback_query_handler.

@bot.callback_query_handler(func=lambda call: call.data in ['one', 'two', 'three', 'fourth', 'five']) # Мероприятияdef callback_inline_one(call):try:if call.message:if call.data == 'one': # Ближайшие мероприятияbot.send_message(call.message.chat.id,"Итак,<b>ближайшие мероприятия</b>:\\n\\n" # Здесь будут ссылки ещё"Форум Байкал\\n""Конкурс Цифровой ветер\\n""PRONETI", parse_mode="html")elif call.data == 'two': # Проведённые мероприятияbot.send_message(call.message.chat.id, "Вот список <b>проведённых мероприятий</b>:\\n\\n""МНТК\\n""Семинары по проектной деятельности\\n""Встреча с представителями предприятий", parse_mode="html")elif call.data == 'three':

Итак, разберём по строчно:

Строка 269 объявляем обработчик, который будет обрабатывать каждую из нажатых кнопок с использованием лямбда-функции

Строки 273-278 В данном блоке if, мы просто обрабатываем сообщение и отправляем сообщение пользователю.

Строки 279-283 Делают аналогичное действие, что и в предыдущем условном блоке.

и т. д.

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

Результат:



Так просто и обрабатываются inline keyboards.

3. Завершаем работу бота


Данная функция будет аналогичной функции обработки команд для старта бота, поэтому Вы сможете легко понять её функционал:

@bot.message_handler(commands=['stop']) # Обработка команды для выходаdef bye(message):bye_Sti = open(path+'byeMorty.tgs', 'rb')hideBoard = types.ReplyKeyboardRemove()bot.send_message(message.chat.id,"Досвидания, {0.first_name}!\\nМы, команда <b>{1.first_name}</b>, надеемся, что ты хорошо провел(а) время \\n\\n""Присоединяйся к нашей команде в <a href='<https://vk.com/projector_neti>'>vk</a>\\n""Наш <a href='<https://instagram.com/projector_neti>'>inst</a>\\n\\n""Напиши Координатору проектов (<a href='<https://vk.com/nikyats>'>Никите Яцию</a>) и задай интересующие тебя вопросы по <i>проектной деятельности</i>\\n\\n""Надеемся, что тебе ответят очень скоро \\n\\n""<u>Don't be ill and have a nice day</u> \\n\\n\\n""P.S.: Если есть какие-то пожелания или вопросы по боту, то напиши <a href='<https://vk.com/setmyaddresspls>'>мне</a>".format(message.from_user, bot.get_me()), parse_mode='html', reply_markup=hideBoard)exit()

Здесь происходит следующее:

  1. Отправляется прощальный стикер.

  2. Закрывается встроенная клавиатура (строка 44).

  3. Отправляется прощальное сообщение.


Так как мы используем bot.polling, с параметром none_stop = True, то пользователь может снова вознообновить общение с ботом при помощи команды /start или /go, обработка которых показано в пункте выше.

Результат:



ВК БОТ

Перейдём к реализации бота Вконтакте, написанном на том же родном языке Python, его основное отличие от предыдущего в том, что он был написан с использованием ООП, а именно класса. Внешне, он выполняет ту же миссию. Сама библиотека для написания вк бота намного проще телеграмм бота, поэтому разобраться в ней самостоятельно не составит большого труда. Итак, начнём.

1. Предварительные подготавления


Установим следующие библиотеки по тем же технологиям:

import vk_api # pip install vk-apiimport json  # pip install jsonfrom vk_api.longpoll import VkLongPoll, VkEventType

1.1 Получение токена для сообщества Вконтакте.


  1. На главной странице сообщества найти раздел Управление
  2. Работа с API
  3. Создать ключ. Выбираете нужные для вас пункты, которые будут доступны боту.

В итоге должно получиться примерно следующее:

Берем ключ и переходим в среду разработки и делаем следующее:

vk = vk_api.VkApi(token="Ваш_токен")

Далее следующее:

longpoll = VkLongPoll(vk)

На этом, закончим подготавления.

2. Разворачиваем функционал


Первым делом создадим файл

Cоздадим прототип встроенной клавиатуры ( всё с помощью документации VkBotAPI ).

main_keyboard = {"one_time": False,"buttons": [[{"action": {"type": "text","payload": "{\\"button\\": \\"1\\"}","label": "О нас"},"color": "positive"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"2\\"}","label": "Мероприятия"},"color": "positive"},{"action": {"type": "text","payload": "{\\"button\\": \\"3\\"}","label": "Приложения"},"color": "positive"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"4\\"}","label": "Контакты"},"color": "primary"}]]}

Затем переводим её в формат json, как требуется в документации:

main_keyboard = json.dumps(main_keyboard, ensure_ascii=False).encode('utf-8')main_keyboard = str(main_keyboard.decode('utf-8'))

Пример инлайн клавиатуры:

about_us_keyboard = {"inline": True,"buttons": [[{"action": {"type": "text","payload": "{\\"button\\": \\"1\\"}","label": "Основная информация"},"color": "positive"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"2\\"}","label": "Чем мы занимаемся ?"},"color": "primary"},{"action": {"type": "text","payload": "{\\"button\\": \\"3\\"}","label": "Где мы находимся ?",},"color": "positive"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"4\\"}","label": "Как попасть в команду ?",},"color": "primary"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"5\\"}","label": "Контакты",},"color": "secondary"}],[{"action": {"type": "text","payload": "{\\"button\\": \\"6\\"}","label": "Задать вопрос руководителю проекта",},"color": "negative"}]],}

Не забываем все используемые клавиатуры переводить в формат json:

about_us_keyboard = json.dumps(about_us_keyboard, ensure_ascii=False).encode('utf-8')about_us_keyboard = str(about_us_keyboard.decode('utf-8'))

Создадим функцию write_msg, для того, чтобы не мучиться с постоянной отправкой сообщений от бота:

def write_msg(user_id, message, key):vk.method('messages.send',{'user_id': user_id,'message': message,'keyboard': key,'random_id': random.randint(0, 2048)})

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

2.1 Основной функционал (создаем файл vk_bot.py)


Мы не будем разрабатывать методы, которые будут выполнять, например, функцию парсинга времени или погоды, назовем их второстепенными. Я покажу лишь основной метод, который будет обращаться к этим второстепенным методам, для обработки тех или иных сообщений от пользователя. В конце статьи я выложу ссылку на свой GitHub, где Вы сможете самостоятельно просмотреть интересующий Вас функционал любого из метода. Итак:

Конструктор класса:

class VkBot:def __init__(self, user_id):self.USER_ID = user_idself._USERNAME = self._get_user_name_from_vk_id(user_id)self.my_str = ""self._COMMANDS = ["привет", "погода", "время", "пока"]self._inputMes = {"основная информация": answers.about_us1,"чем мы занимаемся ?": answers.about_us2,"где мы находимся ?": answers.about_us3,"ближайшие мероприятия": answers.events1,"проведённые мероприятия": answers.events2,"волонтёрство на мероприятие": answers.events3,"действующие проекты в нгту": answers.events4,"мероприятия межвузовского центра": answers.events5}

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

(Пример кода из файла)

events1 = "Итак,ближайшие мероприятия:\\n\\n" \\"Форум Байкал\\n"\\"Конкурс Цифровой ветер\\n"\\"PRONETI"events2 = "Вот список проведенных мероприятий:\\n"\\"МНТК\\n"\\"Семинары по проектной деятельности\\n"\\"Встреча с представителями предприятий\\n"\\events3 = "По поводу этого критерия напиши Илье (<https://vk.com/ki1337ki>)\\n"\\"А также, ты можешь заполнить анкету, благодаря которой,\\n"\\"с тобой лично свяжется один из руководителей направления\\n"\\"или координатор проекта (<https://vk.com/nikyats>)"

Итак, основной метод класса это new_message, который принимает один параметр message, который обрабатывается соответствующим условным блоком и возвращает какое -то значение обратно туда, откуда был вызван.

def _get_user_name_from_vk_id(self, user_id):request = requests.get("<https://vk.com/id>" + str(user_id))bs = bs4.BeautifulSoup(request.text, "html.parser")user_name = self._clean_all_tag_from_str(bs.findAll("title")[0])return user_name.split()[0]def new_message(self, message):# self.my_str = " ".join(re.findall('[0-9]{2}', message))if message.lower() == self._COMMANDS[0]:return f"Привет, {self._USERNAME}!"elif message.lower() == self._COMMANDS[1] or message.lower() == "узнать погоду ":return self._get_weather()elif message.lower() == self._COMMANDS[2] or message.lower() == "узнать точное время ":return self._get_time()elif message.lower() == self._COMMANDS[3]:return f"До скорой встречи, {self._USERNAME}!"else:for key, value in self._inputMes.items():if message.lower() == key:return valuereturn "Не понимаю тебя "

3. Возвращаемся в и дописываем функционал


Теперь в первых строках нам необходимо проимпортить файл vk_bot. А также нам потребуется библиотека random.

import random # pip install randomfrom vk_bot import VkBot

После того, как мы объявили longpoll, дописываем основной функционал.

longpoll = VkLongPoll(vk)try:for event in longpoll.listen():if event.type == VkEventType.MESSAGE_NEW:if event.to_me:bot = VkBot(event.user_id)if event.text.lower() == "о нас":write_msg(event.user_id, "Немного о нашем проекте", about_us_keyboard)elif event.text.lower() == "мероприятия":write_msg(event.user_id, "Что ты хочешь узнать?", events_keyboard)elif event.text.lower() == "приложения":write_msg(event.user_id, "Посмотри, что есть здесь!", app_keyboard)elif event.text.lower() == "контакты":write_msg(event.user_id, "По любым вопросам можешь обращаться к:", contacts_keyboard)elif event.text.lower() == "задать вопрос руководителю проекта":write_msg(event.user_id, "У тебя есть возможность написать сообщение нашему Руководителю проекта",go_answer)elif event.text.lower() == "калькулятор":write_msg(event.user_id, "В разработке...", calc_keyboard)# elif event.text == " ".join(re.findall('\\d{2}', event.text)):#   write_msg(event.user_id, "Отлично, мы здесь", calc_keyboard)elif event.text.lower() == "как попасть в команду ?":write_msg(event.user_id, "Напиши координатору проекта - Никите\\n""или перейди на сайт проектной деятельности,\\n""найди проект номер 612 и подай заявку", in_team)else:write_msg(event.user_id, bot.new_message(event.text), main_keyboard)except Exception as e:print(e)

Как можете заметить, в условных блоках if и elif присутствует обработка тех сообщений, которые подразумевают под собой вывод инлайн или встроенной клавиатуры (в данном примере выводятся только инлайн клавиатуры). Сюда также можно добавить более сложные обработки сообщений, после которых обработка будет метаться туда сюда по блокам if и elif. Таким образом бот будет работать, пока не упадёт с ошибкой.

Другое дело обстоит с блоком else, здесь мы обращаемся как раз ко классу нашего Бота, после чего он аналогичным способом находит обработку сообщения и выводит результат. Это можно назвать вложенной обработкой, а так как вложенностей лучше избегать, то лучше использовать тот метод программирования бота, который как раз-таки реализован в телеграмм боте.

Заключение


Надеюсь, что после прочтения данной статьи, Вы как минимум поняли основной принцип создания своего Telegram или Vk бота, а как максимум легко сможете написать своего бота.

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

Весь код опубликован в моём профиле GitHub:


Подробнее..

Контент ВКонтакте не заслуживает ВКонтакте

12.03.2021 10:04:49 | Автор: admin

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

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

После часа настройки newsboat я осознал, что основной функционал RSS-ридеров уже несколько лет имеется в ВК, но отсутствует стимул его использовать.

Было лучше

Говорят, что раньше интернет был другим, и я могу с этим согласиться. Мои первые воспоминания об интернете - помегабайтные карточки доступа, IE как доминирующий на рынке браузер и Rambler в качестве поисковика по умолчанию.

Мои первые воспоминания о ВК - flash-игры, эндпоинты, оканчивающиеся на .php, золотые полоски под аватарками, однострочные JS-скрипты для получения бесплатных голосов, и ссылка на профиль загрузившего трек на странице поиска аудио. Для меня много лет интернетом в его романтическом смысле был именно ВК, где можно было находить интересных людей, следить за их творчеством или просто же предаваться бесконечному блужданию в поисках нового.

Как следствие продолжающейся монополизации интернета горсткой частных компаний, общественное мнение о соцсетях сместилось в негативную сторону, но по-прежнему большинство продолжает ими пользоваться, и я не могу их (себя) в чем-то винить. Если игнорировать аддиктивные аспекты, то это вполне удобные инструменты для общения, создания и просмотра контента. И всего того, что еще сегодня предлагают суперсервисы.

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

Было бы странно, если рекламный бизнес позволит пользователям не смотреть бесконечно на рекламу каждые N постов, и одновременно даст возможность не раскрывать часть информации о своих интересах...

Да и сейчас неплохо: RSS-like ленты прямо в ВК

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

Во вкладку можно добавить любые сообщества или людей, на которых подписан пользователь, и затем их посты будут появляться в этой вкладке. Важное отличие от обычной ленты помимо выбора источников - ограничение показа по давности публикации (около 2 недель). Не хватает маркировки "прочитано", но совершенно ясно, почему ее нет.

Убираем единицы из вектора пользователя

Если отписаться от сообщества после того, как оно было добавлено во вкладку, его отображаемость во вкладке не изменится.

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

Точечное управление контентом

Закладки предельно просты - помечаешь что-то как важное, и затем оно отображается в списке важного. Метки - способ дальнейшей классификации закладок по отдельным категориям.

По списку всего, что можно пометить важным, достаточно четко вырисовывается картина ВК как замкнутого в себе интернета. У некоторых это вызовет чувство тревоги, а на Хабре можно выразить восхищение инженерами, построившими эти сервисы.

Альтернативой закладкам могут быть непосредственные уведомления об обновлениях. Интересно, что их можно включить, даже не подписавшись и не добавив в закладки автора. В таком виде эта фича больше подходит для сталкинга, либо для чего-то важного, но не интересующего на постоянной основе.

И напоследок, при нажатии на "Записи сообщества" (только в веб-версии) можно получить нумерованный список всех публикаций и относительно быстро переместиться в заданный временной отрезок.

Cтимулы

Я никогда не занимался ведением сообщества ВК в целях заработка, и у меня нет статистики изменения заработков администраторов с приходом единой площадки размещения рекламы в сообществах. Зато однажды я наткнулся на сообщество таких администраторов, общающихся на насущные темы в свободной форме. Немного просмотрев его, несложно сделать вывод о том, что монетизация сообществ как минимум несовершенна.

Сообщества прекращают быть активными, в основном, из-за утраты интереса авторов. Причины этому могут быть разные - неудовлетворенность обратной связью, взросление, или страйк за неоригинальный контент. Чтобы оставаться привлекательным для рекламодателей и пробиваться через эвристики алгоритмических лент, авторам приходиться соответствовать целому ряду требований "нормального" контента, что не может не сказаться на его качестве, а иногда и на форме представления.

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


Но ведь нет ничего плохого, чтобы написать конвертацию каналов Телеграма в RSS ленты, там все стабильно.

Подробнее..

VKWave фреймворк для разработки ботов ВКонтакте

16.08.2020 16:17:46 | Автор: admin


Привет, Хабр!


Сегодня я хочу рассказать о замечательной библиотеке для разработке ботов ВКонтакте с помощью языка программирования Python.


VKWave


VKWave это фреймворк для разработки ботов ВКонтакте, написанный с помощью asyncio. Основные цели проекта дать возможность разработчику конфигурировать фреймворк максимально под себя, в тоже время обеспечивая достойную скорость разработки.


Минимальная требуемая версия Python 3.7


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


Также у нас есть чат в Telegram


Установка


Установка очень проста и содержит в себе всего одну команду:


pip install vkwave

А теперь предлагаю перейти к примерам!


Echo-бот


Самая простая задача. Бот который отвечает нам тем же самым текстом, который мы ему написали.


# Импортируем нужные классы.# SimpleLongPollBot: обёртка для более удобной работы с фреймворком# SimpleBotEvent: тип события, который предоставляет SimpleLongPollBotfrom vkwave.bots import SimpleLongPollBot, SimpleBotEvent# инициализируем бота (можно ввести список токенов, тогда vkwave сможет обходить лимиты ВКонтакте)bot = SimpleLongPollBot(tokens=TOKEN, group_id=GROUP_ID)# декоратор для создания обработчиков.# можно передавать свои фильтры, но в данном случае мы хотим принимать все сообщения@bot.message_handler()def echo(event: SimpleBotEvent) -> str:    # мы можем сразу возвращать текст, т.к vkwave понимает, что если вы возвращаете строку, то вы хотите ответить на сообщение этим текстом. пользователь может задать свои типы данных, которые он сможет возвращать из хендлеров (а также написать нужную логику для их преобразования в нужные действия)    return event.object.object.message.text# запускаем бота с игнорированием ошибок (не останавливаться даже при них)bot.run_forever()

Код содержит буквально пару строк и выглядит очень легко.


Предлагаю написать что-нибудь поинтереснее. Давайте напишем такого же бота, но он будет печатать в ответ только тот текст, который идёт как аргументы команды /echo. Например /echo мой текст.


Вторая версия Echo-бота


# мы используем фильтр для команд. он фильтрует все сообщения которые не выглядит как `/<наша команда>`. можно задать свои префиксы, а также передать список команд@bot.message_handler(bot.command_filter("echo"))def echo(event: SimpleBotEvent) -> str:    # получаем все аргуметы команды    args = event.object.object.message.text.split()    # проверяем, что есть хотя бы один аргумент    # в противном случае - пишем, что пользователь должен ввести какой-нибудь текст    if len(args) < 2:        return "Напиши какой-нибудь текст!"    # возвращаем итоговый текст (соединяем все аргументы через пробел)    return " ".join(args[1:])

Уже интереснее. Как мы видим, VKWave предоставляет нам фильтр для команд. Скажу сразу: стандартных фильтров в VKWave много, а также вы можете написать свои.


Итоговая версия Echo-бота


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


# Импортируем нужные классы для разработки своих фильтровfrom vkwave.bots.core.dispatching.filters.base import BaseFilter, BaseEvent, FilterResult# объявляем свой фильтр, который наследуется от базовогоclass EchoFilter(BaseFilter):    # мы можем определить `__init__` для дополнительной настройки фильтра    # объявляем асинхронный метод `check`, который принимает событие и возвращает результат фильтра    async def check(self, event: BaseEvent) -> FilterResult:        # делаем алиас для текста сообщения        text = event.object.object.message.text        # разбиваем сообщение по пробелам        all_args = text.split()        # если частей меньше двух - фильтр не прошёл        if len(all_args) < 2:            # возвращаем False.            # так же можем, например, что-то написать пользователю            # у нас есть `event.api_ctx`, который предоставляет лёгкий доступ ко всем методам            return FilterResult(False)        # если нулевой аргумент (сама команда) не "/echo" возвращаем False        if all_args[0] != "/echo":            return FilterResult(False)        # передаём обработчику уже готовый ответ на сообщение        event["echo_answer"] = " ".join(all_args[1:])        return FilterResult(True)# используем фильтр@bot.message_handler(EchoFilter())def echo(event: SimpleBotEvent) -> str:    # возвращаем текст, который мы уже "собрали" в фильтре    return event["echo_answer"]

Заключение


Конечно, я показал вам не все, вообще не все, возможности VKWave. Они очень широки, начиная от возможности своих фильтров и middlewares, типов обработчиков, способов получения событий, заканчивая мультиботом, собственным HTTP клиентом и многое другое!


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


Репозиторий на GitHub
Наш чат в Telegram

Подробнее..

Ещё один поиск Вк по фото

20.03.2021 16:14:02 | Автор: admin

Я люблю ввязываться в авантюры, и за последний месяц об одной из них я пару раз рассказывал друзьям, что вызывало восторг, поэтому решил поделиться с хабравчанами! Эта история про отважные пет-проекты, мощь опен-сорса и саморазвитие, а также основные технические детали. Надеюсь, вас это вдохновит :)

1. Предыстория

В первой половине 2016-го в свет вышел нашумевший FindFace, позволяющий загрузить фото человеческого лица и находить соответствующий профиль Вк. Он вызвал большой общественный резонанс, привёл как к поиску девушек по скрытым фоткам на эскалаторах в метро и к обнародованию порноактрис с неприятными последствиями для их близких, так и к находкам потерянных близких, к нереально быстрому поиску преступников по случайным кадрам с камер, прям как в американских фильмах, только наяву.

В то время мне об этом сервисе говорили и ленты новостей, и друзья, я отвечал "ну да, прикольно", и только. Но спустя пару лет, в начале октябре 2018 на каком-то айтишном форуме я захотел связаться с одним пользователем по специфическому вопросу, вот только он туда уже давно не заходил. Зато там было его хорошее фото, и тут-то я вспомнил про крутой сервис! Побежал на их сайт и разочаровался в сентябре 2018, буквально за месяц, они перестали предоставлять свои услуги физ.лицам, и бесплатно, и даже за деньги, перейдя в сегмент b2b и b2g. Оно и понятно, пиар уже сработал, а этических вопросов так возникает куда меньше. Но меня, законопослушного гражданина, это огорчило. И не только меня: фан-группы ФайндФейса пестрили сообщениями о том, что люди готовы заплатить в 10 раз больше, лишь бы им помогли найти нужного человека.

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

Пару рабочих дней я размышлял, что же сложного в создании такого сервиса, который бы и точно искал людей, и по всему Вк? Решил, что ничего, ведь у меня тогда уже были базовые познания в data science, разработке и администрировании. Поэтому в пятницу, приехав с работы домой, я взялся за дело. За вечер я накидал скрипт, который парсит профили Вк, находит фото, индексирует по ним лица и сохраняет в БД. Потом просидел ещё пару суток почти без сна, заставил это дело безостановочно работать на своём сервере. Началась новая трудовая неделя, я был очень уставший, но ещё больше довольный и полный энтузиазма! Ведь мой скрипт медленно, но безостановочно бежал по всему Вк.

2. Техническое устройство

2.1. Индексирование

Как вы считаете, что происходит после того, как вы отправляете запрос в любую крупную поисковую систему? Не важно, поиск текста в Яндексе, Google или поиск лиц в FindFace или моём сервисе. Многие, особенно не-айтишники, с трудном представляют внутренние механики технических процессов, а они бывают нетривиальны даже казалось бы в простых задачах. В случае поисковых систем магия заключается в том, что при получении запроса они не начинают обегать все страницы в интернете, ища там ваш текст, или весь Вк, сравнивая вашу фотку со всеми подряд, это бы занимало астрономические объёмы времени. Вместо этого, поисковые системы сперва индексируют нужные данные. В случае текста (и подобных тексту данных вроде ДНК) в ближайшем приближении могут использоваться хэш-таблицы или префиксные деревья. В случае фоток тоже нужны индексы, которые сильно сократят время поиска. Для этого я использовал библиотеку face_recognition, которая позволяет преобразовать фото лица, если правильно помню, в 128-мерный вектор признаков со значениями от -1 до 1 (далее буду называть его просто хэш). Для поиска человека по фото, нам нужно просто пробежаться по всем фото из коллекции, считая евклидово расстояние между векторами-хэшами из запроса и набора подобный пример, реализованный на Питоне, доступен на сайте упомянутой библиотеки. Да, такая операция поиска тоже не дешёвая, но об этом позже.

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

Конечно, не только лимиты АПИ повышать надо, но и объёмы CPU. Изначально я развернул скрипт на маленьком VPS, который создавался для простого личного сайта. В подмогу ему, я взял ещё один VPS, в несколько раз мощнее. Потом я решил, что и этого мало, взял ещё и целый выделенный сервер, который сильнее моего собственного рабочего компьютера :D Не энтерпрайз-левел, но производительность стала меня устраивать, хотя расходы и выросли до 15 тысяч руб/месяц, что для меня тогда было весьма ощутимой тратой.

2.2. Подобие архитектуры и DevOps'а

Если у вас есть опыт в бэкэнд разработке, то сразу встаёт вопрос, как я заставил несколько серверов работать в тандеме, а не независимо, дублируя одну и ту же работу? На самом деле, решение классическое: один микросервис брал на себя роль ведущего, мастера, хранил состояние всей системы, и выдавал задания объёмом в тысячу профилей Вк воркерам, которые быстрее или медленнее их индексировали, а результаты, в том числе промежуточные, возвращали мастеру; если же мастер за определённый промежуток времени не получал ответа от воркера, он давал это задание другому, с учётом промежуточного прогресса.

Кстати, воркеры работали в несколько потоков. Да, Питон, благодаря Global Interpreter Lock, не умеет в полный параллелизм, но много времени уходило на выгрузку фоток, а IO-операции хорошо параллелятся. Вдобавок, это позволило легко назначить каждому потоку свой токен доступа и гибко настраивать загруженность каждой машины.

Для автоматизации настройки окружения, токенов и т.п были написаны скрипты на Питоне, которые подключались к целевой машине по SSH и ставили всё что нужно. Позже я узнал, что у меня костыльный велосипед, есть качественные решения, но всё равно было интересно посмотреть подноготные детали. Из прикольного, пришлось также разобраться, что есть разные ВМ и средства виртуализации, что некоторое ПО не работает в определённых конфигурациях, благодаря чему виртуалки на Xen и OpenVZ с казалось бы одинаковыми ресурсами могут отличаться в цене на 40%.

2.3. Поиск

Помимо ролей мастера и воркера, есть роль поискового микросервиса. Проиндексированные фото Вк и айдишники их профилей сохраняются в БД, точнее, MySQL v5.7 и алгоритм поиска я переписал с Python на SQL, что позволило сильно ускорить вычисления и выйти на больший масштаб. Но с ростом данных этого всё равно было очень мало, я думал над оптимизациями, старался переиспользовать свой опыт big data аналитики с работы, экспериментировал с разными структурами запросов и генерацией SQL-запросов Питоном, это позволило ускорить вычисления в несколько раз, что мило, но всё равно мало.

Потом я решил сделать поиск двух-этапным: преобразовывать хэши-дробные-векторы в небольшой массив байт, сохраняя каждый признак в два бита: v>0.1 и v<-0.1 (здесь), затем сравнивая число совпавших бит такого хэша у целевого лица и всех лиц в БД, а потом фильтруя записи в БД по какому-то трешхолду, отправляя на более точное и медленное сравнение только потенциальных кандидатов. Пришлось повозиться и переехать на MySQL v8, т.к в 5.7 бинарных операций нет. Но это позволило ускорить поиск ещё почти в 30 раз а это уже клёво ^_^

Вообще, поиск можно было бы улучшать и дальше возможно подобрав более эффективные коэффициенты в операции выше, или переделав этот хэш, ещё было бы круто добавить параллелизм, которого в MySQL из коробки нет, партицирование, шардирование, и искать многопоточно; для этого в планах был переезд на PostgreSQL.

2.4. Другие механики

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

Ускорять время поиска можно не только ускорением самого поискового алгоритма, но и снижением выборки, например, ища профили только среди участников каких-то групп Вк. Ясное дело, здесь встаёт вопрос ограничения размера этой выборки, т.к делать запрос с "ISIN (десятки тысяч айдишников)" такое себе, а вот на паре сотен и даже тысяч работает в разы быстрее, чем полный проход БД.

Помимо прочего, я немного помешан на математике, множествах графах, а соц.сети это прекрасные данные и множеств, и графов! Я подумал, что можно двигаться в этом направлении, позволяя задавать сложные запросы с И-ИЛИ-деревьями. Притом, искать можно не только по фото, но и по ник-неймам или ссылкам на профили в других соц.сетях к сожалению, поисковики интернета и Вк эту инфу не очень индексируют, и я попробовал делать это сам.

Если идти ещё дальше, то можно индексировать не только Вк, но и ВотсАп, Тг перебрав все русские номера, возможно частично FB, Twi, Ig. Но это уже совсем будущее, я решил двигаться в сторону скорейшей апробации и монетизации того, что есть уже.

3. Заключение

3.2. Happy ли end?

Перед разработкой ЛК, интеграции платежей и т.п декора, я решил больше разобраться в общественных настроениях, т.к некоторые мои знакомые выражали сомнения, что им было быы приятно пользоваться, а ещё серьёзнее быть доступными в таком сервисе. Помимо этого, примерно тогда же Вк ввёл закрытые профили, чтобы переживающее о своей безопасности люди могли спокойно скрываться, и анализируя статистику своих воркеров я видел, что число таких профилей всё растёт.

Я написал в тех поддержку Вк (тогда они ещё отвечали, ахах), аккуратно представился студентом, что хочу проводить социологические исследования скандируя большие объёмы данных Вк, в т.ч фото, ФИО и описание. Что на самом деле было правдой, с учётом моего интереса к аналитике и психологии. Они ответили, что ради статистики и небольших выборок в целом не против, но точно против какой-либо идентификации. А ещё "порадовали" тем, что будут и палки в колёса АПИ вставлять таким сервисам, и участвовать в разработке/внедрению законов, регулирующих эту деятельность. А недавно, уже в наше время, вышел законопроект, запрещающий автоматизированную обработку данных с сайтов, что по сути полностью блокирует подобные сервисы с парсингом.

В связи с этим, я принял решение о закрытии проекта, хоть это и было печально: в феврале 2019 у меня уже было проиндексировано 25% всего Вк в гигабайтах БД, притом не за бесплатно. Но у меня уже тогда был опыт различных проектов, поэтому я не жил розовыми мечтами об успешном успехе, а старался извлечь другую пользу и просто фан (:

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

После завершения описанной истории, я решил опубликовать исходники, но т.к там в истории коммитов засветились токены, то перезалил в новый репозиторий. Но код действительно такой, что мне самому туда страшно заглядывать :D
https://github.com/AivanF/ID-Detective-public

3.2. Польза

Здесь, как и в других своих пет-проектах и стартапах, я набрался много опыта:

  • Разобрался с многопоточностью в Питоне.

  • Покопался в специфических вопросах оптимизации MySQL запросов.

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

  • Освоил работу из кода с SSH для настройки окружения, понял, насколько чудесен Ansible.

  • Разработал микросервисную архитектуру из клея и палок, что затем позволило легко понять концепции Kubernetes.

И всё это мне очень пригодилось в последующих работах и проектах.

3.3. Мораль

Выводы каждый сделает свои, но главное не бойтесь пробовать, учиться и искать себя! Надеюсь, вам было интересно :)

Подробнее..

Вездекод как перенести хакатон в онлайн и не облажаться

03.11.2020 14:09:04 | Автор: admin
2020-й не пощадил большинство офлайн-мероприятий в том числе традиционный VK Hackathon. Раньше мы проводили его в Эрмитаже и Манеже, а в этом году в паблике ВКонтакте. Рассказываем, как придумали марафон Вездекод специально для онлайн-формата, собрали больше участников, чем ожидали, набили несколько шишек и получили отличную коллекцию мемов.



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

Наш хакатон один из крупнейших в России: его призовой фонд 2 миллиона рублей. Это флагманское мероприятие ВКонтакте, которое ждут каждый год. В 2019-м VK Hackathon прошёл в Манеже историческом здании в центре Санкт-Петербурга, где проводятся крупнейшие международные форумы и выставки. В соревновании участвовали 600 человек из 150 команд как независимые разработчики, так и сотрудники крупных IT-компаний: Яндекса, Сбербанка, Mail.ru, OZON, JetBrains, Альфа-Банка и других.



Мы могли отложить хакатон на следующий год, но не хотели оставлять наших участников без соревнования в 2020-м. Или перенести его в онлайн, не меняя формат и название, так сделали многие коллеги. Но это был бы уже не VK Hackathon его фишка именно в атмосфере непрерывного командного кодинга в центре Петербурга. Поэтому мы решили оставить офлайн-мероприятие до лучших времён и придумали концепцию нового.

Офлайна не будет. Что делать?


Мы начали с того, что разложили составляющие классического хакатона на части. Если грубо упростить, получалось, что на мероприятии участники команды работают практически по очереди: сначала дизайнер рисует первые макеты, потом мобильные или веб-разработчики создают техническую часть продукта, которую в итоге защищают на питчинге.

Мы сформулировали идею: запустить микросоревнования по разным направлениям и таким образом провести многоступенчатый отбор команд для финала. За основу взяли схему дизайн мобильное приложение веб и придумали три кейса, которые командам предстояло решить за две недели. К этим заданиям щедро добавили задачек для разогрева: по тестированию, а также поиску и фиксу уязвимостей в VK Mini Apps.

Так появилась концепция марафона кодинга и родился Вездекод.

Вездекод 1.0


Вездекод это двухнедельный марафон, где можно было участвовать в одиночку или командой до четырёх человек. Соревнование проходило в закрытом сообществе ВКонтакте туда ребята попадали после регистрации. В группе публиковались задания тем, кто верно выполнял их, начислялись баллы. По их сумме команды занимали строчки в общем рейтинге. Обладатели первых трёх мест в итоговой турнирной таблице стали победителями марафона. А ещё баллы пригодились участникам во внутреннем магазине Вездекода: там можно было купить стикеры, значки, мягкие игрушки и другой мерч VK, а также важные нематериальные бонусы: например, ревью резюме с нашей HR-командой.

Одна из главных фишек мероприятия в том, что каждый день в 12:00 по Москве мы выходили в прямой эфир: объясняли основное задание и отвечали на вопросы участников. На этих встречах мы общались с ребятами лицом к лицу и это помогло сохранить тесную связь с командами. Получился формат хакатона и реалити-шоу в одном флаконе.



Мы сделали два чата от имени сообщества Вездекод:
  • Оргвопросы здесь участники уточняли задания, давали обратную связь и спрашивали: А ГДЕ БАЛЛ?;
  • флудилку чтобы все общались на любые темы.

Чаты не умолкали 24/7: мы постоянно отвечали на вопросы, помогали понять задания и принимали обратную связь. Это был совершенно новый формат и для нас, и для участников. Так что мы старались откликаться на комментарии ребят и шли им навстречу: докручивали задания, меняли их очерёдность или критерии оценки результатов, если понимали, что что-то получилось не совсем логично.

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

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



Участники


Мы традиционно даём участникам свободу решать, сколько человек будет в их команде. Обозначаем только верхнюю границу четверо. На офлайн-хакатоне можно было соревноваться и вдвоём, и втроём, а на Вездекоде даже соло. Но выигрышной всё же была стратегия команд, где объединились несколько специалистов разных направлений. Как и в классическом хакатоне, каждый должен был играть свою роль: отвечать за дизайн, веб или мобильную разработку. (В середине Вездекода мы поняли, что эта схема не сработала: ребята штурмовали задачи вне зависимости от специализации.)

Попробовать силы в марафоне могли все желающие, кому уже исполнилось 14 лет. Для регистрации участников мы разработали простое мини-приложение. Оно позволяло быстро выгружать обновлённую базу ведь к Вездекоду можно было присоединиться в любой момент. Мы сделали регистрацию максимально свободной, поэтому собрали намного больше участников, чем ожидали. Планировали, что их будет около тысячи, а в итоге приняли на марафоне 1400 команд (!) это почти 3000 участников.



Задания и их оценка


Как в условиях полного онлайна грамотно оценить разнообразные проекты? И получится ли обеспечить равные условия участникам, если кто-то может работать над проектом целыми днями все две недели, а у других получается выделить на задачи только пару вечеров?

Мы придумали гибкую разветвлённую систему заданий. В её основе три больших проекта разного уровня: простой, средний и сложный. Каждый из них включал задачи по категориям: дизайну, мобильной и веб-разработке. Так получилось 9 заданий. Затем мы добавили блоки тестирования и задач стало 12. Они концептуально связаны друг с другом, но выполнять их можно было и по отдельности. Чем больше заданий делала команда тем больше баллов зарабатывала. Если справлялась со всеми задачами по одному проекту, получался полноценный продукт: мини-апп или мобильное приложение с веб-версией. Мы распределили задания в случайном порядке, но внимательные участники догадывались, что им предстоит реализовывать через несколько дней.



Новые задания публиковались в закрытом паблике по одному в день и выполнять их нужно было за 24 часа. Не все участники были заняты ежедневно например, если мы выкладывали задачу на веб-разработку, дизайнеры могли отдыхать. Чтобы свободные ребята не скучали, мы предлагали им дополнительные задания: приглашали на внезапные бот-викторины и онлайн-соревнования по мотивам наших любимых активностей с конференций: Code in the Dark (это вёрстка вслепую) и Kitten Contest (версия Своей игры от VK).



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

Здесь мы столкнулись с первой сложностью: даже тщательно проработанный участниками макет мог быть не полностью адаптирован под каждую из наших платформ мобильный веб, Mini App, iOS и Android. Кроме того, участникам оказалось сложно применить их гайдлайны к готовому макету.

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



Но главный челлендж онлайн-мероприятий без предварительного отбора это непредсказуемый объём проверки заданий. Составляя первое расписание, мы думали, что сможем отсматривать все решения примерно за сутки. Участники ведь справляются с задачами за 24 часа! Как же мы ошибались :) В одном из заданий по дизайну мы получили 164 решения, по мобильной разработке 100: причём у некоторых участников это были и Android-, и iOS-реализации. В итоге мы едва успевали публиковать итоговые баллы за задание только через полтора дня после того, как заканчивали принимать от участников решения. Оставлять подробную обратную связь тоже не получалось в итоге ребята обсуждали проекты друг друга в оргчате.

А ещё мы не учли огромную любовь участников Вездекода к ненативной разработке под мобильные платформы и не предусмотрели это при формулировке заданий. Многие команды стали работать с React Native и Flutter с их помощью можно легко обеспечить кросс-платформенность и даже переиспользовать код между мобильными и веб-заданиями. Но результаты не радовали нас при проверке заданий: решения не всегда собирались из исходников, основывались на не самых эффективных подходах. К сожалению, мы не сформулировали сразу список разрешённых технологий поэтому участники были справедливо недовольны тем, что правила оценки решений менялись.

Мир, дружба, мемы


На второй неделе марафона в чате-флудилке начали появляться мемы от участников. Картинки были суперсмешными, так что мы решили устроить батл и начислять авторам самых метких шуток дополнительные баллы.



Финал Вездекода. Питчинг вымышленных проектов


В рецепте идеального хакатона есть несколько обязательных ингредиентов: клёвая команда, оригинальная задумка, качественная реализация и взрывная презентация. В финале Вездекода мы взяли одну из составляющих на себя: предложили двадцати командам-лидерам очень необычные идеи для проектов и пригласили защитить их на питчинге в прямом эфире.

Чтобы было веселее, сделали приложение генератор идей. Он в случайном порядке собирает концепцию проекта из фрагментов, отвечающих на вопросы какой?, что?, для чего? и для кого?. Так что команде мог достаться Культурный агрегатор для удалённой работы диснеевских принцесс или Сезонный навигатор для саморазвития молодых родителей. Генератор идей работает и сейчас загляните, может, он предложит вам проект, который захочется реализовать ;)



Накануне финала мы распределили вымышленные проекты между командами из топа рейтинга и составили расписание защит. Чтобы приблизить атмосферу питчинга к реальным условиям, запланировали прямую трансляцию презентаций в сообществе VK Tech. В магазине Вездекода ребята могли за баллы продлить дедлайн на один час и записаться на онлайн-консультацию со специалистами из студии коммуникаций BEsmart. В итоге те команды, которые заказали прогон выступления с тренерами, и заняли призовые места.

Многие участники блестяще справились с защитой немыслимых проектов от нашего генератора идей это был, думаем, уникальный опыт :) Некоторые даже успели сделать работающий MVP. Все защиты проектов мы опубликовали в сообществе VK Tech их можно посмотреть.

Какие выводы мы сделали?


  • Позиционирование. Слово хакатон сыграло против нас, ведь участники ждали привычного состязания в этом формате, а мы сделали нечто иное. Хотя Вездекод был как раз марафоном кодинга по смыслу это очень близко к изначальному значению термина хакатон.
  • Количество участников. Не ожидали такого наплыва желающих. Всего за время Вездекода зарегистрировались 1400 команд, то есть почти 3000 человек. Активно соревновались 647 команд это 1749 участников. В общей сложности мы проверили 27 заданий, начислили 59106 баллов и отправили 1000 заказов из магазина.
  • Уровень команд. Зарегистрироваться на Вездекод мог любой человек старше 14 лет. Мы не проводили отбор по идеям и специализации участников поэтому по сравнению с классическим хакатоном порог входа ощутимо понизился. С одной стороны, это плюс попробовать силы смогли совсем юные разработчики, мы научили многих работать с Figma и решать продуктовые задачки. Но с другой получили от участников шквал базовых околотехнических вопросов, на которые отвечали почти круглосуточно.
  • Мало направлений. В формате онлайн-марафона мы решили переложить саму концепцию взаимодействия участников на хакатоне последовательное выполнение разных задач. Так в Вездекоде появились направления для заданий и их очерёдность. Но мы обожглись о полярный уровень участников. Одни, быстро разгадав логику, были заранее готовы к следующим задачам, консультировались с дизайнером и помогали друг другу на каждом этапе. А менее опытные ждали от нас чёткого ТЗ и расстраивались, что задание снова не на код (эмоциями по этому поводу делились под хештегом #агдекод). В будущем мы попробуем разнообразить специфику заданий. А ещё на берегу обозначим стек технологий: не забудем разобрать скользкие кейсы вроде мобильной разработки на Flutter. И придумаем, как прикрутить автопроверку, чтобы разгрузить жюри и авторов заданий.


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

  1. Подумайте о трудозатратах и команде. Подготовьтесь к тому, что сил и времени на онлайн уйдёт даже больше, чем на офлайн. Мы это прочувствовали в многократном объёме: Вездекод стал марафоном не только для участников, но и для нас :) На нашем событии с командами работали четыре организатора, и ещё около 20 человек были задействованы в составлении и проверке заданий.
  2. Уделите внимание деталям и максимально разжёвывайте задания. То, что на площадке можно проговорить голосом со сцены, на онлайн-соревновании быстро обрастает версиями во флудилках и провоцирует лавину нерелевантных вопросов.
  3. Заботьтесь об участниках. Придумайте механики, чтобы каждая команда могла себя проявить и получить хотя бы небольшой приз. В онлайне гораздо меньше ощущается взаимодействие с организаторами, поэтому важно оставить о мероприятии что-то на память. Один из наших участников при заказе из магазина Вездекода попросил организаторов оставить на мерче автографы и так у нас родилась идея рукописных открыток для всех.
  4. Не бойтесь ошибаться. Фиксируйте обратную связь и возвращайтесь на арену онлайн-ивентов!
Подробнее..

Бенчмарки VKUI и других ребят из UI-библиотек

26.05.2021 12:10:08 | Автор: admin

Меня зовут Григорий Горбовской, я работаю в Web-команде департамента по экосистемным продуктам ВКонтакте, занимаюсь разработкой VKUI.

Хочу вкратце рассказать, как мы написали 8 тестовых веб-приложений, подключили их к моно-репозиторию, автоматизировали аудит через Google Lighthouse с помощью GitHub Actions и как решали проблемы, с которыми столкнулись.

VKUI это полноценный UI-фреймворк, с помощью которого можно создавать интерфейсы, внешне неотличимые от тех, которые пользователь видит ВКонтакте. Он адаптивный, а это значит, что приложение на нём будет выглядеть хорошо как на смартфонах с iOS или Android, так и на больших экранах планшетах и даже десктопе. Сегодня VKUI используется практически во всех сервисах платформы VK Mini Apps и важных разделах приложения ВКонтакте, которые надо быстро обновлять независимо от магазинов.

VKUI также активно применяется для экранов универсального приложения VK для iPhone и iPad. Это крупное обновление с поддержкой планшетов на iPadOS мы представили 1 апреля.

Адаптивный экран на VKUIАдаптивный экран на VKUI

Масштабирование было внушительным поэтому мы провели аудит, проанализировали проблемы, которые могут возникнуть у нас и пользователей при работе с VKUI, и заодно сравнили свои решения с продуктами ближайших конкурентов.

Какие задачи поставили

  1. Выявить главные проблемы производительности VKUI.

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

  3. Сравнить производительность VKUI и конкурирующих UI-фреймворков.

Технологический стек

Инструменты для организации процессов:

Чтобы проще взаимодействовать с несколькими веб-приложениями, в которых применяются разные UI-библиотеки, здесь используем lerna. Это удобный инструмент, с помощью которого мы объединили в большой проект ряд приложений с отличающимися зависимостями.

Бенчмарки мы проводим через Google Lighthouse официальный инструмент для измерения Web Vitals. Де-факто это стандарт индустрии для оценки производительности в вебе.

Самое важное делает GitHub Actions: связывает воедино сборку и аудит наших приложений.

Библиотеки, взятые для сравнения:

Название

Сайт или репозиторий

VKUI

github.com/VKCOM/VKUI

Material-UI

material-ui.com

Yandex UI

github.com/bem/yandex-ui

Fluent UI

github.com/microsoft/fluentui

Lightning

react.lightningdesignsystem.com

Adobe Spectrum

react-spectrum.adobe.com

Ant Design

ant.design

Framework7

framework7.io


Мы решили сравнить популярные UI-фреймворки, часть из которых основана на собственных дизайн-системах. В качестве базового шаблона на React использовали create-react-app, и на момент написания приложений брали самые актуальные версии библиотек.

Тестируемые приложения

Первым делом мы набросали 8 приложений. В каждом были такие страницы:

  1. Default страница с адаптивной вёрсткой, содержит по 23 подстраницы.

    • На главной находится лента с однотипным контентом и предложением ввести код подтверждения (абстрактный). При его вводе на несколько секунд отображается полноэкранный спиннер загрузки.

    • Страница настроек, в которую входит модальное окно с примитивным редактированием профиля и очередным предложением ввести код.

    • Страница с простым диалогом условно, с техподдержкой.

  2. List (Burn) страница со списком из 500 элементов. Главный аспект, который нам хотелось проверить: как вложенность кликабельных элементов влияет на показатель Performance.

  3. Modals страница с несколькими модальными окнами.

Не у всех UI-фреймворков есть аналогичные компоненты недостающие мы заменяли на равнозначные им по функциональности. Ближе всего к VKUI по компонентам и видам их отображения оказались Material-UI и Framework7.

Сделать 8 таких приложений поначалу кажется простой задачей, но спустя неделю просто упарываешься писать одно и то же, но с разными библиотеками. У каждого UI-фреймворка своя документация, API и особенности. С некоторыми я сталкивался впервые. Особенно запомнился Yandex UI кажется, совсем не предназначенный для использования сторонними разработчиками. Какие-то компоненты и описания параметров к ним удавалось найти, только копаясь в исходном коде. Ещё умилительно было обнаружить в компоненте хедера логотип Яндекса <3

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

Автоматизация

Краткая блок-схема, описывающая процессы в автоматизацииКраткая блок-схема, описывающая процессы в автоматизации

Подготовили два воркфлоу:

  • Build and Deploy здесь в первую очередь автоматизировали процессы сборки и разворачивания. Используем surge, чтобы быстро публиковать статичные приложения. Но постепенно перейдём к их запуску и аудиту внутри GitHub Actions воркеров.

  • Run Benchmarks а здесь создаётся issue-тикет в репозитории со ссылкой на активный воркфлоу, затем запускается Lighthouse CI Action по подготовленным ссылкам.

UI-фреймворк

URL на тестовое приложение

VKUI

vkui-benchmark.surge.sh

Ant Design

ant-benchmark.surge.sh

Material UI

mui-benchmark.surge.sh

Framework7

f7-benchmark.surge.sh

Fluent UI

fluent-benchmark.surge.sh

Lightning

lightning-benchmark.surge.sh

Yandex UI

yandex-benchmark.surge.sh

Adobe Spectrum

spectrum-benchmark.surge.sh


Конфигурация сейчас выглядит так:

{  "ci": {    "collect": {      "settings": {        "preset": "desktop", // Desktop-пресет        "maxWaitForFcp": 60000 // Время ожидания ответа от сервера      }    }  }}

После аудита всех приложений запускается задача finalize-report. Она форматирует полученные данные в удобную сравнительную таблицу (с помощью магии Markdown) и отправляет её комментарием к тикету. Удобненько, да?

Пример подобного репорта от 30 марта 2021 г.Пример подобного репорта от 30 марта 2021 г.

Нестабильность результатов

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

Из отчётов Lighthouse выяснили следующее: по неведомым причинам сервер долго отвечал, и это привело к общему замедлению и снижению баллов. Изначально грешили на воркеры и хостинг в целом, и я решился задеплоить и провести бенчмарки на одном сервере. Результаты стали лучше, но такое странное поведение оставалось нелогичным.

Предупреждения из отчётов Google LighthouseПредупреждения из отчётов Google Lighthouse

GitHub Actions по умолчанию выполняет задачи параллельно, как и в нашем воркфлоу с бенчмарками. Решение ограничить максимальное количество выполняющихся одновременно задач:

jobs.<job_id>.strategy.max-parallel: 1

Мы провели бенчмарк дважды, и вуаля результаты стали ощутимо стабильнее. Теперь можно переходить к результатам.

Результаты от 30 марта 2021 г.

VKUI (4.3.0) vs ant:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

ant

default

report

0.99

vkui (4.3.0)

modals

report

1

ant

modals

report

0.99

vkui (4.3.0)

list

report

0.94

ant

list

report

0.89

list - У ant нет схожего по сложности компонента для отрисовки сложных списков, но на 0,05 балла отстали.

VKUI (4.3.0) vs Framework7:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

f7

default

report

0.98

vkui (4.3.0)

modals

report

1

f7

modals

report

0.99

vkui (4.3.0)

list

report

0.94

f7

list

report

0.92

list - Framework7 не позволяет вложить одновременно checkbox и radio в компонент списка (List).

VKUI (4.3.0) vs Fluent:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

fluent

default

report

0.94

vkui (4.3.0)

modals

report

1

fluent

modals

report

0.99

vkui (4.3.0)

list

report

0.94

fluent

list

report

0.97

modals - Разница на уровне погрешности.

list - Fluent не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs Lightning:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

lightning

default

report

0.95

vkui (4.3.0)

modals

report

1

lightning

modals

report

1

vkui (4.3.0)

list

report

0.94

lightning

list

report

0.99

list - Lightning не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs mui:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

mui

default

report

0.93

vkui (4.3.0)

modals

report

1

mui

modals

report

0.96

vkui (4.3.0)

list

report

0.94

mui

list

report

0.77

default и modals - Расхождение незначительное, у Material-UI проседает First Contentful Paint.

list - При примерно одинаковой загруженности списков в Material-UI и VKUI выигрываем по Average Render Time почти в три раза (~1328,6 мс в Material-UI vs ~476,4 мс в VKUI).

VKUI (4.3.0) vs spectrum:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

spectrum

default

report

0.99

vkui (4.3.0)

modals

report

1

spectrum

modals

report

1

vkui (4.3.0)

list

report

0.94

spectrum

list

report

1

list - Spectrum не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs yandex:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

yandex

default

report

1

vkui (4.3.0)

modals

report

1

yandex

modals

report

1

vkui (4.3.0)

list

report

0.94

yandex

list

report

1

default - Разница на уровне погрешности.

list - Yandex-UI не имеет схожего по сложности компонента для отрисовки сложных списков.

modals - Модальные страницы в Yandex UI объективно легче.

Выводы из отчёта Lighthouse о VKUI

  • VKUI по показателям на одном уровне с другими библиотеками. Сильных просадок, как и значительного превосходства, нет.

  • Одно из явных проблемных мест вложенные Tappable протестированы на большом списке. Единственная библиотека, в которой полноценно реализован этот кейс, Material-UI. И VKUI уверенно обходит её по производительности.

  • Lighthouse ругается на стили после сборки много неиспользуемых. Они же замедляют First Contentful Paint. Над этим уже работают.

Два CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gzДва CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gz

Планы на будущее vkui-benchmarks

Переход с хостинга статики на локальное тестирование должен сократить погрешность: уменьшится вероятность того, что из-за внешнего фактора станет ниже балл у того или иного веб-приложения. Ещё у нас в репортах есть показатель CPU/Memory Power и он немного отличается в зависимости от воркеров, которые может дать GitHub. Из-за этого результаты в репортах могут разниться в пределах 0,010,03. Это можно решить введением перцентилей.

Также планируем сделать Lighthouse Server для сохранения статистики по бенчмаркам на каждый релиз.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru