Цены на жильё формируются из многочисленных факторов, основные из которых — это близость к центру города и наличие рядом различной инфраструктуры. Но реальные цены только в бумажных газетах и риэлторских сайтах. Мы будем строить свою карту с ценами на недвижимость в Москве при помощи python, яндекс API и matplotlib, специальный репортаж с места событий под катом.
Гипотеза
Как человек, не проживающий в москве, характер цен в москве оцениваю следующим образом:
- очень дорого — в пределах садового кольца
- дорого — от садового кольца до ТТК
- не очень дорого — между ТТК и МКАД, а цена линейно убывает в сторону МКАДа
- дешево — за МКАДом
На карте будут присутствовать локальные максимумы и минимумы в связи с близостью важных объектов или промышленных зон. А также будет разрыв в ценах до МКАДа и после, т.к. это кольцо в основном совпадает с административной границей города.
Сотни строчек великолепного и не очень python-кода будут доступны в конце статьи по ссылке.
Для исследований я взял два сайта о недвижимости с данными за лето этого года. Всего в выборке участвовали 24,000 записей о новостройках и вторичном жилье, причём разные объявления с одним адресом усреднялись по цене.
Объявления парсились скриптом и хранились в sqlite базе данных в формате:
широта, долгота, цена за кв.м.
Строим функцию
Для обобщения функции на всю плоскость её необходимо проинтерполировать по имеющимся точкам. Для этого подойдёт функция
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.
Стоит заметить, что метод линейной интерполяции не может делать расчёт значений за пределами граничных точек. Тем самым на графике с достаточном большим масштабом мы увидим оченьмногоугольник. Масштаб необходимо выбрать таким образом, чтобы график был полностью вписан в получившуюся фигуру.
Другим взглядом на статистику может послужить карта с областями низких и высоких цен. Динамически варьируя границу разбиения на низкие и высокие цены мы сможем увидеть положение цен в динамике. Значение цены в каждой точке уже не будет играть роли, вклад вносит только кучность точек той или иной группы (кликабельно).
Расчёты похожи на расчёт гравитационного поля в точке. Для оптимизации будем брать в расчёт только те точки, которые действительно вносят вклад в конечное значение поля. После расчётов, результат напоминает брызги (кликабельно).
Визуализация
Совмести полученные изображения со схематичной картой Москвы. Яндекс API позволяет взять карту по координатам и указать для неё угловые размеры по долготе и широте, а так же желаемый размер изображения.
Пример запроса:
http://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.
Комментарии (25)
VBart
31.08.2015 12:45+4Вдруг кому пригодится: карта цен на недвижимость в Москве от ЦИАН и исследование Яндекса на эту же тему.
dprotopopov
05.09.2015 11:37Спасибо!
А данные более точно на какую дату?
сейчас кризис — было бы интересно и в динамике посмотреть
AWSVladimir
31.08.2015 13:59Без разреза по категориям жилья?
Странное сравнение.ajaxtpm
31.08.2015 20:32Какие категории жилья вы сочли бы интересными для рассмотрения? Для подсчёта средней цены по району вполне хватает стоимости за квадратный метр.
novoselov
31.08.2015 21:55+1Как минимум стоит сделать несколько слоев, например: хрущевки, сталинки, панельки, монолит, современный кирпич.
Думаю картина будет более плавной. И да, без cian'а данные не релевантны.
encyclopedist
31.08.2015 14:08+3Личейная интерполяция по триангуляции — плохой метод для шумных данных. Необходимо делать какую-то фильтрацию. В отчёте яндекса они поделили карту на клеточки и в каждой клеточке посчитали медиану. На карте ЦИАНА не написана точная методика, но по-видимому они нарисовали по кружочку в каждой точке данных. Если есть желание получить более гладкую функцию, то можно использовать RBF или подобные.
ComodoHacker
31.08.2015 19:47поделили карту на клеточки и в каждой клеточке посчитали медиану
Именно, это называется регуляризация. После нее можно хоть поля рисовать, хоть изолинии. Только простой медианой тут не отделаешься, бывают сложные случаи. Хорошие алгоритмы регуляризации до сих пор тема для исследований.encyclopedist
31.08.2015 19:54Ещё имеет смысл размер клеточек менять в зависимости от плотности данных. И вы правы, это сама по себе большая тема.
Ascott
31.08.2015 14:25+10Я бы оценил стоимость жилья так:
очень дорого — Москва (даже за МКАДом);
дорого — Санкт-Петербург;
не очень дорого — остальные города миллионники;
и дешево — остальная Россия.MacIn
31.08.2015 14:38+1Это некорректно, т.к. цены по Питеру и Москве пересекаются.
Ascott
31.08.2015 15:51Возможно неправильно, но забавно: В Москве реклама в метро (где-то два года назад): «Всего 7 миллионов ...», в Питере «Всего 2 миллиона ...». Речь об однокомнатных квартирах.
MacIn
31.08.2015 18:31В СПБ можно и рекламу студии за 1.5 увидеть и однушки за 1.7.
Только такие рекламы частенько — надувательство. Ну, например, пишут «квартира в городе, метро такое-то». А внизу мелко «городская прописка», потому что на деле квартира не в городе, а за городом, и от этого метро еще на наземке ехать over9000 минут. Или объявления о сдаче квартиры на Авито (знающие СПБ оценят) «метро Автово.........» в конце «Красное село».
ajaxtpm
31.08.2015 16:30В Санкт-Петербурге всё-таки дешевле раза в 1,5-2.
MacIn
31.08.2015 18:25Я сказал «пересекаются», а не равны. Разбиение же было предложено без деления на категории, просто «в МСК дорого, в СПБ дешевле». Я и отмечаю, что цены на, условно, трешку в СПБ и однушку в МСК пересекаются.
artyums
31.08.2015 22:10В таком случае можно сказать и о пересечении цен с «остальными городами-миллионниками», только там рассматривать какую-нибудь пятикомнатную или двухэтажную квартиру. Но, ведь, согласитесь, что это будет некорректно.
MacIn
31.08.2015 22:24В принципе, вы правы. Только таких квартир — раз два и обчелся, а массовый сегмент не пересекается.
Rumlin
31.08.2015 15:13есть исключения из категорий — Сочи, например. Спрос не всегда зависит от количества постоянно проживающего в этом месте населения. А еще есть очень индивидуальное жилье на берегу моря с собственным виноградником, например.
Chikey
01.09.2015 08:48>очень дорого — Москва (даже за МКАДом);
с рублем по 70, цены на любые квартиры меньше $2000 — курам на смех
Moskus
01.09.2015 04:38+1Как-то вы мучительно решили вопрос с подложкой карты.
Воспользовавшись вот этим www.gdal.org/frmt_wms.html (ищите пример по строке «OpenStreetMap TMS Service Example») можно скачать картинку карты любого стиля отображения OpenStreetMap по точным координатам границ (они будут в проекции Меркатора вот в этой системе координат spatialreference.org/ref/epsg/popular-visualisation-crs-mercator ).
dna1983
02.09.2015 09:13Красногорск почему-то слишком красный вышел, прям как центр Москвы :) На северной стороне Волоколамки насколько знаю ничего необычного нету. А вот южнее, вдоль реки — там дворцы. Видимо карта сползла немного.
Sellec
А цель сиих усилий?