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

У меня была неделя на эксперименты, наши движки анализа данных,16 тысяч русских романов и повестей XIX века и 15 тысяч современных длинных произведений. И, конечно, не было никаких размеченных данных.

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

Вот визуализация того, что получилось. Точнее, одного из распространённых вариантов.


Цвет глаз, волос, платье, рост, воспитание — всё это можно выделить из корпуса текстов.

Конечно, не всё так просто и однозначно как на рисунках, но примерное представление вы уже получили. Теперь давайте расскажу про детали и последовательность действий.

Корпус текстов


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

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

Весь анализ я делала на связке SAS Visual Text Analytics и питоновских библиотек (pymorphy2, gensim, tensorflow).

Шаг 1. Лингвистические правила


Итак, сначала нужно было выделить фрагменты с описаниями женской внешности. Размеченных данных не было, поэтому я начала с простых правил в духе «девушка AND (глаза OR волосы OR лицо)». Правила писала в SAS Visual Text Analytics, так что они учитывали морфологические формы, опечатки (для современного корпуса было актуально), простой синтаксис, расстояние между токенами и фильтровали нежелательные контексты.

Упрощённое правило
PREDICATE_RULE:(arg1, arg2, arg3): (UNLESS, «bad_contexts», (SENT_5, "_arg1{beauty}", "_arg2{woman}", "_arg3{traits}"))

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

Написать такое правило несложно, проблема в деталях. Как, например, собрать все возможные упоминания женщин? Ведь в тексте это может быть и «барыня», и «девчуля», и «Маргарита», и «кузина». Простыми синонимами здесь не обойтись, ни один словарь не выдаст «машинистку» или «студентку» как синоним к «женщине». Можно перечислять «из головы», пока хватает фантазии, но список будет неполный (да и скучно это).

Для расширения правил и поиска контекстных синонимов подключаем векторные представления.

Шаг 2. Модель word2vec


Word2vec — инструмент векторизации слов, который основывается на идее «скажи мне, кто стоит рядом с тобой, и я скажу, кто ты». Например, в предложении «я ___ её с первого взгляда» большинство заменили бы пропуск на слово типа «полюбил». Идея простая — похожие слова встречаются в схожих контекстах. Для русского языка есть готовые предобученные модели, которые размещены здесь. Опыт на проектах показывает, что модели, обученные на корпусе предметной области, работают лучше, чем модели «для всего языка», поэтому я обучила две модели на своих корпусах.

Сначала корпуса питоном разбила на слова, привела слова к начальной форме (спасибо pymorphy2), извлекла частотные многословные выражения типа двоюродная сестра, львиная грива, осиная талия (спасибо phrases из gensim). На обработанных данных обучила модель word2vec (алгоритм skipgram, окно — 3, размерность — 300).

С помощью обученной модели итеративно составила списки похожих слов. Функция most_similar в gensim принимает на вход слово и возвращает список слов/выражений, вектора которых близки по косинусной мере вектору исходного слова.

Векторы, близкие вектору слова «красавица» на корпусе XXI века. Второе значение — косинусная мера.
('красотка', 0.6690341234207153)
('хорошенький', 0.6438576579093933)
('очаровательный', 0.6156517267227173)
('умница', 0.6063219308853149)
('красавец', 0.6044491529464722)
('девчушка', 0.5829722285270691)
('синеглазый', 0.5814758539199829)
('барышня', 0.5773882865905762)
('принцесса', 0.5754760503768921)
('светленький', 0.5743755102157593)
('белокурый', 0.5731547474861145)
('голубоглазый', 0.5724368095397949)

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

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

Женщины XIX века:
Катерина
Катя
Клавдия
Клотильда
княгиня
княжна
кокетка
компаньонка
кормилица
красавица
крестьянка
кружевница
кузина
куколка
кумушка
купчиха
кухарка

Женщины XXI века:
Карен
Карина
кассирша
Катерина
Катрина
Катька
Катя
квартирантка
Кира
Клара
клиентка
кокетка
комсомолка
королева
красавица
красотка
Кристина
Ксения
Ксюша
кузина

Тот же принцип использовала для расширения остальных правил.

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

Шаг 3. Нежелательные контексты


Итак, у меня длинные подробные правила, которые довольно удачно ловят описание внешности, упоминание женщины и упоминание факта её привлекательности. Прописываю в лингвистических правилах очевидные ограничения: нужно учесть отрицания, модальность, условное наклонение, чтобы не поймались контексты типа «не отличалась красотой», «далеко не красавица».

Вот такое нам не нужно.
В юности была совсем не красавицей, а довольно упитанной девушкой с широким утиным носиком. Очень она из-за своего носика переживала, и по рассказам сестёр, нередко спала с деревянной защипкой для белья на носу, чтобы его таким образом сузить.
П. Ребенина, «Несчастная Зинка».

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

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

Примеры разбора, полужирным выделен контекст, подчёркиванием — факты о внешности. Кроме некоторых. А эта ссылка тоже не ссылка и не кликается!
Алина всё-таки была и из другого круга, и вообще вся другая. Она была очень красивая: брюнетка с серо-голубыми глазами, покатым лбом, аккуратным носиком, точёным личиком, тонкими запястьями, на которых болтались самые стильные фенечки, которые я когда-либо видела в жизни. Она была выше меня на голову, фигура у неё была… ну, без шуток, классная.
К. Белозёрова, «Друг, которого нет».

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

В ней было нечто таинственное и притягательное, она была стройна и хороша собой. Длинные, слегка вьющиеся светлые волосы, правильные черты лица, очень живые голубые глаза делали Лену очаровательной. Борису нравились её озорная улыбка, чувственный рот, её веселость. Ему казались неотразимо привлекательными и внешность её, и манера держаться.
А. Большаков, «Изгой».

Это была очень красивая женщина с резкими чертами лица, острым носом и точёным подбородком, звали её не менее эффектно — Аделаида. Она вышла встречать меня в длинном ярко-зелёном платье, а на груди её и руках висели многочисленные какие-то диковинные этнические украшения. «Можно просто Ида», — приветливо сказала она, и уголки её тонкого рта несимметрично разъехались в стороны. «Какая красавица с изюминкой!», — подумала я.
О. Павленко, «Байка о ведьмах».

У дверей соседней комнаты стояла молодая женщина со свечой в руках… Я взглянул и изумился — такая она была красивая в белом капоте, с распущенными по плечам волосами. Что за прелестные черты, несмотря на то, что они были искажены гневом! Голубые глаза с расширенными зрачками блестели зловещим блеском… Фигура стройная, гибкая.
К. Станюкович, «Оригинальная пара».

И Якову было за что любить свою молодуху: баба — работящая, не пустомеля, не слезомоя, женщина здоровая и красивая. Лицо у неё продолговатое, с прямым, тонким носом и с пухлыми, алыми губами. Её голубые глаза весело и открыто смотрят на белый свет. А над ними, словно кисточкой, проведены тёмные брови. Густой румянец играет на её загорелых щеках.
П. Засодимский, «От сохи к ружью».

Шаг 4. Сборка результата


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

Первые два варианта типажа:


Дама XIX века VS дама XXI века.

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

Второй типаж. С этой картинкой вы уже знакомы:



Было: молоденькая нежная брюнетка с голубыми глазами, которая тепло улыбается. Большое внимание уделено аккуратным тонким пальцам. Она задумчива, кротка, уступчива, даже застенчива. Часто она смотрит из-за локона. Современная красавица будет отличаться. Голубые глаза — всё ещё признак красоты наряду с чёрными, но появляются зелёные глаза, которых раньше вообще не было. Получается молоденькая, зеленоглазая, рыжая (это тоже совершенно новый признак!) девушка, с хорошим макияжем, ещё она стройна, высока, носит лёгкое светлое платье. Она оптимистична, спокойна и умна.

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

Зачем это всё?


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

Ну или могу просто посмотреть в текстах что угодно. Проанализировать описания домов и интерьеров. Найти побочные эффекты на лекарства. Выяснить, что вафли хрустят как-то не так, а сахар в печенье недостаточно сладкий. Узнать, что блондинки всё-таки почти в два раза популярнее брюнеток, а голубые глаза не выходят из моды. И так далее…

А вот практическое применение: как мы искали признаки врачебных ошибок.