Feature types¶
Circle¶
Aggregate a dataset in a radius around the point.
type'circle'datasetstr, aggregated datasetfilterdict = None, dataset filter in mongo formatfieldstr, aggregated dataset field or numexpr formulaaggstr, aggregation functionlimitint, circle radius, i.e. the maximum distance in meters to the dataset pointsfillnaOptional[float] = None, returned value instead of NaN/Nonemetric_funcsList[dict] = [], metric functionsgeometryOptional[Literal['geopos', 'geometry']] = None, dataset geometry field, if None then 'geopos' will be selected if it exists else 'geometry'
Config example:
circle_feature = {
'type': 'circle',
'dataset': 'ru-pub-households/apartments',
'field': 'apartments',
'limit': 300,
'agg': 'sum',
'fillna': 0,
'filter': {'price': {'$lt': 145000.0}},
}
Isochrone¶
Aggregate a dataset in an isochrone around the point.
type'isochrone'datasetstr, aggregated datasetfilterdict = None, dataset filter in mongo formatmetricstr, router metricfieldstr, aggregated dataset field or numexpr formulaaggstr, aggregation functionlimitint, isochrone radius, i.e. the maximum travel time or distance to the dataset pointsfillnaOptional[float] = None, returned value instead of NaN/Nonemetric_funcsList[dict] = [], metric functionsgeometryOptional[Literal['geopos', 'geometry']] = None, dataset geometry field, if None then 'geopos' will be selected if it exists else 'geometry'
Config example:
isochrone_feature = {
'type': 'isochrone',
'dataset': 'ru-pub-households/apartments',
'field': 'apartments',
'metric': 'foot',
'limit': 5,
'agg': 'sum',
'fillna': 0,
}
Huff¶
Aggregate a dataset using probability weights from huff model, thus taking competitors into account.
Example:
Suppose we calculate the sum of apartments taking into account competitors and there is one competitor of our store. We can calculate influence of each of them for each house using formula: \(\frac{weight}{metric}\) (competitor lines are red):
| house id | apartments | point id | point metric | point weight | influence |
|---|---|---|---|---|---|
| 1 | 100 | 1 | 8 | 1000 | 125 |
| 1 | 100 | 2 | 4 | 2000 | 500 |
| 2 | 120 | 1 | 5 | 1000 | 200 |
| 2 | 120 | 2 | 10 | 2000 | 200 |
| 3 | 150 | 1 | 1 | 1000 | 1000 |
| 3 | 150 | 2 | 8 | 2000 | 250 |
Then probability for each house is calculated as \(p_i = \frac{infl_i}{\sum_i infl_i}\):
| house id | apartments | point id | influence | probability |
|---|---|---|---|---|
| 1 | 100 | 1 | 125 | 0.2 |
| 1 | 100 | 2 | 500 | 0.8 |
| 2 | 120 | 1 | 200 | 0.5 |
| 2 | 120 | 2 | 200 | 0.5 |
| 3 | 150 | 1 | 1000 | 0.8 |
| 3 | 150 | 2 | 250 | 0.2 |
And aggregation result is \(0.2 * 100 + 0.5 * 120 + 0.8 * 150 = 200\)
type'huff'datasetstr, aggregated datasetfilterdict = None, dataset filter in mongo formatmetricstr, distance or router metricweightOptional[str] = None, weight name withoutwt:prefixfieldstr, aggregated dataset field or numexpr formulaaggstr, aggregation functionlimitint, metric limit, i.e. the maximum travel time or distance to the dataset pointsfillnaOptional[float] = None, returned value instead of NaN/Nonemetric_funcsList[dict] = [], metric functionsinfl_funcOptional[dict] = None, influence functionwinner_takes_allbool = False, ifTrue, the probability weight will be set to 1 for the point with the highest influence, i.e. winner by influence "takes all"cannibalizationbool = True, ifFalse, the points set is not counted as competitors for the current points. The points are not competitors to themselvesgeometryOptional[Literal['geopos', 'geometry']] = None, dataset geometry field, if None then 'geopos' will be selected if it exists else 'geometry'competitors_filterOptional[dict] = None, competitors dataset filter in mongo format
For the calculated point the points from the competitors and other points
from the points (see faas config)
will be considered competitors.
Config example:
huff_feature = {
'type': 'huff',
'dataset': 'ru-pub-households/apartments',
'field': 'apartments',
'metric': 'foot',
'limit': 10,
'agg': 'sum',
'fillna': 0,
}
Distance¶
Calculate the distance or router metric to the nearest dataset item according to that metric.
type'distance'datasetstrfilterdict = None, dataset filter in mongo formatmetricstr, distance or router metriclimitint, metric limit, i.e. the maximum travel time or distance to the dataset pointsfillnaOptional[float] = None, returned value instead of NaN/Nonerankint = 1, proximity rank.1means calculate distance to the nearest (closest) item from the dataset,2— to the second closest, etc.metric_funcsList[dict] = [], metric functions (only circle and donut are supported)geometryOptional[Literal['geopos', 'geometry']] = None, dataset geometry field, if None then 'geopos' will be selected if it exists else 'geometry'
Config example:
distance_feature = {
'type': 'distance',
'dataset': 'ru-pub-households/apartments',
'metric': 'dist',
'limit': 500,
'fillna': -1,
'rank': 1,
}
Near¶
Get the field from the closest dataset item by distance or router metric.
type'near'datasetstrfilterdict = None, dataset filter in mongo formatfieldstr, aggregated dataset fieldmetricstr, distance or router metriclimitint, metric limit, i.e. the maximum travel time or distance to the dataset pointsfillnaOptional[float] = None, returned value instead of NaN/Nonedropnabool = False, whether to drop empty fields (None, NaN)dropzerobool = False, whether to drop fields with a zero valuerankint = 1, proximity rank.1means calculate distance to the nearest (closest) item from the dataset,2— to the second closest, etc.metric_funcsList[dict] = [], metric functions (only circle and donut are supported)geometryOptional[Literal['geopos', 'geometry']] = None, dataset geometry field, if None then 'geopos' will be selected if it exists else 'geometry'geometry_filterOptional[str] = None, Geometry filters
Config example:
near_feature = {
'type': 'near',
'dataset': 'ru-pub-households/apartments',
'field': 'apartments',
'metric': 'dist',
'limit': 300,
'fillna': 0,
'dropna': True,
'dropzero': True,
'rank': 2,
}
Match¶
Get the field from the dataset item that intersects by geometry with the point.
Dataset items should contain geojson polygons in the geometry field.
type'match'datasetstr, dataset with polygonsfilterdict = None, dataset filter in mongo formatfieldstr, dataset fieldfillnaOptional[float] = None, returned value instead of NaN/None
Config example:
match_feature = {
'type': 'match',
'dataset': 'ru-pub-polygons/regions',
'field': 'name',
'fillna': 0,
}
Match_aggregate¶
Get a polygon from one dataset and then aggregate another dataset within this polygon.
Polygon can be matched with the point by geometry intersection or by id field.
Polygon dataset items should contain geojson polygons in the geometry field.
type'match_aggregate'datasetstr, polygon datasetfilterdict = None, polygon dataset filter in mongo formataggdict, aggregation rulebystr = 'geometry', if'geometry', match by geometry intersection, if'id', match byidfieldfillnaOptional[float] = None, returned value instead of NaN/None
where aggregation rule is:
datasetstr, aggregated datasetfilterdict = None, aggregated dataset filter in mongo formatfieldstr, aggregated dataset field or numexpr formulaaggstr, aggregation function
Config example:
match_aggregate_feature = {
'type': 'match_aggregate',
'dataset': 'ru-pub-polygons/regions',
'agg': {
'dataset': 'ru-pub-households/apartments',
'field': 'apartments',
'agg': 'sum',
},
'fillna': 0,
}
Collect¶
The operation of "collecting" features from linked points.
Assume that for each point there is a set of points linked by some id in dataset.
For each such point, we calculate a feature, then aggregate the resulting
features with a given weight.
type'collect'datasetstr, linked points datasetfeaturedict, feature config calculated for each point fromdataset. Must be one of Circle, Isochrone, Distance, Nearweightstr = 'none', weight name withoutwt:prefixaggstr, aggregation functionid_fieldstr = 'id', name of the id field in points datasetfillnaOptional[float] = None, returned value instead of NaN/None
Config example:
collect_feature = {
'type': 'collect',
'dataset': 'client/traffic_probability',
'agg': 'sum',
'fillna': 0,
'feature': {
'type': 'circle',
'limit': 1500,
'dataset': 'ru-pub-households/apartments',
'field': 'price',
'agg': 'sum',
'fillna': 0,
},
}
If you want to pass collected points explicitly, you can set
collect:{here must be collect feature dataset name} field with list[dict]. For example:
config = {
'points': [
{
'id': 1,
'geopos': {'type': 'Point', 'coordinates': [33, 55]},
'collect:client/traffic_probability': [
{
'id': 125,
'geopos': {'type': 'Point', 'coordinates': [33.5, 55.5]},
},
{
'id': 127,
'geopos': {'type': 'Point', 'coordinates': [33.7, 55.7]},
},
],
}
],
'features': {
'type': 'collect',
'dataset': 'client/traffic_probability',
...,
},
}
More complex gas stations example:
Traffic aggregation from different entrances
Each gas station is associated with a set of points that define its entries.
For each entry, a traffic conversion coefficient wt:conv is specified.
Additionally, the field id_gas_station in each entry indicates the corresponding gas station's id.
The traffic_points entry dataset (points) contains the id_azs, geopos, and wt:conv fields.
The traffic (lines) dataset contains the fields intensity and geometry.
collect_feature = {
'type': 'collect',
'dataset': 'client/traffic_points',
'id_field': 'id_gas_station',
'agg': 'sum',
'weight': 'conv',
'feature': {
'type': 'near',
'dataset': 'client/traffic',
'field': 'intensity',
'metric': 'dist',
'limit': 30,
'geometry_filter': 'cross_right',
'dropna': True,
'dropzero': True,
'fillna': 0,
},
}
Inner Near feature means "take the nearest traffic intensity on the side of the road where the entry point is located."