Дедупликация объявлений на Яндекс.Недвижимости
Участники проекта
Руководитель
Проектная задача
Яндекс.Недвижимость — это сервис объявлений о продаже и съёме квартир, комнат, домов, участков. Объявления размещают частные лица, компании-застройщики или агентства, поэтому один и тот же объект недвижимости часто бывает представлен несколькими офферами. Чаще всего квартиру пытаются продать сразу несколько агентств, а иногда ещё и собственник.
Дубликаты просмотренных объявлений в лучшем случае раздражают пользователей, в худшем — вводят в заблуждение. Ещё это мешает команде Яндекса собирать аналитику по квартирам и считать, сколько точно продаётся или сдаётся. Поэтому хочется научиться искать и склеивать дубликаты в один оффер.
Поток объявлений невозможно модерировать вручную, потому что он огромный. Значит, нужен алгоритм, который способен с высокой точностью находить как можно больше дубликатов. Точность важна, потому что цена ошибки высокая: склеивание разных объявлений приведёт к тому, что пользователи будут жаловаться.
Задачи с такими высокими требованиями и сложной структурой данных традиционно решают с помощью алгоритмов машинного обучения, поэтому в реальности задача была сформулирована как «Обучение одного из state-of-the-art классификаторов».
Проблемы
- Предметная область — новая для нас, там есть свои сложности и особенности.
- Размеченных данных нет совсем.
- Нет задачи машинного обучения в явном виде — что здесь будет факторами и целевыми переменными?
С последним пунктом всё относительно просто: факторами будет информация о паре объектов из разных объявлений, а целевой переменной — то, один это объект в реальности, или два разных. А вот выяснение особенностей рынка недвижимости и разметка данных заняли большую часть проектного времени.
Разметка данных
Мы получили часть базы данных с офферами о продаже квартир в Москве. Основные данные, которые их описывают, такие:
- Общие структурированные данные — метраж, цена, этаж, число комнат, санузлов, высота потолков, мета-информация о продавце и другие.
- Текстовое описание объекта.
- Фотографии объекта.
В Яндексе до нас был классификатор дубликатов, обученный на факторах из 1 пункта без контрольных данных. Это алгоритм кластеризации офферов, который называл дубликатами офферы, попавшие в один кластер. Он имел достаточно высокую точность, но сравнительно низкую полноту. Это значит, что доля дубликатов, которые он обнаруживал, была низкой, хоть и ошибался он довольно редко.
Мы использовали идею сравнения офферов между собой на основании разностей и отношений основных показателей: например, цены или этажа, чтобы получить эмпирическую метрику непохожести объявлений. И придумали функцию, которая сопоставляла двум офферам единственное число — меру того, насколько два объявления отличаются по первичным данным. Этот показатель помог нам при разметке данных создать сбалансированную выборку и хотя бы примерно регулировать распределение примеров: хочется нам больше одинаковых, или сильно разных, или сложных примеров где-то посередине.
Разметка оказалась намного более сложным занятием, чем мы предполагали. И вот почему:
- Одинаковые и не информативные описания похожих объектов. Особенно из нового фонда: компании-застройщики заносят их пачками, и лишь в редких случаях их можно отличить по номеру лота.
- Намеренное искажение данных. Специалисты по недвижимости объяснили нам, что иногда люди хотят скрыть реальный этаж или внешний вид квартиры.
- Не информативные экстерьерные или похожие фотографии объектов.
- Разные фотографии одного и того же объекта. Ниже — один из несложных примеров, однако в некоторые фото приходится долго вглядываться подобно сыщику, применяя всю мощь дедуктивного метода с единственной целью — решить, одна это квартира или две разных.
Supervised baseline
Мы разметили данные и попробовали обучить Random Forest только на факторах из первого пункта — категориальных и непрерывных показателях цены, метража, и т.д. В качестве предикторов выступали разности и отношения этих факторов, а также дополнительно сконструированные факторы на основании времени размещения и обновления, информации о продавце и т.д. На тестовых данных этот классификатор был точнее консервативного алгоритма кластеризации на 5-8%, а его полнота превысила предыдущий результат на 30-35%.
Воодушевленные этим результатом, мы обратились к двум другим факторам — текстовому описанию и картинкам. С последними поработать почти не удалось: мы выгрузили их довольно поздно. Пробовали использовать в качестве дополнительных факторов хэши для отсеивания общих экстерьерных фотографий, перцептивные хэши для борьбы с водными метками и выходы высоких слоев сверточных сетей (ResNet-18), однако, к нашему удивлению, не получили сильный прирост к точности.
На наш взгляд, к анализу изображений в этой предметной области нужно подойти ещё более основательно, уделить много внимания препроцессингу изображений, попробовать другие архитектуры и специальные функции потерь. К лемматизированным и векторизованным текстовым данным был применен алгоритм Tf-Idf векторизации и использовано векторизованное представление как первичные признаки. Разные метрики над этими векторами давали более внушительный прирост к качеству предсказаний. Лучший результат в качестве фактора дала вероятность, предсказанная отдельно обученной на этих векторах логистической регрессией.
Финальная модель
Финальной моделью, которая агрегировала все признаки и выходы других, стал CatBoost. Это продукт Яндекса, обученный со специальной функцией потерь — модифицированной F-мерой. Технология CatBoost зарекомендовала себя как одна из лучших в задаче классификации и легко интегрировалась в инфраструктуру. Качество работы алгоритма на тестовой выборке — 98% точности и 93% полноты.
Мы считаем это хорошим результатом, а является ли он таким же с точки зрения бизнеса — решат специалисты из отдела маркетинга :)