Проектная задача
Яндекс.Недвижимость — это сервис объявлений о продаже и съёме квартир, комнат, домов, участков. Объявления размещают частные лица, компании-застройщики или агентства, поэтому один и тот же объект недвижимости часто бывает представлен несколькими офферами. Чаще всего квартиру пытаются продать сразу несколько агентств, а иногда ещё и собственник.
Дубликаты просмотренных объявлений в лучшем случае раздражают пользователей, в худшем — вводят в заблуждение. Ещё это мешает команде Яндекса собирать аналитику по квартирам и считать, сколько точно продаётся или сдаётся. Поэтому хочется научиться искать и склеивать дубликаты в один оффер.
Поток объявлений невозможно модерировать вручную, потому что он огромный. Значит, нужен алгоритм, который способен с высокой точностью находить как можно больше дубликатов. Точность важна, потому что цена ошибки высокая: склеивание разных объявлений приведёт к тому, что пользователи будут жаловаться.
Задачи с такими высокими требованиями и сложной структурой данных традиционно решают с помощью алгоритмов машинного обучения, поэтому в реальности задача была сформулирована как «Обучение одного из state-of-the-art классификаторов».
Проблемы
- Предметная область — новая для нас, там есть свои сложности и особенности.
- Размеченных данных нет совсем.
- Нет задачи машинного обучения в явном виде — что здесь будет факторами и целевыми переменными?
С последним пунктом всё относительно просто: факторами будет информация о паре объектов из разных объявлений, а целевой переменной — то, один это объект в реальности, или два разных. А вот выяснение особенностей рынка недвижимости и разметка данных заняли большую часть проектного времени.
Разметка данных
Мы получили часть базы данных с офферами о продаже квартир в Москве. Основные данные, которые их описывают, такие:
- Общие структурированные данные — метраж, цена, этаж, число комнат, санузлов, высота потолков, мета-информация о продавце и другие.
- Текстовое описание объекта.
- Фотографии объекта.
В Яндексе до нас был классификатор дубликатов, обученный на факторах из 1 пункта без контрольных данных. Это алгоритм кластеризации офферов, который называл дубликатами офферы, попавшие в один кластер. Он имел достаточно высокую точность, но сравнительно низкую полноту. Это значит, что доля дубликатов, которые он обнаруживал, была низкой, хоть и ошибался он довольно редко.
Мы использовали идею сравнения офферов между собой на основании разностей и отношений основных показателей: например, цены или этажа, чтобы получить эмпирическую метрику непохожести объявлений. И придумали функцию, которая сопоставляла двум офферам единственное число — меру того, насколько два объявления отличаются по первичным данным. Этот показатель помог нам при разметке данных создать сбалансированную выборку и хотя бы примерно регулировать распределение примеров: хочется нам больше одинаковых, или сильно разных, или сложных примеров где-то посередине.
Разметка оказалась намного более сложным занятием, чем мы предполагали. И вот почему:
- Одинаковые и не информативные описания похожих объектов. Особенно из нового фонда: компании-застройщики заносят их пачками, и лишь в редких случаях их можно отличить по номеру лота.
- Намеренное искажение данных. Специалисты по недвижимости объяснили нам, что иногда люди хотят скрыть реальный этаж или внешний вид квартиры.
- Не информативные экстерьерные или похожие фотографии объектов.
- Разные фотографии одного и того же объекта. Ниже — один из несложных примеров, однако в некоторые фото приходится долго вглядываться подобно сыщику, применяя всю мощь дедуктивного метода с единственной целью — решить, одна это квартира или две разных.
Supervised baseline
Мы разметили данные и попробовали обучить Random Forest только на факторах из первого пункта — категориальных и непрерывных показателях цены, метража, и т.д. В качестве предикторов выступали разности и отношения этих факторов, а также дополнительно сконструированные факторы на основании времени размещения и обновления, информации о продавце и т.д. На тестовых данных этот классификатор был точнее консервативного алгоритма кластеризации на 5-8%, а его полнота превысила предыдущий результат на 30-35%.
Воодушевленные этим результатом, мы обратились к двум другим факторам — текстовому описанию и картинкам. С последними поработать почти не удалось: мы выгрузили их довольно поздно. Пробовали использовать в качестве дополнительных факторов хэши для отсеивания общих экстерьерных фотографий, перцептивные хэши для борьбы с водными метками и выходы высоких слоев сверточных сетей (ResNet-18), однако, к нашему удивлению, не получили сильный прирост к точности.
На наш взгляд, к анализу изображений в этой предметной области нужно подойти ещё более основательно, уделить много внимания препроцессингу изображений, попробовать другие архитектуры и специальные функции потерь. К лемматизированным и векторизованным текстовым данным был применен алгоритм Tf-Idf векторизации и использовано векторизованное представление как первичные признаки. Разные метрики над этими векторами давали более внушительный прирост к качеству предсказаний. Лучший результат в качестве фактора дала вероятность, предсказанная отдельно обученной на этих векторах логистической регрессией.
Финальная модель
Финальной моделью, которая агрегировала все признаки и выходы других, стал CatBoost. Это продукт Яндекса, обученный со специальной функцией потерь — модифицированной F-мерой. Технология CatBoost зарекомендовала себя как одна из лучших в задаче классификации и легко интегрировалась в инфраструктуру. Качество работы алгоритма на тестовой выборке — 98% точности и 93% полноты.
Мы считаем это хорошим результатом, а является ли он таким же с точки зрения бизнеса — решат специалисты из отдела маркетинга :)
Комментарии (7)
akryukov
24.06.2019 20:32При чем тут хаб "учебный процесс в IT"?
katyateria Автор
24.06.2019 20:53Добавила, потому что это рассказ об учебной практике в CS центре. Пересмотрела посты в хабе — вы правы, поправила)
sshikov
24.06.2019 21:04+2Мы анализировали такие же объявления из других источников, и что могу сказать:
— зачастую данные не заполнены. В нашем случае, например, этаж зачастую можно было извлечь только из текстового комментария, что является само по себе нетривиальной задачей NLP
— даже если заполнены, то например, наличие двух и более одинаковых объектов, со всеми совпадающими параметрами, является вполне возможным вариантом. Например, две квартиры одинакового метража в одном доме, на одном этаже, два офисных помещения в одном офисном центре. При этом нет буквально никаких признаков, которые позволяли бы считать эти объявления дублями, или же нет. Точнее, есть — номер квартиры или офиса, например. Но его почти никогда не бывает в объявлении (потому что опубликуй его — и посредники в виде сайта уже и не нужны).
— идентичные по всем параметрам объекты могут все еще сильно отличаться по цене, в лучшем случае причина для такого отличия описана в тексте (и тогда снова NLP, да и то задача плохо формализуется, потому что описание ремонта, оно такое...), а в худшем — не описана вообще нигде. Типовой пример — торговые площади в ТЦ, где размещение на этаже является одним из показателей, влияющих на ставку аренды.
— некоторые параметры вполне можно додумать или валидировать, если мы знаем характеристики здания, например, то же число этажей в нем, или класс офиса, или проект дома — на основе этого можно вычислить многое, а зная адрес, теоретически можно понять вообще все.
— и тем не менее, даже если вы знаете, что в таком-то ТЦ сдаются две торговые площади с одинаковыми параметрами, а у вас имеется три объявления, вряд ли что-то вам позволит понять, два тут дубля или же один.
А то, как задача тут описана, на мой взгляд вообще пока ни о чем.
nerudo
Frohman
Точность (precision) и полнота(recall) — стандартные метрики оценки качества. Precision= TruePositive/(TruePositive+FalsePositive), Recall = TruePositive/(TruePositive+FalseNegative)
love_camel_case
nerudo
То есть под одним «оффером» будут все три объявы каждая со своими контактами? Тогда хорошо.