Пользователь
0,0
рейтинг
31 августа 2015 в 11:24

Разработка → Стоимость жилья как функция координат из песочницы


Цены на жильё формируются из многочисленных факторов, основные из которых — это близость к центру города и наличие рядом различной инфраструктуры. Но реальные цены только в бумажных газетах и риэлторских сайтах. Мы будем строить свою карту с ценами на недвижимость в Москве при помощи python, яндекс API и matplotlib, специальный репортаж с места событий под катом.

Гипотеза


Как человек, не проживающий в москве, характер цен в москве оцениваю следующим образом:
  • очень дорого — в пределах садового кольца
  • дорого — от садового кольца до ТТК
  • не очень дорого — между ТТК и МКАД, а цена линейно убывает в сторону МКАДа
  • дешево — за МКАДом

На карте будут присутствовать локальные максимумы и минимумы в связи с близостью важных объектов или промышленных зон. А также будет разрыв в ценах до МКАДа и после, т.к. это кольцо в основном совпадает с административной границей города.

Сотни строчек великолепного и не очень python-кода будут доступны в конце статьи по ссылке.

Для исследований я взял два сайта о недвижимости с данными за лето этого года. Всего в выборке участвовали 24,000 записей о новостройках и вторичном жилье, причём разные объявления с одним адресом усреднялись по цене.

Объявления парсились скриптом и хранились в sqlite базе данных в формате:
широта, долгота, цена за кв.м.


О веб пауках
Да, из-за недостатка знаний, никаких сторонних библиотек не было использовано и это повлекло за собой создание двух отдельных скриптов по одному на каждый сайт, дёргающих адреса, метраж и стоимость квартир. Адреса волшебным образом превращались в координаты посредством Google Geocoder API. Но из-за довольно низкой планки квоты на использование был вынужден запускать скрипт каждый день в течении недели. Геокодер яндекса в 10 раз бесплатнее .


Строим функцию


Для обобщения функции на всю плоскость её необходимо проинтерполировать по имеющимся точкам. Для этого подойдёт функция LinearNDInterpolator из модуля scipy. Для этого только необходимо установить python с наобором научных библиотек, известный как scipy. В случае, когда данные очень разнородны, практически невозможно подобрать правдоподобную функцию на плоскости. Метод LinearNDInterpolator использует триангуляцию Делоне, разбивая всю плоскость на множество треугольников.

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

А тем временем, результат интерполяции выглядит как градиентный ад (кликабельно):



Чтобы получить удобную для восприятия карту, нужно распределить полученные значения на дискретные уровни. После чего карта становится похожей на страничку из атласа за 7й класс (кликабельно):



О дискретизации на карте
В зависимости от того, хотим мы видеть общую картину цен или флуктуации вблизи среднего значения, необходимо применить компадирование данных, т.е. распределение данных равномернее на шкалу значений, уменьшая больше значения и увеличивая маленькие. В коде это выглядит так:
    zz = np.array(map(lambda x: map(lambda y: int(2*(0.956657*math.log(y) - 10.6288)) , x), zz)) #HARD    
    zz = np.array(map(lambda x: map(lambda y: int(2*(0.708516*math.log(y) - 7.12526)) , x), zz)) #MEDIUM  
    zz = np.array(map(lambda x: map(lambda y: int(2*(0.568065*math.log(y) - 5.10212)) , x), zz)) #LOW  

Функции подбирались эмпирическим путём при помощи аппроксимации по 3м-4м точкам на wolframalpha.


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

Другим взглядом на статистику может послужить карта с областями низких и высоких цен. Динамически варьируя границу разбиения на низкие и высокие цены мы сможем увидеть положение цен в динамике. Значение цены в каждой точке уже не будет играть роли, вклад вносит только кучность точек той или иной группы (кликабельно).



Расчёты похожи на расчёт гравитационного поля в точке. Для оптимизации будем брать в расчёт только те точки, которые действительно вносят вклад в конечное значение поля. После расчётов, результат напоминает брызги (кликабельно).



Какое ещё преобразование?
При строгом построении графика поля, на нём видно россыпь точек, соответствующих локальному преобладанию “дорогого” поля над “недорогим” и наоборот. Эти точки похожи на шум и портят график. Убрать их можно, например, медианным фильтром над изображением с достаточном большим значением. Для этого я использовал командный интерфейс программы IrfanView.


Визуализация


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

Пример запроса:
static-maps.yandex.ru/1.x/?ll=37.5946002,55.7622764&spn=0.25,0.25&size=400,400&l=map


Проблема заключается только в том, что указанные угловые размеры определяют не границы видимой области, а её гарантируемый размер. Это значит, что мы получим картинку с угловыми размерами >= 0.25. Способа совладать с границами видимых координат обнаружено не было, и они искались вручную.

О подгониане
Выровнять карты друг относительно друга можно при помощи яндекс меток, рисуя точки на карте с заданными координатами и получая карту с метками.

За пару вызовов из библиотеки PIL изображения совмещаются с комфортными для наблюдения уровнями прозрачности.

map_img = Image.open(map_img_name, 'r').convert('RGBA')
price_img = Image.open(prices_img_name, 'r').convert('RGBA')
if price_img.size == map_img.size:
    result_img = Image.blend(map_img, price_img, 0.5)


Результаты


Три изображения с разными уровнями компандирования и анимация варианта с полем.



Немного аналитики:

В целом, как и предсказывала гипотеза, внутри садового кольца и кольца ТТК цены на жильё максимальны и убывают по мере удаления от центра. Однако в пределах МКАД, средняя цена сохраняется в западной и юго-западной частях. За пределами МКАД, а так же в восточной части за ТТК цена ниже средней.

В деталях всё намного интересней, отметим основные области:
  • В лужниках и воробьёвых горах жить довольно дорого жилой недвижимости в области воробьёвых гор нет, скорее все область была построена по граничным значениям сверху и снизу
  • Жилые массивы вблизи фундаментальной библиотеки МГУ, строящиеся и построенные высотки у мосфильмовского пруда стоят дороже предположительно из-за активной стройки и обширных лесопарковых участков. Высокая цена на территории от мемориальной синагоги и сквером им. Анны Герман так же обусловлена окружающими ценами и своим местоположением среди парков и заказника.
  • В районе между станцией метро “Крылатское” и проспектом Маршала Жукова жильё так же считается дорогим
  • Несмотря на положение за МКАДом и близостью к кладбищу, дома вдоль улицы Генерала Белобородова отличаются высокой ценой.

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

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

Код веб пауков, самой программы, а так же использованные базы данных доступны через GitHub.
@ajaxtpm
карма
28,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • +5
    А цель сиих усилий?
  • +4
    • +1
      Спасибо!
    • 0
      Спасибо!
      А данные более точно на какую дату?
      сейчас кризис — было бы интересно и в динамике посмотреть
  • +2
    А почему cian.ru решили не парсить? Он раз в 10 больше по трафику, чем sob.ru и realto.ru.
    • +1
      cian.ru ускользнул от моего внимания. А ведь база там хорошая, соглашусь
      карта цен правда там только за 2013 год, у меня посвежее данные.
  • 0
    Без разреза по категориям жилья?
    Странное сравнение.
    • 0
      Какие категории жилья вы сочли бы интересными для рассмотрения? Для подсчёта средней цены по району вполне хватает стоимости за квадратный метр.
      • +1
        Как минимум стоит сделать несколько слоев, например: хрущевки, сталинки, панельки, монолит, современный кирпич.
        Думаю картина будет более плавной. И да, без cian'а данные не релевантны.
  • +3
    Личейная интерполяция по триангуляции — плохой метод для шумных данных. Необходимо делать какую-то фильтрацию. В отчёте яндекса они поделили карту на клеточки и в каждой клеточке посчитали медиану. На карте ЦИАНА не написана точная методика, но по-видимому они нарисовали по кружочку в каждой точке данных. Если есть желание получить более гладкую функцию, то можно использовать RBF или подобные.
    • 0
      поделили карту на клеточки и в каждой клеточке посчитали медиану

      Именно, это называется регуляризация. После нее можно хоть поля рисовать, хоть изолинии. Только простой медианой тут не отделаешься, бывают сложные случаи. Хорошие алгоритмы регуляризации до сих пор тема для исследований.
      • 0
        Ещё имеет смысл размер клеточек менять в зависимости от плотности данных. И вы правы, это сама по себе большая тема.
  • +10
    Я бы оценил стоимость жилья так:
    очень дорого — Москва (даже за МКАДом);
    дорого — Санкт-Петербург;
    не очень дорого — остальные города миллионники;
    и дешево — остальная Россия.
    • +1
      Это некорректно, т.к. цены по Питеру и Москве пересекаются.
      • 0
        Возможно неправильно, но забавно: В Москве реклама в метро (где-то два года назад): «Всего 7 миллионов ...», в Питере «Всего 2 миллиона ...». Речь об однокомнатных квартирах.
        • 0
          В СПБ можно и рекламу студии за 1.5 увидеть и однушки за 1.7.
          Только такие рекламы частенько — надувательство. Ну, например, пишут «квартира в городе, метро такое-то». А внизу мелко «городская прописка», потому что на деле квартира не в городе, а за городом, и от этого метро еще на наземке ехать over9000 минут. Или объявления о сдаче квартиры на Авито (знающие СПБ оценят) «метро Автово.........» в конце «Красное село».
      • 0
        В Санкт-Петербурге всё-таки дешевле раза в 1,5-2.
        • 0
          Я сказал «пересекаются», а не равны. Разбиение же было предложено без деления на категории, просто «в МСК дорого, в СПБ дешевле». Я и отмечаю, что цены на, условно, трешку в СПБ и однушку в МСК пересекаются.
          • 0
            В таком случае можно сказать и о пересечении цен с «остальными городами-миллионниками», только там рассматривать какую-нибудь пятикомнатную или двухэтажную квартиру. Но, ведь, согласитесь, что это будет некорректно.
            • 0
              В принципе, вы правы. Только таких квартир — раз два и обчелся, а массовый сегмент не пересекается.
    • +2
      И одинаково недоступна для жителей любого города.
    • 0
      есть исключения из категорий — Сочи, например. Спрос не всегда зависит от количества постоянно проживающего в этом месте населения. А еще есть очень индивидуальное жилье на берегу моря с собственным виноградником, например.
    • 0
      >очень дорого — Москва (даже за МКАДом);

      с рублем по 70, цены на любые квартиры меньше $2000 — курам на смех
  • +1
    Как-то вы мучительно решили вопрос с подложкой карты.
    Воспользовавшись вот этим www.gdal.org/frmt_wms.html (ищите пример по строке «OpenStreetMap TMS Service Example») можно скачать картинку карты любого стиля отображения OpenStreetMap по точным координатам границ (они будут в проекции Меркатора вот в этой системе координат spatialreference.org/ref/epsg/popular-visualisation-crs-mercator ).
  • 0
    Красногорск почему-то слишком красный вышел, прям как центр Москвы :) На северной стороне Волоколамки насколько знаю ничего необычного нету. А вот южнее, вдоль реки — там дворцы. Видимо карта сползла немного.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.