Как клеить по 13 девушек в час, используя машинное обучение и Tinder

*Исключительно ради изучения Machine Learning, разумеется. Под немного недовольным взглядом любимой жены.

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

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

Как клеить по 13 девушек в час, используя машинное обучение и Tinder

В чем проблема сетей для знакомств

Был такой ресурс — Ashley Madison. Специфичный, с лозунгом «Life is short. Have an affair». Основная аудитория — женатые мужчины, ищущие себе интрижку на стороне. Монетизация тоже веселая — помимо стандартных «потрать баллы, чтобы лайкнуть и написать» они просили $19, чтобы удалить аккаунт пользователя без следов.

В 2015 году сайт закономерно протек и 60 ГБ персональных данных утекли в открытый доступ. Помимо множества разрушенных семей, эта утечка дала очень много интересной информации аналитикам. Я всегда подозревал, что мужчин на сайтах знакомств намного больше, но в этом случае оказалось совсем интересно. Журналистка Annalee Newitz, анализируя утекшие данные обнаружила, что из 5 миллионов пользователей только 12 000 были похожи на настоящие аккаунты девушек и использовались регулярно. Остальные были просто ботами, которые общались с мужчинами посетителями.

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

Особенность Tinder

Как клеить по 13 девушек в час, используя машинное обучение и Tinder
Идеальный брутфорсер в гендерных отношениях

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

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

Собираем данные

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

За основу возьмем репозиторий TinderAutomation. Фотографии у Tinder всегда общедоступны, но функция «лайков» уже лимитирована. Поэтому надо извлечь все живое в радиусе и тщательно промаркировать. Для начала надо воспользоваться довольно простым скриптом:

from skimage.io import imread, imsave, imshow, show
import matplotlib.pyplot as plt
import pynder
from helpers import get_access_token, get_login_credentials
from io_helper import save_image

email, password, FBID = get_login_credentials()
FBTOKEN = get_access_token(email, password)
session = pynder.Session(facebook_token=FBTOKEN)

while True:
    users = session.nearby_users()
    for user in users:
        photos = user.get_photos()
        print("Fetched user photos..")
        for photo in photos:
            print(photo)
            image = imread(photo)
            imshow(image)
            show()

            input_string = "Write 1 to like. Write 2 to dislike."
            ans = str(input(input_string)).lower()

            if ans == "1":
                save_image(image, photo, True)
            else:
                save_image(image, photo, False)

Он позволит вам максимально быстро разметить датасет всего двумя кнопками. Ключевой подводный камень кроется в том, что библиотека werkzeug сломала обратную совместимость и придется делать ее принудительный даунгрейд. Иначе вываливает вот такую ошибку.

Traceback (most recent call last):
  File "img_scrape.py", line 4, in <module>
    from helpers import get_access_token, get_login_credentials
  File "/home/someone/tmp/TinderAutomation/helpers.py", line 1, in <module>
    import robobrowser
  File "/home/someone/tmp/TinderAutomation/venv/lib/python3.6/site-packages/robobrowser/__init__.py", line 3, in <module>
    from .browser import RoboBrowser
  File "/home/someone/tmp/TinderAutomation/venv/lib/python3.6/site-packages/robobrowser/browser.py", line 8, in <module>
    from werkzeug import cached_property
ImportError: cannot import name 'cached_property'

Поэтому, в requirements.txt надо прописать Werkzeug==0.16.1. Тогда взлетит.
Вторая проблема — добыть этот самый токен. Стандартный способ из репозитория у меня не взлетел, но получилось добыть его из консоли разработчика. Для этого переходим по ссылке и выдергиваем ответ на POST-запрос в www.facebook.com/v2.6/dialog/oauth/confirm?dpr=1. Внутри ищем ‘access_token’. С первого раза почему-то не получилось, но потом я его нашел и захардкодил в скрипт.

Требования к датасету

Есть несколько ключевых требований к датасетам машинного обучения:

  1. Достаточность
  2. Равномерность
  3. Разнообразие

Достаточность в данном случае требует не меньше 10000 фотографий для построения адекватной модели. Да, это очень много. Собственно поэтому и существуют сервисы вроде Amazon Mechanical Turk, где за определенную плату вы можете перепоручить разметку вашего датасета другим людям. С другой стороны, вы точно хотите, чтобы ваш бот лайкал чудесных луноликих азиаток или не менее прекрасных девушек с индийскими корнями? Все-таки модель должна отражать именно ваш вкус.

С разнообразием проблем особо нет, все фотографии представлены в разнообразных ракурсах и освещении. В очках, платьях, купальниках и лыжных костюмах. Проблема может возникнуть с равномерностью датасета. В идеале, когда мы разметим нашу выборку, она должны состоять из приблизительно равных частей. Если у вас получился «перекошенный» датасет, то его придется разбавлять фотографиями из других источников. Более симпатичных надо будет добавить или наоборот вы определите по результату разметки. У меня получилось что-то в районе 60% симпатичных. То ли я не слишком разборчив, то ли мне просто повезло и вокруг много симпатичных девушек.

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

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

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

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

Как клеить по 13 девушек в час, используя машинное обучение и Tinder
Более подробно это описано в мануале к OpenCV

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

Как клеить по 13 девушек в час, используя машинное обучение и Tinder
Источник

У людей Hue параметр в цвете кожи не привносит значимого вклада в оценку симпатичности.
Поэтому, стоит упросить работу нейросети и оставить только grayscale.

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

Сразу хочу сказать, что без хорошей видеокарты и CUDA вы скорее всего просто не получите обученную модель в адекватные сроки. Поэтому сразу нацеливайтесь на расчеты в специализированных облаках или с использованием python-CUDA.

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

model = Sequential()
model.add(Convolution2D(32, 3, 3, activation='relu', input_shape=(img_size, img_size, 3)))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Convolution2D(32, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Convolution2D(64, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
          
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

adam = optimizers.SGD(lr=1e-4, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer= adam,
              metrics=['accuracy'])

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

Запускаем бота

Как клеить по 13 девушек в час, используя машинное обучение и Tinder

Спасибо автору репозитория за готовый вариант для быстрой проверки идеи. На самом деле вполне себе работает в базовом варианте и можно, в принципе, запустить на нашем готовом арендованном сервере. Обучать пока не получится, на данный момент мы не предоставляем виртуальные машины с поддержкой CUDA для расчетов, но запустить что-то на 24/7 работу можно без проблем. Бот довольно легковесный, поэтому выгоднее будет взять тариф с оплатой за использованные ресурсы.

Результаты

Как клеить по 13 девушек в час, используя машинное обучение и Tinder
Наверное я очень симпатичный. И у меня богатый внутренний мир. Получил что-то в районе 13 совпадений в течение часа. Причем, несколько раз девушки писали первыми.
В итоге получались весьма милые диалоги, где я рассказывал, что зашел исключительно поиграть с машинным обучением и разметкой данных. Одна из девушек крайне заинтересовалась, так как сама разработчик. Есть стойкое ощущение, что она в итоге прочитает этот пост на Хабре. Я очень надеюсь, что Оксана сохранит мою анонимность. 🙂
*машет лапой и передает привет

Немного про этическую сторону вопроса

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

Вокруг лето. Пора знакомиться.

Как клеить по 13 девушек в час, используя машинное обучение и Tinder

Как клеить по 13 девушек в час, используя машинное обучение и Tinder

Источник: habr.com