вступление

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

Однако, что меня удивило, когда я впервые заглянул в него, так это не формат/контент, а люди в видеороликах, рекомендованных приложением. Лица людей, которых я там вижу, казались совсем не такими, какие я вижу в повседневной жизни, в сторону — как бы это сказать? — «условная привлекательность». Это очень необычно и существенно отличалось от других платформ видеохостинга — я никогда не сталкивался с этим при просмотре YouTube, например.

Я подумал, что это могут быть только мои внутренние предубеждения и то, как я лично воспринимал систему, поэтому я решил проанализировать данные, чтобы увидеть, есть ли на самом деле научные доказательства, подтверждающие мое утверждение. Этот пост — попытка более тщательного анализа и проверки гипотезы о том, что TikTok активно (явно или неявно) продвигает лукизм.

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

Сбор данных

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

Берем последний снимок индекса Common Crawl и собираем все упомянутые в нем учетные записи TikTok (около 16000). Конечно, это относится к активным учетным записям, о которых мы должны помнить позже.

Далее мы очищаем эти аккаунты. Это довольно утомительный и ресурсоемкий шаг. Есть некоторые инструменты для парсинга Tiktok (например, TikTok-Api), однако на данный момент они давно не обновлялись, и многие функции не работают, поэтому необходима некоторая ручная работа.

Наша цель — получить лица создателей каналов, и, к сожалению, аватарки для этой цели не годятся (низкое разрешение и часто вместо лиц содержит что-то другое). Итак, мы должны очистить видео. Мы берем не более 16 случайных видео на канал, что дает около 1200 ГБ данных. Кроме того, мы сохраняем метаданные канала (в частности, количество подписчиков, которое будет нашим прокси для понятия «популярность»). Мы также сохраняем метаданные для всехвидео на канале, которые впоследствии пригодятся для анализа (в частности, для определения языка канала, возраста и темы).

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

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

Обработка данных

Как было сказано выше, для наших меток мы берем количество подписчиков канала (если быть точнее — log(1 + Subscribers)). Однако, как мы получаем лица?

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

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

Далее мы хотим найти фактическое лицо владельца канала. Для этого мы можем использовать любое разумное встраивание лица (например, из той же библиотеки face_recognition). Выбираем самую центральную грань, минимизируя сумму расстояний от ее вложения до вложений всех остальных граней, и сортируем все грани по расстоянию от нее. Обычно существует очень четкое разделение кластера с основной гранью от остальных и граней, при этом основной кластер больше, чем все остальные вместе взятые (если бы это было не так — такой упрощенный подход не годился бы). не работает, и нам нужно будет запустить правильную кластеризацию и выбрать самый большой кластер).

Ниже представлена ​​проекция t-SNE граней из приведенного выше примера, с цветовой маркировкой основных граней по сравнению с выбросами (интерактивная ссылка):

После фильтрации мы видим, что наш алгоритм имеет смысл:

Таким образом мы обрабатываем всех пользователей, отбрасывая тех, у кого нет/слишком мало лиц (удивительно, но нетривиальная часть из них имеет нулевое лицо — в отличие от того, что мы видим в рекомендациях на главной странице TikTok). В результате мы получаем набор данных из 12947 пользователей с несколькими лицами на пользователя.

Мы делимся полученным набором данных здесь:

  • TFRecord с лицами (до 32 лиц на канал), с разбивкой на обучение/тест: ссылка
  • Метаданные на канал: ссылка

Предиктивная модель: первая попытка

Теперь мы можем рассматривать нашу проблему как простую задачу регрессии с учителем — по лицу предсказать метку (log(1 + Subscribers)). В качестве цели обучения используем среднеквадратичную ошибку, в качестве метрики — корреляцию Пирсона (рассуждать немного проще, чем MSE, которая сильно зависит от распределения меток). Если кто-то скептически относится к корреляции Пирсона, он также может взглянуть на корреляцию Спирмена, которая еще более интуитивно понятна, поскольку не зависит ни от масштаба, ни от распределения меток. Мы делаем обычное разделение обучения/проверки (очевидно, по пользователям, а не по лицам) с соотношением 90%:10%.

Давайте сначала посмотрим на распределение количества подписчиков (до применения логарифма):

Это выглядит довольно странно — в значительной степени бимодальным. Если подумать, в этом нет ничего удивительного, должны быть какие-то кластеры типа «английский против других языков» или тематические (подробнее об этом позже).

В отношении модели необходимо сделать некоторые выборы (например, сколько лиц мы берем от каждого пользователя, каковы гиперпараметры и т. д.). Выбираем максимально простую сверточную модель, дополненную вложениями из библиотеки face_recognition (аугментация имеет следующий вид: сначала пропускаем изображение через сверточную НС, получаем вложение, затем конкатенируем с вложением из библиотеки , и пройти через небольшой MLP). Как оказалось, конкретные гиперпараметры не имеют большого значения.

Однако количество лиц, которое может выбрать каждый пользователь, сильно влияет на результирующую производительность (также, если мы используем несколько лиц на этапе вывода, собирая результат по нескольким лицам). Использование нескольких лиц на этапе обучения можно рассматривать как форму аугментации данных, так что в этом нет ничего удивительного. Мы достигаем корреляции Пирсона 0,33 при 1 лице на пользователя, 0,42 при 32 лицах на пользователя при обучении и 1 при проверке и 0,45 при 32 лицах на пользователя в обоих случаях (т. е. ансамбли при проверке).

Обратите внимание, что все эти цифры на самом деле безумно высоки! Это означает, что 45% дисперсии количества подписчиков объясняется лицом создателя контента, а не «незначительными» вещами, такими как качество контента или личность. Трудно поверить, что такая высокая корреляция может быть органичной без «помощи» алгоритмов TikTok.

Обученную модель можно найти здесь, блокнот Jupyter — здесь. Давайте посмотрим на лица в проверочном наборе, которые нравятся модели (слева), и те, которые ей не нравятся (справа):

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

Срезовой и факторный анализ

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

Откуда взять эти понятия? Знаменитый набор данных Celeb-A содержит набор лиц, аннотированных кучей понятий, что очень хорошо подходит для нашего варианта использования. Поэтому мы обучаем отдельную модель на Celeb-A (Jupyter, веса), чтобы предсказывать эти атрибуты, и применяем ее к лицам в нашем наборе данных TikTok.

Теперь для каждого пользователя у нас есть набор прогнозов в диапазоне [0, 1] для таких атрибутов, как «Улыбчивый», «Бледная кожа» и «Мужской». Первое, что мы можем сделать, это вычислить корреляцию с меткой для каждого атрибута:

Вариант «Bushy_Eyebrows» странный — все значения низкие, а более высокие значения (около 0,2) указывают на людей с сильным макияжем, в частности с искусственными бровями. Остальные высокие (по абсолютной величине) корреляции, похоже, имеют смысл (вывод: если вы хотите стать популярным в TikTok — носите много косметики и не носите очки).

Затем мы можем обучить модель на основе этих атрибутов для прогнозирования метки. Наиболее подходящим типом модели будут деревья решений с градиентным усилением, например. ЛайтГБМ. Простое добавление прогнозов в модель дает нам корреляции около 0,41, что близко к сверточной модели NN, но это не совсем справедливо: эти прогнозы с плавающей запятой содержат больше информации, чем просто атрибуты, а древовидная модель извлекает его, получая значительно немонотонные зависимости от признаков, в то время как он пытается извлечь некоторые лежащие в основе поверхностные корреляции в модели, которая предоставляет эти понятия, а не из самих понятий.

Более чистым способом было бы «дискретизировать» функции до 0/1 и обучить модель поверх них (например, вышеупомянутый Bushy_Eyebrows исчезает при этом). Альтернативой может быть изучение простых моделей (например, линейных), которые будут монотонными, и древовидной модели будет сложнее извлекать поверхностные корреляции.

Это теряет много информации и дает нам модель с корреляцией всего 0,21, однако теперь она изучает то, что мы хотим, и мы можем посмотреть на важность функций:

Хорошо, кажется, что улыбка важна, но теперь мы видим, что признак «Мужской» очень высок. Это довольно подозрительно, давайте посмотрим внимательнее.

Первое, что бросается в глаза, это то, что качество предсказания исходной модели CNN на срезах мужского и не мужского пола сильно различается: корреляция Пирсона 0,40 против 0,47! Средняя метка немного в пользу не-мужского, но разница в корреляциях объясняет то, что мы видели выше: все лица с самым низким прогнозом были не-мужскими, не из-за средних, а потому, что модель более уверена в этом срезе, поэтому он делает более экстремальные прогнозы (в частности, в низком диапазоне).

Затем мы можем разделить данные по признаку «Мужской» и посмотреть на корреляции и важность признаков. Например. корреляции:

Мы видим некоторые различия, например. Быть молодым важнее для мужчин, а яркий макияж — для не-мужчин.

Помимо пола, есть много тревожных закономерностей. Например. эйджизм: «Молодость» — очень важная положительная характеристика по всем направлениям, в то время как понятия, связанные со старением (например, «Седые волосы»), являются отрицательными. Или анти-бодипозитивность: такие понятия, как «пухлый» или «двойной подбородок» негативны. Макияж и концепции, связанные с макияжем, пожалуй, самые сильные из всех.

Добавление дополнительных сигналов

Мы видели ошеломляющую корреляцию 0,45 с количеством подписчиков только для моделей, основанных на лицах. Однако есть факторы, которые должны быть ортогональны (или преимущественно ортогональны) грани, что должно существенно повлиять на эту величину. Например, чем старше канал, тем больше у него должно быть подписчиков, или у каналов на английском языке должно быть больше подписчиков, чем на каких-то малопонятных языках. Что произойдет, если мы используем эти сигналы и в прогностических моделях? Насколько хорошего предсказателя мы можем добиться? Можем ли мы проверить, является ли количество подписчиков в значительной степени предопределенным (если да, то оно, скорее всего, предопределено алгоритмами TikTok), или все же присутствует значительная стохастическая составляющая?

Давайте отметим важный аспект этого, прежде чем мы углубимся в детали. Честной и справедливой настройкой было бы сделать моментальный снимок данных во время создания канала (возможно, давно), вычислить сигналы из него, а затем прямо сейчас использовать подписчиков в качестве метки. То, что мы делаем, несколько отличается. Налицо явная предвзятость выживших: мы взяли каналы из недавнего снимка CommonCrawl, так что это предвзятое отношение к каналам, которые активны сейчас. Это означает, что вымершие каналы не захватываются должным образом. Другой (похожий) эффект — это петля обратной связи — сам TikTok влияет на сигналы, которые мы измеряем.

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

Начнем с добавления языка, так как он наименее предвзят. Определить его довольно просто — мы можем посмотреть описания всех видео на канале, пропустить их через детектор языка и выбрать большинство. Давайте проверим работоспособность: самые популярные языки (по порядку): EN, ES, AR, ID, PT, DE, JA, VI. Порядок имеет смысл, английский лидирует с большим отрывом. А как насчет распространения лейбла? Ниже приведены дистрибутивы для EN, AR и более мелких языков:

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

Итак, давайте скормим язык модели и совместно обучим предиктор (лицо, язык) -> метка. Что мы получаем? Результирующая корреляция составляет 0,47.

Следующим шагом является добавление возраста канала. Как было сказано выше, эта функция не совсем «честная» из-за предвзятости выжившего, тем не менее, попробуем ее использовать. Прежде всего, как это определить? TikTok не показывает, когда пользователь был зарегистрирован, но у нас есть временные метки всех видео, поэтому мы можем взять самое раннее, чтобы определить возраст канала. Полученный признак имеет 0,5 корреляции с лейблом, частично это, вероятно, связано с предвзятостью выжившего, но ожидается высокая корреляция — чем дольше существует канал, тем больше подписчиков он накапливает. Удивительно, но это также коррелирует с предсказанием на основе лиц, эта часть, вероятно, связана с предвзятостью выжившего (компонент «старые каналы имеют пожилых пользователей» вряд ли будет сильным; но может быть другой эффект людей с определенными лицами, которые являются первыми). создатели контента TikTok). Что произойдет, если мы добавим его к лицу и языку? Результирующая корреляция составляет 0,65, что уже является очень надежным (чрезвычайно высоким для чего-то, что должно быть стохастическим).

Наконец, как насчет темы канала? Можно себе представить, что каналы о танцах, кулинарии и косметике имеют разное среднее количество подписчиков. Но как определить тему? Мы не нашли готовых моделей, поэтому сделали следующее. Давайте возьмем описания видео и хэштеги, обучим на них word2vec и посчитаем встраивание для каждого пользователя как среднее вложений всех токенов, упомянутых пользователем. Видно, что он довольно хлипкий — скорее всего захватит темы, но может захватить и многое другое (в худшем случае лейблы могут просочиться в фичи, если кто-то решит написать в описании У меня 10 млн подписчиков! ).

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

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

Бонус: фейс тиктокификатор

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

Есть много способов сделать это, возможно, лучшим с точки зрения качества может быть использование некоторых современных архитектур генерации изображений, например. Распространение + img2img + руководство по классификатору. Однако мы пойдем более простым и быстрым путем.

Давайте используем StyleGAN3 в качестве нашей модели для лиц и сделаем инверсию модели на основе этого репозитория. Архитектура StyleGAN генерирует лицо из скрытого кодирования формы [16, 512], которое должно выглядеть как случайный шум. Инверсия создает скрытую кодировку лица (эта задача не так тривиальна, как кажется; конечно, можно создать некоторую кодировку, но она может оказаться в нераспространяемой области скрытое пространство, и магия редактирования не сработает). Тогда получается, что естественные правки лица соответствуют линейным преобразованиям в этом пространстве (подробнее см. это).

Есть предварительно обученные преобразования для таких атрибутов, как Возраст и Пол (см. Официальный Colab), а также все атрибуты CelebA, включая Привлекательность. Мы обучаем еще одно линейное преобразование для максимизации подписчиков TikTok и визуально сравниваем его с преобразованием CelebA Привлекательность.

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

Итак, мы кодируем наш набор данных в скрытое пространство StyleGAN3 и используем эти данные для обучения линейному преобразованию для увеличения количества подписчиков. Давайте посмотрим, как это влияет на некоторые лица. На графиках ниже первый ряд — это вариации (как в положительную, так и в отрицательную сторону) лица по нашему обученному вектору, второй ряд — по вектору «Привлекательности» от CelebA (для сравнения). Изображение «без редактирования» в середине обозначено черным прямоугольником.

Видно, что вектор «ТикТок» не имеет отбеливающего и феминизирующего эффектов, в отличие от вектора CelebA-Привлекательность. Тем не менее, это дает эффект добавления большего количества макияжа и уменьшения воспринимаемого возраста.

Давайте посмотрим на некоторые другие примеры:

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

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

Заключение

Мы показали, что внешний вид/лицо создателя контента очень сильно влияет на количество его подписчиков в TikTok. Какой практический вывод мы можем из этого сделать?

Следует отметить, что все модели, которые мы обучаем, являются корреляционными, и невозможно определить причинно-следственную связь без проведения рандомизированных A/B-тестов. Тем не менее, можно рассуждать даже с корреляционными моделями: мы не знаем, приводит ли сильный макияж к росту числа ваших подписчиков, или большое количество подписчиков заставляет людей носить сильный макияж, но наличие корреляции указывает на то, что что-то происходит.

В частности, масштаб корреляции (0,45 от одних только лиц, 0,8 (условно) от лица+язык+возраст+тема) настолько высок, что трудно представить, что это произойдет органично. Даже если бы пользователи нажимали на такие лица, достижение таких цифр без петли подкрепления практически невозможно. Что приводит нас к следующему выводу: скорее всего, алгоритмы рекомендаций TikTok используют лица в качестве сигнала,таким образом продвигая лукизм (либо явно, либо неявно — путем обучения на предпочтениях пользователей) .

Разве это плохо? Я бы сказал, что даже имплицитный лукизм — это плохо из-за усиления предвзятости: основывая рекомендации на лицах, они сделают предвзятость еще сильнее (т. лица TikTok-y» получат больше подписчиков). т.е. это не только отражает их экосистему, но и берет ее худшие части (например, эйджизм) и делает ее еще хуже. Если петля обратной связи действительно существует, в конце концов она усилится до предела; мы можем повторить анализ через пару лет и проверить, становятся ли корреляции еще сильнее (держу пари, что они становятся).

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

Более экстремальным способом было бы прекратить оптимизацию для взаимодействия, по крайней мере, напрямую. Вовлеченность хороша как метрика топлайна, потому что она хорошо коррелирует со знаком доллара, но, как мы знаем, если мы оптимизируем метрики топлайна напрямую, они перестают быть хорошими метриками (закон Гудхарта). Включение чего-то вроде независимого от создателя качества контента определенно поможет, но это повредит краткосрочной вовлеченности (хотя на самом деле может помочь долгосрочному росту). Однако я скептически отношусь к тому, что этот подход когда-либо будет принят — кажется, что все современные социальные сети сфокусированы на оптимизации взаимодействия, и TikTok не является исключением.

указатели

Код и блокноты

Данные

  • TikTok сталкивается с набором данных: ссылка
  • Метаданные канала для набора данных: ссылка
  • CommonCrawl — открытый веб-индекс
  • CelebA — большой набор аннотированных лиц

Библиотеки

  • face_recognition — хороший пакет Python для извлечения и встраивания лиц.
  • LightGBM — библиотека для форсированных деревьев решений
  • Gensim — библиотека НЛП, с помощью которой можно легко обучить собственный word2vec.
  • StyleGAN3 и его инверсия

Автор и контакты

— — — НАЧАТЬ ПОДПИСАННОЕ СООБЩЕНИЕ PGP — — -
Хэш: SHA512

https://medium.com/@enryu9000/lookism-in-tiktok-3def0f20cf78
— — — НАЧАЛО ПОДПИСИ PGP — — —

iHUEARYKAB0WIQS6MzboE1mQihro0YYJtk434j9gEgUCYzGIFgAKCRAJtk434j9g
EtRzAQConj5K9wQ3sNkQQyzXBDlDKs38+UpE9wL1qs4QmaAWGAEAu6M2ztaYUqLW
r7TG8 TqNAhuQSD/2lwtgL1vZEfQPhw8=
=BCeE
— — -КОНЕЦ ПОДПИСИ PGP — — —