В комментариях в одной из прошлых статей и на гитхаб писали что не обязательно жить близко к магазину, когда есть службы доставки. Вот с этим я могу поспорить - большая часть людей в России покупает продукты и товары в магазинах. В 90е были крайне популярны вещевые рынки и часто покупали одежду там потому что было дешевле. У многих студентов и пенсионеров их финансовая ситуация не располагает не то что платить за доставку курьером, но даже возможность купить хорошие продукты и одежду после квартплаты - это арифметика жизни. Им неосознанно приходится решать задачу коммивояжера в голове чтобы обойти несколько торговых точек и выгодно купить по заранее составленному списку покупок. Шаговая доступность магазинов все еще важна для жителей городов.
Как выбрать правильное место для открытия магазина и что нужно учесть
Его локация должна быть в удобном месте для потенциальных клиентов. Рядом с офисными зданиями, в туристическом или в жилом районе. Учитываются поток пешеходов, так и доступность общественного транспорта и парковок. И конечно учитывают целевую аудиторию: для магазинов детских товаров, лучше расположить в том районе где много семей с детьми и инфраструктуры для них.
Торговля требует выполнения стандартов безопасности и санитарии. Нужно быть уверенным что здание соответствует требованиям пожарной безопасности, санитарии и перепланировки торгового помещения узаконены. Помещение должно иметь достаточно места для товара и посетителей магазина. Хорошо бы найти профессионального юриста / агента по коммерческой недвижимости для помощи при заключения договора и решении юридических вопросов связанных с торговым помещением. Рекомендации + опыт эксперта поможет избежать лишних трат и распространенных ошибок при выборе здания.
Помимо арендной платы или стоимости покупки помещения, нужно заложить дополнительные расходы на ремонт, обслуживание помещений, зарплаты персонала, закупку товара и уплату налогов.
Как много в этом районе конкурентов? Кто целевая аудитория, где проживает или как часто посещает этот район?
Можно ли адаптировать здание при изменениях в бизнес-модели. Например решите сменить категорию товаров и что нужно будет учесть, что прийдется менять в торговом зале...
И это не все, а мы же сфокусируемся только на расположении и анализе пешеходной доступности магазинов и попрактикуемся в решении задачи - сколько человек сможет дойти до конкретного магазина: обычно люди предпочитаю покупать там где магазин ближе и где больше ассортимент товаров.
Специалисты, кто занимаются геоаналитикой профессионально для открытия новых магазинов, имеют доступ к большому объему часто платной информации: локации абонентов от операторов связи, платежных операторов и банков, доступ к подготовленным данным из ГИС ЖКХ/Реформа ЖКХ, и много еще к чему. Но они, как почтальон Печкин, вам их не дадут. И не дадут результат расчета на данных: дешево, быстро, качественно - выбирай любые два варианта.
Не претендую на академичность и точность моего субъективного исследования, лишь покажу вам как cамостоятельно рассчитать достижимость магазинов клиентами на основе свободных данных из OpenStreetMap. К счастью, для Москвы полнота и качество данных для многоэтажных жилых домов одно из самых лучших по РФ.
Данные и расчеты
Как подготовть данные для анализа я уже рассказывал в "Где 15 минут пешком от дома до метро в Москве…" и в "Где бы вы точно не жили и не остановились даже на время, если бы знали и выбирали на основе фактов". Пример расчета расстояний для магазинов с программой также публиковал в статье "Жилье в 500м от сетевых продуктовых магазинов в Москве". Данные из OpenStreetMap PBF файла загружаются в PostgreSQL базу с установленным расширением PostGIS и H3.
Кроме пешеходных дистанций, расчитаных с помощью GraphHopper, понадобится еще число квартир в каждом доме. Его можно найти в значениях OSM тега building:flats
.
Для жилых домов, у которых не указан этот тег проставляем число квартир по правилам:
Если для здания указан диапазон квартир на подъездах (
addr:flats
) то выбираем максимальное значение для дома. Если это значение отличается не более чем на 50% от вычисленного по среднему, то для здания выбираем его, иначе значение из следующего пунктаможно проставить среднее значение квартир и умножить на число этажей в доме и площадь здания:
CREATE TABLE flats_per_building AS WITH flats_precalc AS
(SELECT g.id,
g.type,
(CASE
WHEN g.tags->'building:levels' ~ '^\d+(\.\d+)?$' THEN g.tags->'building:levels'
ELSE NULL
END)::real levels,
(CASE
WHEN g.tags->'building:flats' ~ '^[0-9]+$' THEN g.tags->'building:flats'
ELSE NULL
END)::smallint flats,
(CASE
WHEN g.type='ways'
AND ST_IsClosed(g.geom) THEN st_area(ST_MakePolygon(g.geom)::geography)
WHEN g.type='multipolygon' THEN st_area(g.geom::geography)
ELSE 0
END) area
FROM geometry_global_view g
WHERE type<>'nodes'
AND (CASE
WHEN g.tags->'building:levels' ~ '^\d+(\.\d+)?$' THEN g.tags->'building:levels'
ELSE NULL
END)::real>2 --and **проверка что здание жилое - портянка OSM тегов**;
),
building_max_flat AS
(SELECT g.id,
type,
max(max_flat)::smallint max_flat
FROM geometry_global_view g
INNER JOIN
(SELECT id,(regexp_split_to_array(tags->'addr:flats', '-'))[2] max_flat,
geom
FROM nodes
WHERE tags?'addr:flats'
AND tags?'entrance'
AND tags->'addr:flats' ~ '^\d+\-\d+?$') e ON st_contains(CASE
WHEN TYPE='ways'
AND ST_IsClosed(g.geom) THEN ST_MakePolygon(g.geom)
ELSE g.geom
END, e.geom)
WHERE type<>'nodes'
AND ((CASE
WHEN g.tags->'building:levels' ~ '^\d+(\.\d+)?$' THEN g.tags->'building:levels'
ELSE NULL
END)::real>2)
AND not(g.tags?'building:flats')
GROUP BY 1,2),
flats_aprox AS
(SELECT id,
type,
flats,
(levels*area*
(SELECT avg((flats/levels)/area)
FROM flats_precalc
WHERE area>0
AND flats>0))::smallint aproximated_flats
FROM flats_precalc)
SELECT b.id,
b.type,
coalesce(flats, CASE
WHEN max_flat IS NOT NULL
AND aproximated_flats>0
AND abs(max_flat-aproximated_flats)/(aproximated_flats::real)<0.5 THEN -1*max_flat
ELSE aproximated_flats
END) flats
FROM flats_aprox b LEFT JOIN building_max_flat USING(id,type);
ALTER TABLE flats_per_building ADD PRIMARY KEY(id,type);
Спасибо @roman_deev за подсказку в комментарии к статье, чтобы получить более точное решение по числу квартир из данных уже доступных в OSM!
Простой вариант того же запроса, где отсутствующие flats заполняются только средним
create table flats_per_building as
WITH flats_precalc as (select g.id,g.type,
(case when g.tags->'building:levels' ~ '^\d+(\.\d+)?$' then g.tags->'building:levels' else NULL end)::real levels,
(case when g.tags->'building:flats' ~ '^[0-9]+$' then g.tags->'building:flats' else NULL end)::smallint flats,
(CASE WHEN g.type='ways' and ST_IsClosed(g.geom) THEN st_area(ST_MakePolygon(g.geom)::geography) WHEN g.type='multipolygon' THEN st_area(g.geom::geography) ELSE 0 END) area
from geometry_global_view g
where type<>'nodes' and (case when g.tags->'building:levels' ~ '^\d+(\.\d+)?$' then g.tags->'building:levels' else NULL end)::real>2)--and **проверка что здание жилое - портянка OSM тегов**;
select id,type,
coalesce(flats, (levels*area*
(select avg((flats/levels)/area)
from flats_precalc
where area>0 and flats>0))::smallint) flats
from flats_precalc ;
alter table flats_per_building add primary key(id,type);
Это простое решение чтобы заполнить пропуски в данных. Правильнее и точнее - это обойти дома где не указано число квартир и по почтовым ящикам( табличкам с номером подъезда) посмотреть номера квартир и указать точное число квартир в доме в исходных данных. Когда анализ выполняется для больших территорий, то можно найти данные в ГИС ЖКХ, но выгрузок для этого сайта в открытом доступе нет.
Итак, у нас есть дистанции расчитаные от многоэтажных жилых домов до магазинов. Если просуммировать число квартир в радиусе 1км от магазина, то это число будет пропорционально числу людей которые смогут прийти в этот магазин.
osmworld=# \d flats_per_building
Column | Type |
--------+-----------------|
id | bigint |
type | table_reference |
flats | smallint |
Indexes:
"flats_per_building_pkey" PRIMARY KEY, btree (id, type)
osmworld=# \d distance
Column | Type |
---------------+-----------------|
building_id | bigint |
building_type | table_reference |
poi_id | bigint |
poi_type | table_reference |
distance | smallint |
osmworld=# select count(*) from distance;
count
----------
60816611
(1 row)
Time: 1722,807 ms (00:01,723)
Теперь объединим эти данные - сложив число квартир каждого дома в пешеходной доступности 1000м от точек интереса (POI) - магазинов:
create table flats_per_poi as
select poi_id, poi_type, sum(flats) total_flats
from distance inner join flats_per_building
on building_id=id and building_type=type and distance<=1000
group by poi_id,poi_type
order by total_flats desc;
SELECT 129128
Time: 3108,646 ms (00:03,109)
Обогатим эти данные районом и в каждом районе отсортируем данные по убыванию числа квартир в пешей доступности:
CREATE TABLE moscow_district AS select tags->'name' name,polygon from multipolygon where tags->'admin_level'='8' and tags->'boundary'='administrative';
CREATE INDEX idx_moscow_district_geometry ON moscow_district USING gist (polygon);
create table best_retail_location_per_district as
select name,
row_number() over (partition by district order by total_flats desc) max_flats_rating, district,
total_flats,
centre
from (select total_flats,
coalesce(r.tags->'name',r.tags->'name:ru',r.tags->'name:en') name, (select name from moscow_district where st_contains(polygon, centre) limit 1) district, centre
from flats_per_poi inner join poi r
on poi_id=id and poi_type=type
and 'shop' = any(categories)
and coalesce(r.tags->'name',r.tags->'name:ru',r.tags->'name:en') is not null
order by total_flats desc) shops;
Если нужен анализ конкурентов при открытии продуктового магазина или места для торговли товаром который не представлен у сетевых магазинов Пятёрочка, Перекрёсток, Дикси, Магнит, Магнолия, ВкусВилл, Лента, Азбука Вкуса, Ашан, Атак, но попадает в ту же целевую аудиторию, можно переиспользовать аналитику которую уже для себя выполнили торговые сети и открыли в нужном месте магазин. Для этого в фильтры можно добавить:
(tags@>'shop=>supermarket' or tags@>'shop=>convenience') and
(tags->'brand' in ('Billa',
'Eurospar','EuroSPAR','EUROSPAR',
'"METRO Cash & Carry"',
'Spar','SPAR',
'"АВ Daily"','Авокадо','Авоська','"Азбука Вкуса"',
'Атак','Ашан','"Ашан Сити"',
'Верный','Виктория',
'ВкусВилл','Дикси','Лента','Магнит',
'Магнолия','"Мини Лента"','МясновЪ',
'О’КЕЙ',
'Перекрёсток','"Перекресток Экспресс"',
'Пятёрочка','Светофор',
'"Супер Лента"','СуперЛента',
'"У Палыча"','Фасоль','Чижик','Ярче!')
Статистика по брендам продуктовых в Москве:
select tags->'brand' brand,count(*) from geometry_global_view where (tags@>'shop=>supermarket' or tags@>'shop=>convenience') and tags?'brand' group by 1 having count(*)>1 order by 2 desc;
brand | count
----------------------+-------
Пятёрочка | 1142
ВкусВилл | 594
Дикси | 434
Магнит | 388
Перекрёсток | 295
Магнолия | 161
Лента | 84
У Палыча | 76
Верный | 69
Азбука Вкуса | 68
МясновЪ | 56
Суши Wok | 40
Ашан | 27
АВ Daily | 27
Виктория | 24
Eurospar | 23
Ярче! | 22
Атак | 15
Супер Лента | 14
Светофор | 11
Чижик | 9
О’КЕЙ | 9
СуперЛента | 9
Spar | 7
Авокадо | 6
Перекресток Экспресс | 6
SPAR | 4
Авоська | 3
METRO Cash & Carry | 3
EuroSPAR | 3
Ашан Сити | 3
Фасоль | 3
Мини Лента | 3
Billa | 2
Нефтьмагистраль | 2
Продуктовий магазин | 2
EUROSPAR | 2
(37 rows)
Отобразим в каждом районе лучшие места для торговых точек по числу жителей:
Список существующих торговых мест по одному в каждом из районов Москвы с наибольшим количеством квартир в пешеходных окрестностях 1км от торгового помещения:
select district, total_flats, st_x(centre), st_y(centre)
from best_retail_location_per_district
where max_flats_rating=1
order by total_flats desc;
district | total_flats | st_x | st_y
---------------------------------+-------------+--------------------+--------------------
район Митино | 44554 | 37.355865200000004 | 55.8478696
район Измайлово | 39255 | 37.800719 | 55.793489400000006
район Восточное Измайлово | 39254 | 37.799821800000004 | 55.79304380000001
район Гольяново | 32907 | 37.80093225 | 55.81096895
район Раменки | 31709 | 37.5055284 | 55.70210530000001
район Северное Измайлово | 30541 | 37.8124447 | 55.8050585
Ломоносовский район | 29928 | 37.5473658 | 55.6803493
район Южное Бутово | 29658 | 37.5593346 | 55.5486773
Таганский район | 29457 | 37.6752278 | 55.739144700000004
район Черёмушки | 28843 | 37.5469279 | 55.6735065
Пресненский район | 28788 | 37.518790700000004 | 55.7570794
Гагаринский район | 28615 | 37.5473967 | 55.6811439
район Хорошёво-Мнёвники | 28588 | 37.4602547 | 55.7818655
район Щукино | 28155 | 37.4625799 | 55.8089335
район Ховрино | 27974 | 37.5031309 | 55.8609803
Обручевский район | 27952 | 37.517463 | 55.6643959
район Аэропорт | 27551 | 37.5356024 | 55.803232200000004
район Северное Бутово | 27199 | 37.577473600000005 | 55.568533
район Некрасовка | 27009 | 37.927194300000004 | 55.7028795
Бескудниковский район | 26881 | 37.550535800000006 | 55.875935000000005
район Кунцево | 26791 | 37.410576407649934 | 55.73863922462011
район Богородское | 26623 | 37.719145000000005 | 55.8078323
район Зюзино | 26066 | 37.599057900000005 | 55.653555100000005
район Левобережный | 25818 | 37.475883100000004 | 55.864906600000005
район Северное Тушино | 25815 | 37.4244894 | 55.8499326
район Солнцево | 25813 | 37.4061808 | 55.6502106
район Коньково | 25808 | 37.524680000000004 | 55.6426711
район Восточное Дегунино | 25701 | 37.5481326 | 55.878368900000005
район Люблино | 25541 | 37.7584202 | 55.67367470000001
район Северное Медведково | 25425 | 37.662568300000004 | 55.888120150000006
Академический район | 25403 | 37.5539208 | 55.6836137
район Преображенское | 25278 | 37.717225500000005 | 55.804943400000006
район Выхино-Жулебино | 24985 | 37.8533144 | 55.684696200000005
район Марьино | 24825 | 37.765138 | 55.668098
Дмитровский район | 24682 | 37.5332311 | 55.8812342
район Арбат | 24663 | 37.5830846 | 55.7471182
район Южное Тушино | 24653 | 37.425816600000005 | 55.848617700000005
район Отрадное | 24578 | 37.60205305 | 55.863150100000006
район Новокосино | 24372 | 37.858880500000005 | 55.740321800000004
Нагорный район | 24369 | 37.6060573 | 55.6516913
Ново-Переделкино | 24264 | 37.349189800000005 | 55.6410172
район Текстильщики | 24168 | 37.7484052 | 55.7007545
район Нагатинский Затон | 24130 | 37.6775296 | 55.68217430000001
район Свиблово | 24093 | 37.6462869 | 55.8517595
район Хамовники | 24042 | 37.5789264 | 55.7254597
Тверской район | 24037 | 37.5973848 | 55.7709714
Алексеевский район | 23962 | 37.645125400000005 | 55.81044300000001
Орехово-Борисово Южное | 23737 | 37.7338043 | 55.6073353
район Новогиреево | 23715 | 37.8027832 | 55.753313600000006
Головинский район | 23674 | 37.5111866 | 55.85889400000001
район Чертаново Центральное | 23578 | 37.593337250000005 | 55.60662975
район Кузьминки | 23536 | 37.763281 | 55.705186100000006
район Перово | 23473 | 37.7999486 | 55.754013400000005
Лосиноостровский район | 23342 | 37.6858603 | 55.876531
район Бибирево | 23312 | 37.596387500000006 | 55.8903642
район Южное Медведково | 23006 | 37.6367825 | 55.87363860000001
Рязанский район | 22981 | 37.778901677736364 | 55.71208193761292
район Строгино | 22929 | 37.4063571 | 55.807376600000005
Тимирязевский район | 22852 | 37.5732797 | 55.812274200000004
район Якиманка | 22658 | 37.6136508 | 55.7213738
район Чертаново Южное | 22591 | 37.605664700000005 | 55.594416100000004
район Крылатское | 22568 | 37.4084348 | 55.760584400000006
район Проспект Вернадского | 22325 | 37.512944600000004 | 55.666986800000004
поселение Сосенское | 22225 | 37.477374700000006 | 55.57048090000001
Бабушкинский район | 21958 | 37.6771351 | 55.867305300000005
поселение Внуковское | 21831 | 37.3237201 | 55.6370195
район Зябликово | 21643 | 37.7416136 | 55.6214627
район Тёплый Стан | 21573 | 37.5181272 | 55.632703400000004
Даниловский район | 21467 | 37.6175062 | 55.719938000000006
район Ясенево | 21410 | 37.5439495 | 55.607119700000005
район Ивановское | 21390 | 37.826334100000004 | 55.753645600000006
район Коптево | 21371 | 37.520052 | 55.823584700000005
район Марьина Роща | 21313 | 37.6127702 | 55.7926579
район Лианозово | 21263 | 37.5785372 | 55.89771390000001
район Сокол | 21262 | 37.5147357 | 55.800178700000004
Останкинский район | 21086 | 37.637360900000004 | 55.8134049
Южнопортовый район | 21057 | 37.664825900000004 | 55.731036100000004
Савёловский район | 21011 | 37.5738591 | 55.7945739
район Замоскворечье | 20951 | 37.617964 | 55.7204885
Басманный район | 20784 | 37.6759708 | 55.77245370000001
район Орехово-Борисово Северное | 20782 | 37.708416400000004 | 55.609964500000004
район Западное Дегунино | 20547 | 37.5228794 | 55.8780158
район Чертаново Северное | 20459 | 37.6001775 | 55.6291803
Бутырский район | 20390 | 37.581405100000005 | 55.8199976
район Сокольники | 20328 | 37.676637400000004 | 55.7855112
Войковский район | 20192 | 37.5187881 | 55.821412200000005
Мещанский район | 20033 | 37.621846000000005 | 55.7732935
Можайский район | 19652 | 37.423553500000004 | 55.725824700000004
Донской район | 19509 | 37.607535000000006 | 55.7157616
район Очаково-Матвеевское | 19501 | 37.4757927 | 55.7104287
Тропарёво-Никулино | 19432 | 37.4681865 | 55.664694000000004
Красносельский район | 18394 | 37.636166200000005 | 55.7719856
Алтуфьевский район | 18364 | 37.597489200000005 | 55.885716900000006
район Лефортово | 18326 | 37.7081619 | 55.7505072
район Братеево | 18287 | 37.7634054 | 55.63621010000001
район Соколиная Гора | 18285 | 37.7326258 | 55.779113100000004
район Царицыно | 18200 | 37.6565437 | 55.6260485
Хорошёвский район | 17739 | 37.533148600000004 | 55.776608200000005
район Вешняки | 17409 | 37.823054400000004 | 55.721068200000005
район Котловка | 17388 | 37.5936012 | 55.6813876
район Косино-Ухтомский | 17371 | 37.88647929577547 | 55.7146019953649
район Дорогомилово | 17313 | 37.5489696 | 55.743085300000004
район Филёвский Парк | 17221 | 37.489751000000005 | 55.7397427
район Нагатино-Садовники | 17176 | 37.6629725 | 55.679679900000004
район Печатники | 17069 | 37.7247369 | 55.682193700000006
район Фили-Давыдково | 16830 | 37.451718400000004 | 55.723709500000005
район Беговой | 16642 | 37.5755901 | 55.7896471
район Ростокино | 15438 | 37.6557199 | 55.8335372
район Марфино | 14216 | 37.589894400000006 | 55.8285594
район Метрогородок | 13866 | 37.7586345 | 55.825178550000004
район Бирюлёво Восточное | 13122 | 37.66389045 | 55.601072300000006
район Москворечье-Сабурово | 12305 | 37.663324800000005 | 55.6403018
район Покровское-Стрешнево | 12231 | 37.4536358 | 55.830881500000004
Ярославский район | 10980 | 37.687691 | 55.862006400000006
поселение Московский | 10884 | 37.41915496649685 | 55.660058285851896
район Северный | 10731 | 37.544192200000005 | 55.928780100000004
Нижегородский район | 10346 | 37.681484632205915 | 55.72787293563479
поселение Воскресенское | 9373 | 37.514949 | 55.5256966
район Капотня | 9128 | 37.796075200000004 | 55.6350781
район Куркино | 7364 | 37.428532700000005 | 55.87720755000001
район Внуково | 5940 | 37.2621203 | 55.614216500000005
поселение «Мосрентген» | 4296 | 37.4733691 | 55.620890900000006
район Бирюлёво Западное | 1817 | 37.6464437 | 55.5913467
Где total_flats - число квартир в радиусе 1км от торговой точки района district и её координаты. Конечно эти цифры включают расчет только по пешеходной доступности и только тех многоэтажных домов, что не дальше 2км от входа в метро.
Этот рейтинг так же не учитывает как часто люди будут приходить в торговую точку. Одно дело когда это магазин по пути к метро, а другое - ларек спрятанный во дворах. Расположение на пути людей к аттракторам крайне важно для успеха торговли - будут чаще заходить чем ближе торговый объект расположен к ежедневному маршруту человека. Так же как может помочь поиск локации-двойника уже успешно работающего магазина.
Если углубляться в эту тему, то нужно больше данных и смотреть на применимость модели Хаффа( Huff model), Multinomial Logit Model, Multiplicative Interactive Choice. Данные о расположении торговых точек магазинов по сегментам бизнеса доступны как в данных OSM, так и в объектах Places от Overture Maps Foundation. Надеюсь, что расчеты и геоаналитика помогут найти лучшее расположение для магазина шаговой доступности в месте, популярном у жителей района Москвы.
Уважаемая бульварная пресса! При публикации этой новости, ссылка на оригинал на сайте Хабр обязательна! Искажение информации при цитировании вами моих статей с Хабра говорит о заказном характере вашей работы и крайне низком профессионализме.
Вывод
Хоть расчет пешеходных расстояний мегаполиса достаточно длительная операция, которая выполняется на обычном ноутбуке больше суток, но в остальном расчитать число людей (из квартир), которые могут дойти в магазин оказалось не сложной задачей.
Использовать open source технологии и открытые данные - лучше чем гадать на кофейной гуще и верить на слово. Конечно это лишь один из факторов выбора места для торговли, где реальный успех малого бизнеса включает множество других факторов.
Комментарии (19)
sshikov
07.12.2023 15:29Вот с этим я могу поспорить - большая часть людей в России покупает продукты и товары в магазинах.
Ну я бы сказал, что это зависит от многого. Скажем, в ковид я как раз почти не ходил по магазинам, в основном доставка. А потом наоборот, стал предпочитать посетить живьем, ибо так надоело дома сидеть. Ну да, стоимость доставки для кого-то может быть существенна - но зато ты можешь заказать килограмм 20, и тебе их принесут к двери. И у меня доставка из Ашана Сбермаркетом стоит 59 рублей - о чем тут вообще говорить при такой-то стоимости услуги? На даче в области мы вообще по магазинам не ходим, только доставка.
igor_suhorukov Автор
07.12.2023 15:29У каждого своя история. Я в карантин выбирался в Атак поблизости раз в неделю, доставкой не пользовался. А после этого тем более. Ну и из того что вокруг вижу, много людей ходит в магазины и ТЦ, и много пенсионеров и молодежи вижу в магазинах.
sshikov
07.12.2023 15:29Ну так я и говорю, что скорее всего тут разные есть истории. По-хорошему, надо исследовать.
igor_suhorukov Автор
07.12.2023 15:29Ты прав! Кажется, что проще всего это исследовать банкам и ФНС - все платежи картой и оплата через POS терминалы доступны для аналитики, а кеш флоу из магазинов есть в налоговой. Но обычному человеку это не перепроверить.
sshikov
07.12.2023 15:29+1Ну мы кстати пытались. Вот представь, что у тебя есть под рукой биллинг (по картам твоего банка). И в этом биллинге написано, что человек заплатил какому-то ООО Вася Пупкин (название латиницей, транслитерация) столько-то денег непонятно за что. Биллинг этот присылает тебе Visa, ну или в общем, некая карточная система, и составлен он по ее стандартам. И адрес там тоже написан так, что геокодировать его удается скажем в 80% случаев. Да, еще биллинг это терабайты в день, скажем, и работать с ним не так и просто чисто технически.
Короче говоря, если это POS терминал не принадлежит своему банку, то исследовать платежи даже в такой ситуации далеко не тривиально. Вплоть до того, что мы начали применять всякие эвристики типа того, что если платежи А и Б были произведены в течение 5 минут - значит POS Б (это например банк конкурент) находится где-то близко от POS А (который нашего банка, и мы даже знаем координаты), и мы можем примерно прикинуть, где этот POS стоит, даже не имея правильного адреса, ну или уточнить результат геокодирования. С кучей допущений, что человек скажем шел пешком, и за 5 минут удалился не более чем на ... (а если он на самокате?).
Даже будучи банком, это не так просто, не все удается определить, что может быть интересно. Удобнее всего когда у человека в кармане смартфон, и там стоит твое платежное приложение, и каждый платеж сопровождается координатами, помимо всего остального. Да и то остаются вопросы при платежах скажем за билет в трамвае ;) Ну или нужно сочетать данные банка, и скажем сотового провайдера - а это уже сложная задача, причем не технически.
А уж про обычного человека я и не говорю.
igor_suhorukov Автор
07.12.2023 15:29Счастливчик, нетривиальная задача попадалась!
Я про такой мэтчинг только слышал. В том числе от компании когда получал оффер, которая не банк, а просто продает банкам систему для оповещения по операциям. Там вроде ElasticSearch для фаззи матчинга пытались использовать - дорого на таком траффике.
даже не имея правильного адреса, ну или уточнить результат
геокодирования. С кучей допущений, что человек скажем шел пешком, и за 5 минут удалился не более чем на ... (а если он на самокате?).Поэтому банкам выгодно "впаривать" клиентам свою виртуальную сим карту.
sshikov
07.12.2023 15:29Поэтому банкам выгодно "впаривать" клиентам свою виртуальную сим карту.
Конечно. И иметь данные с сот.
miksoft
07.12.2023 15:29сколько человек сможет дойти до конкретного магазина
В качестве идеи для продолжения:
Сколько человек сможет дойти до конкретного магазина, если каждого человека учитывать с весом, обратным количеству магазинов в пешей доступности для этого человека.
Если в районе один магазин, он явно будет более посещаем, чем если в этом же районе будет еще 10 таких же магазинов.И следующий шаг:
То же, но еще поделить на торговую площадь магазина. (Возможно, еще торговую площадь имеет смысл внести в весовой коэффициент).
Тогда можно будет оценить перспективность магазинов. При высоком соотношении взвешенных покупателей к площади магазин выглядит более перспективным.igor_suhorukov Автор
07.12.2023 15:29Спасибо вам за совет!
нужно больше данных и смотреть на применимость модели Хаффа( Huff
model), Multinomial Logit Model, Multiplicative Interactive Choice.Модель Хаффа как раз учитывает факторы, нужны данные.
sshmakov
07.12.2023 15:29Расположение на пути людей к аттракторам крайне важно для успеха торговли - будут чаще заходить чем ближе торговый объект расположен к ежедневному маршруту человека.
Как-то в одном инвестбанке рассказали отличный контрпример - ТРЦ Метрополис. Отличное расположение на маршруте, между Балтийской и Войковской, каждый день огромные толпы народа перемещаются прямо через ТРЦ. Казалось бы, все условия созданы, что здесь может пойти не так?
И полный пролет - вся эта толпа чуть менее чем полностью игнорирует магазины ТРЦ на своем пути.
Видимо, близость к дому важнее расположения на маршруте.
igor_suhorukov Автор
07.12.2023 15:29+1Отличный пример! Сам много раз через него пробегал ничего не покупая внутри. Возможно это ошибка зонирования ТЦ стоимости аренды а следовательно и магазинов на пути потока и уровня цен. Есть другой пример ТЦ Праздник - постоянно людей внутри полно и торговля там успешная - как раз если бы не поток людей в метро и из метро в этом торговом центре не было бы такого ажиотажа, как и в супермаркете напротив.
BobArctor
07.12.2023 15:291 километр это просто радиус или реальный путь с учетом всех промзон, рельс и заборов во дворах?
igor_suhorukov Автор
07.12.2023 15:291 километр это пешеходная дистанция с учетом всех ограничений, а не расстояние по прямой. Для расчетов использовались данные полноценной маршрутизации.
roman_deev
07.12.2023 15:29+1Правильнее и точнее - это обойти дома где не указано число квартир и по почтовым ящикам( табличкам с номером подъезда)
Или достать все подъезды дома и посмотреть на максимальный
addr:flats
igor_suhorukov Автор
07.12.2023 15:29Спасибо!
Дельный совет, но это не так просто. Требуется очистка данных и тестировать парсер...
osmworld=# select tags->'addr:flats',count(*) from geometry_global_view where tags?'addr:flats' and tags?'entrance' group by 1 order by length(tags->'addr:flats') desc limit 20; ?column? | count ------------------------------------------------------------------------------------------------+------- 61-69, 90-109, 130-149, 170-189, 210-229, 250-269, 290-309, 330-349, 370-389, 410-429, 450-460 | 1 70-89, 110-129, 150-169, 190-209, 230-249, 270-289, 310-329, 350-369, 390-409, 430-449 | 1 1-9; 10-19; 20-29; 30-39; 40-49; 50-59; 119-120; 131-140; 151-160; 171-178 | 1 3-29;31-32;3А-4А;6А-8А;10А-12А;14А-16А;18А-20А;22А-24А;26А-28А | 1 34-59;34А;36А-38А;40А-42А;44А-46А;48А-50А;52А-54А;56А-57А;59А | 1 60-60А;69-72;81-88;97-104;113-120;130-136;146;188-195 | 1 8-20;21а-23а;22а;26а-28а;30а;31а;34а-36а;37;39;40 | 1 112-124;286;286а;287-288;294;294а;295;295а | 1 95-108;289;289а;290;290а;296;296а;297;297а | 1 1-59, 119-120, 131-140, 151-160, 171-178 | 1 60-68; 69-118; 121-130; 141-150; 161-170 | 1 80А;82А;84А;86А;161-163;91А;158-160 | 1 61,62,64,65,67,68,70,71,73,74,76,77 | 1 11-14; 24-29; 39-44; 54-59; 69-70 | 1 60-118, 121-130, 141-150, 161-170 | 1 52-58;64;40а;42а;44а;46а;48а;50а | 1 517-526;518А;520А;522А;524А;526А | 1 41-45; 46а; 48a; 50a; 52a; 54а | 1 1-10;1А;2А;3А;4А;5А;6А;7А;8А | 1 7-11;20-23;33;34;36;37;46-50 | 1 (20 rows)
C другой стороны:
osmworld=# select tags->'addr:flats',count(*) from geometry_global_view where tags?'addr:flats' and tags?'entrance' group by 1 order by length(tags->'addr:flats') limit 50; ?column? | count ----------+------- 8 | 34 2 | 102 3 | 101 9 | 18 1 | 104 7 | 33 5 | 76 6 | 79 4 | 98 16 | 3 1А | 1 19 | 3 17 | 2 11 | 8 58 | 1 12 | 7 21 | 2 13 | 3 6А | 1 15 | 4 20 | 1 2- | 1 31 | 1 38 | 1 14 | 4 37 | 1 10 | 17 18 | 2 85- | 1 6-9 | 2 280 | 1 1-3 | 3 251 | 1 37- | 1 46- | 1 3-5 | 1 2-7 | 2 3-4 | 1 6-? | 1 301 | 1 4-7 | 1 3-9 | 1 1-5 | 11 4-8 | 2 1-2 | 2 160 | 1 1-9 | 66 2-8 | 3 1-8 | 90 5-6 | 1 (50 rows)
igor_suhorukov Автор
07.12.2023 15:29Решил быстро проверить как много домов в Москве можно заполнить максимальным номером квартиры с подъездов дома( при этом отбросив все addr:flats которые не соответствуют шаблону ^\d+-\d+?$) - вышло 1186 шт. Жаль этот подход покрывает малую часть домов:
with entrances as ( select id,(regexp_split_to_array(tags->'addr:flats','-'))[2] max_flat,geom from nodes where tags?'addr:flats' and tags?'entrance' and tags- >'addr:flats' ~ '^\d+\-\d+?$') select g.id,type,max(max_flat) max_flat from geometry_global_view g inner join entrances e on st_contains(CASE WHEN type='ways' and ST_IsClosed(g.geom) THEN ST_MakePolygon(g.geom) ELSE g.geom END,e.geom) where type<>'nodes' and ((case when g.tags->'building:levels' ~ '^\d+(\.\d+)?$' then g.tags->'building:levels' else NULL end)::real>2) and not(g.tags?'building:flats') --проверка по OSM тегам что дом жилой group by 1,2;
IMHO не особо лучше среднего - нужно валидировать, есть результаты где более 1000 квартир в доме. Ну и в OSM разметке видел что иногда отмечают не все подъезды. Идея-то логичная и отличная!
roman_deev
07.12.2023 15:29Потыкался в данные Москвы и внезапно там много
building:flats
и малоaddr:flats
. Например, в Питере обратная ситуация (но ещё и свои приколы в виде пропущенных квартир и склеенных зданий в центре)Навскидку, в Москве не более чем у 25% многоэтажек по
addr:flats
получится узнать число квартир (поделил 8464addr:flats
начинающиеся с1-
на 31925building=apartments
)
https://overpass-turbo.eu/s/1ExLесть результаты где более 1000 квартир в доме.
А в чём проблема? Вполне реальные дома
igor_suhorukov Автор
07.12.2023 15:29Потыкался в данные Москвы и внезапно там много
building:flats
и малоaddr:flats
. Например, в Питере обратная ситуацияО, да! Каждый город - свои особенности в разметке и свой фокус на тегах!
Навскидку, в Москве не более чем у 25% многоэтажек по
addr:flats
Я скорее всего плохо описал свой прошлый запрос для проверки. 1186 это число домов в котором по
addr:flats
удалось добавить значение по максимальной квартире на подъезде.building:flats.
К сожалению,building=apartments
не всегда расставлено на многоэтажных жилых домах. Поэтому там в прошлых публикаций тянется портянка тегов в where запроса.Спасибо тебе за совет!!! Я обновил запрос в статье и это заменило около 1% в данных
count: 445 (1 row) значений квартир в домах из count:43612 (1 row)
igor_suhorukov Автор
@sshikov смотри что получается если перевернуть агрегацию данных наоборот.