В прошлом семестре студенты Computer Science центра Сергей Горбатюк и Пётр Кароль работали над дедупликацией объявлений на Яндекс.Недвижимости под руководством Владимира Горового, менеджера проекта. Ребята рассказали нам, как устроен проект, и каких результатов они достигли.

image


Проектная задача


Яндекс.Недвижимость — это сервис объявлений о продаже и съёме квартир, комнат, домов, участков. Объявления размещают частные лица, компании-застройщики или агентства, поэтому один и тот же объект недвижимости часто бывает представлен несколькими офферами. Чаще всего квартиру пытаются продать сразу несколько агентств, а иногда ещё и собственник.

Дубликаты просмотренных объявлений в лучшем случае раздражают пользователей, в худшем — вводят в заблуждение. Ещё это мешает команде Яндекса собирать аналитику по квартирам и считать, сколько точно продаётся или сдаётся. Поэтому хочется научиться искать и склеивать дубликаты в один оффер.

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

Задачи с такими высокими требованиями и сложной структурой данных традиционно решают с помощью алгоритмов машинного обучения, поэтому в реальности задача была сформулирована как «Обучение одного из state-of-the-art классификаторов».

Проблемы


  • Предметная область — новая для нас, там есть свои сложности и особенности.
  • Размеченных данных нет совсем.
  • Нет задачи машинного обучения в явном виде — что здесь будет факторами и целевыми переменными?

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

Разметка данных


Мы получили часть базы данных с офферами о продаже квартир в Москве. Основные данные, которые их описывают, такие:

  • Общие структурированные данные — метраж, цена, этаж, число комнат, санузлов, высота потолков, мета-информация о продавце и другие.
  • Текстовое описание объекта.
  • Фотографии объекта.

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

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

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

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


image

image

Supervised baseline


Мы разметили данные и попробовали обучить Random Forest только на факторах из первого пункта — категориальных и непрерывных показателях цены, метража, и т.д. В качестве предикторов выступали разности и отношения этих факторов, а также дополнительно сконструированные факторы на основании времени размещения и обновления, информации о продавце и т.д. На тестовых данных этот классификатор был точнее консервативного алгоритма кластеризации на 5-8%, а его полнота превысила предыдущий результат на 30-35%.

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

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

Финальная модель


Финальной моделью, которая агрегировала все признаки и выходы других, стал CatBoost. Это продукт Яндекса, обученный со специальной функцией потерь — модифицированной F-мерой. Технология CatBoost зарекомендовала себя как одна из лучших в задаче классификации и легко интегрировалась в инфраструктуру. Качество работы алгоритма на тестовой выборке — 98% точности и 93% полноты.

Мы считаем это хорошим результатом, а является ли он таким же с точки зрения бизнеса — решат специалисты из отдела маркетинга :)

Комментарии (7)


  1. nerudo
    24.06.2019 20:21

    1. Расшифруйте что значит 98% точности и 93% полноты. Иногда выкидывались не дубли?
    2. В случае дубля кого оставлять, а кого выкидывать?


    1. Frohman
      24.06.2019 20:37
      +1

      Точность (precision) и полнота(recall) — стандартные метрики оценки качества. Precision= TruePositive/(TruePositive+FalsePositive), Recall = TruePositive/(TruePositive+FalseNegative)


    1. love_camel_case
      24.06.2019 20:47
      +1

      1. Точность — это отношение числа правильно классифицированных офферов к общему числу объектов. То есть в 98% случаев пара, помеченная алгоритмом как дубликат, действительно является таковой. Отвечая на следующий вопрос — да, примерно в 2% случаев алгоритм ошибался, называя пару квартир одинаковыми, хотя они таковыми не являлись. Полнота здесь — это доля офферов, классифицированных правильно, деленная на размер всего класса дубликатов, то есть это число, показывающее насколько большую часть дубликатов алгоритм способен находить. Более формально можно почитать тут.
      2. Дубликаты не удаляются, просто с помощью некоторых эвристик объединяются в один оффер.


      1. nerudo
        24.06.2019 20:50

        То есть под одним «оффером» будут все три объявы каждая со своими контактами? Тогда хорошо.


  1. akryukov
    24.06.2019 20:32

    При чем тут хаб "учебный процесс в IT"?


    1. katyateria Автор
      24.06.2019 20:53

      Добавила, потому что это рассказ об учебной практике в CS центре. Пересмотрела посты в хабе — вы правы, поправила)


  1. sshikov
    24.06.2019 21:04
    +2

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

    А то, как задача тут описана, на мой взгляд вообще пока ни о чем.