huff 1.4.1__py3-none-any.whl → 1.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- huff/models.py +1020 -163
- huff/tests/data/Wieland2015.xlsx +0 -0
- huff/tests/tests_huff.py +142 -24
- {huff-1.4.1.dist-info → huff-1.5.1.dist-info}/METADATA +13 -3
- {huff-1.4.1.dist-info → huff-1.5.1.dist-info}/RECORD +7 -7
- {huff-1.4.1.dist-info → huff-1.5.1.dist-info}/WHEEL +0 -0
- {huff-1.4.1.dist-info → huff-1.5.1.dist-info}/top_level.txt +0 -0
huff/tests/data/Wieland2015.xlsx
CHANGED
Binary file
|
huff/tests/tests_huff.py
CHANGED
@@ -4,18 +4,17 @@
|
|
4
4
|
# Author: Thomas Wieland
|
5
5
|
# ORCID: 0000-0001-5168-9846
|
6
6
|
# mail: geowieland@googlemail.com
|
7
|
-
# Version: 1.
|
8
|
-
# Last update: 2025-
|
7
|
+
# Version: 1.5.1
|
8
|
+
# Last update: 2025-07-01 17:10
|
9
9
|
# Copyright (c) 2025 Thomas Wieland
|
10
10
|
#-----------------------------------------------------------------------
|
11
11
|
|
12
|
-
|
13
|
-
from huff.models import create_interaction_matrix, get_isochrones, load_geodata, load_interaction_matrix, market_shares, modelfit
|
12
|
+
from huff.models import create_interaction_matrix, get_isochrones, load_geodata, load_interaction_matrix, load_marketareas, market_shares, modelfit
|
14
13
|
from huff.osm import map_with_basemap
|
15
14
|
from huff.gistools import buffers, point_spatial_join
|
16
15
|
|
17
16
|
|
18
|
-
#
|
17
|
+
# Dealing with customer origins (statistical districts):
|
19
18
|
|
20
19
|
Haslach = load_geodata(
|
21
20
|
"data/Haslach.shp",
|
@@ -39,10 +38,8 @@ Haslach.define_marketsize("pop")
|
|
39
38
|
# Definition of market size variable
|
40
39
|
|
41
40
|
Haslach.define_transportcosts_weighting(
|
42
|
-
|
43
|
-
#
|
44
|
-
param_lambda = [10, -0.5],
|
45
|
-
func="logistic"
|
41
|
+
param_lambda = -2.2,
|
42
|
+
# one weighting parameter for power function (default)
|
46
43
|
# two weighting parameters for logistic function
|
47
44
|
)
|
48
45
|
# Definition of transport costs weighting (lambda)
|
@@ -51,7 +48,7 @@ Haslach.summary()
|
|
51
48
|
# Summary after update
|
52
49
|
|
53
50
|
|
54
|
-
#
|
51
|
+
# Dealing with upply locations (supermarkets):
|
55
52
|
|
56
53
|
Haslach_supermarkets = load_geodata(
|
57
54
|
"data/Haslach_supermarkets.shp",
|
@@ -87,9 +84,7 @@ Haslach_supermarkets.summary()
|
|
87
84
|
# Summary of updated customer origins
|
88
85
|
|
89
86
|
Haslach_supermarkets_isochrones = Haslach_supermarkets.get_isochrones_gdf()
|
90
|
-
# Extracting isochrones
|
91
|
-
|
92
|
-
print(Haslach_supermarkets_isochrones)
|
87
|
+
# Extracting isochrones as gdf
|
93
88
|
|
94
89
|
|
95
90
|
# Using customer origins and supply locations for building interaction matrix:
|
@@ -101,8 +96,8 @@ haslach_interactionmatrix = create_interaction_matrix(
|
|
101
96
|
# Creating interaction matrix
|
102
97
|
|
103
98
|
haslach_interactionmatrix.transport_costs(
|
104
|
-
ors_auth="5b3ce3597851110001cf62480a15aafdb5a64f4d91805929f8af6abd"
|
105
|
-
|
99
|
+
ors_auth="5b3ce3597851110001cf62480a15aafdb5a64f4d91805929f8af6abd",
|
100
|
+
network=True,
|
106
101
|
#distance_unit="meters",
|
107
102
|
# set network = True to calculate transport costs matrix via ORS API (default)
|
108
103
|
)
|
@@ -131,12 +126,10 @@ print(huff_model.get_market_areas_df())
|
|
131
126
|
|
132
127
|
# Maximum Likelihood fit for Huff Model:
|
133
128
|
|
134
|
-
haslach_interactionmatrix.
|
135
|
-
|
136
|
-
initial_params=[1, 9, -0.6],
|
129
|
+
haslach_interactionmatrix.huff_ml_fit(
|
130
|
+
initial_params=[1, -2],
|
137
131
|
method="trust-constr",
|
138
|
-
|
139
|
-
bounds = [(0.8, 0.9999),(7, 11),(-0.9, -0.4)],
|
132
|
+
bounds = [(0.8, 0.9999),(-2.5, -1.5)]
|
140
133
|
)
|
141
134
|
# Maximum Likelihood fit for Huff Model
|
142
135
|
|
@@ -212,14 +205,20 @@ Wieland2015_interaction_matrix = load_interaction_matrix(
|
|
212
205
|
"K",
|
213
206
|
"K_KKr"
|
214
207
|
],
|
208
|
+
market_size_col="Sum_Ek1",
|
209
|
+
flows_col="Anb_Eink1",
|
215
210
|
transport_costs_col="Dist_Min2",
|
216
|
-
probabilities_col="
|
211
|
+
probabilities_col="MA_Anb1",
|
217
212
|
data_type="xlsx"
|
218
213
|
)
|
214
|
+
# Loading interaction matrix from XLSX file
|
219
215
|
|
220
216
|
Wieland2015_interaction_matrix.summary()
|
221
217
|
# Summary of interaction matrix
|
222
218
|
|
219
|
+
|
220
|
+
# Parameter estimation via MCI model:
|
221
|
+
|
223
222
|
Wieland2015_fit = Wieland2015_interaction_matrix.mci_fit(
|
224
223
|
cols=[
|
225
224
|
"A_j",
|
@@ -240,6 +239,122 @@ Wieland2015_fit.summary()
|
|
240
239
|
# MCI model summary
|
241
240
|
|
242
241
|
|
242
|
+
# Parameter estimation via Maximum Likelihood:
|
243
|
+
|
244
|
+
Wieland2015_interaction_matrix2 = load_interaction_matrix(
|
245
|
+
data="data/Wieland2015.xlsx",
|
246
|
+
customer_origins_col="Quellort",
|
247
|
+
supply_locations_col="Zielort",
|
248
|
+
attraction_col=[
|
249
|
+
"VF",
|
250
|
+
"K",
|
251
|
+
"K_KKr"
|
252
|
+
],
|
253
|
+
market_size_col="Sum_Ek",
|
254
|
+
flows_col="Anb_Eink",
|
255
|
+
transport_costs_col="Dist_Min2",
|
256
|
+
probabilities_col="MA_Anb",
|
257
|
+
data_type="xlsx",
|
258
|
+
xlsx_sheet="interactionmatrix",
|
259
|
+
check_df_vars=False
|
260
|
+
)
|
261
|
+
# Loading empirical interaction matrix again
|
262
|
+
|
263
|
+
Wieland2015_interaction_matrix2.define_weightings(
|
264
|
+
vars_funcs = {
|
265
|
+
0: {
|
266
|
+
"name": "A_j",
|
267
|
+
"func": "power"
|
268
|
+
},
|
269
|
+
1: {
|
270
|
+
"name": "t_ij",
|
271
|
+
"func": "power",
|
272
|
+
#"func": "exponential"
|
273
|
+
#"func": "logistic"
|
274
|
+
},
|
275
|
+
2: {
|
276
|
+
"name": "K",
|
277
|
+
"func": "power"
|
278
|
+
},
|
279
|
+
3: {
|
280
|
+
"name": "K_KKr",
|
281
|
+
"func": "power"
|
282
|
+
}
|
283
|
+
}
|
284
|
+
)
|
285
|
+
# Defining weighting functions
|
286
|
+
|
287
|
+
Wieland2015_interaction_matrix2.huff_ml_fit(
|
288
|
+
# Power TC function
|
289
|
+
initial_params=[0.9, -1.5, 0.5, 0.3],
|
290
|
+
bounds=[(0.5, 1), (-2, -1), (0.2, 0.7), (0.2, 0.7)],
|
291
|
+
# # Logistic TC function:
|
292
|
+
# initial_params=[0.9, 10, -0.5, 0.5, 0.3],
|
293
|
+
# bounds=[(0.5, 1), (8, 12), (-0.7, -0.2), (0.2, 0.7), (0.2, 0.7)],
|
294
|
+
fit_by="probabilities",
|
295
|
+
#method = "trust-constr"
|
296
|
+
)
|
297
|
+
# ML fit with power transport cost function based on probabilities
|
298
|
+
# from InteractionMatrix object
|
299
|
+
|
300
|
+
Wieland2015_interaction_matrix2.summary()
|
301
|
+
# Summary of interaction matrix
|
302
|
+
|
303
|
+
huff_model_fit2 = Wieland2015_interaction_matrix2.marketareas()
|
304
|
+
# Calculation of market areas
|
305
|
+
|
306
|
+
huff_model_fit2 = huff_model_fit2.ml_fit(
|
307
|
+
# Power TC function
|
308
|
+
initial_params=[0.9, -1.5, 0.5, 0.3],
|
309
|
+
bounds=[(0.5, 1), (-2, -1), (0.2, 0.7), (0.2, 0.7)],
|
310
|
+
# # Logistic TC function:
|
311
|
+
# initial_params=[0.9, 10, -0.5, 0.5, 0.3],
|
312
|
+
# bounds=[(0.5, 1), (8, 12), (-0.7, -0.2), (0.2, 0.7), (0.2, 0.7)],
|
313
|
+
fit_by="probabilities",
|
314
|
+
#method = "trust-constr"
|
315
|
+
)
|
316
|
+
# ML fit with power transport cost function based on probabilities
|
317
|
+
# from HuffModel object
|
318
|
+
|
319
|
+
huff_model_fit2.summary()
|
320
|
+
# Summary of Hudd model
|
321
|
+
|
322
|
+
|
323
|
+
# Loading and including total market areas
|
324
|
+
|
325
|
+
Wieland2025_totalmarketareas = load_marketareas(
|
326
|
+
data="data/Wieland2015.xlsx",
|
327
|
+
supply_locations_col="Zielort",
|
328
|
+
total_col="Anb_Eink",
|
329
|
+
data_type="xlsx",
|
330
|
+
xlsx_sheet="total_marketareas"
|
331
|
+
)
|
332
|
+
# Loading empirical total market areas
|
333
|
+
|
334
|
+
huff_model_fit2 = Wieland2025_totalmarketareas.add_to_model(
|
335
|
+
huff_model_fit2
|
336
|
+
)
|
337
|
+
# Adding total market areas to HuffModel object
|
338
|
+
|
339
|
+
print(huff_model_fit2.get_market_areas_df())
|
340
|
+
# Showing total market areas of HuffModel object
|
341
|
+
|
342
|
+
huff_model_fit3 = huff_model_fit2.ml_fit(
|
343
|
+
# Power TC function
|
344
|
+
initial_params=[0.9, -1.5, 0.5, 0.3],
|
345
|
+
bounds=[(0.5, 1), (-2, -1), (0.2, 0.7), (0.2, 0.7)],
|
346
|
+
# # Logistic TC function:
|
347
|
+
# initial_params=[0.9, 10, -0.5, 0.5, 0.3],
|
348
|
+
# bounds=[(0.5, 1), (8, 12), (-0.7, -0.2), (0.2, 0.7), (0.2, 0.7)],
|
349
|
+
fit_by="totals",
|
350
|
+
#method = "trust-constr"
|
351
|
+
)
|
352
|
+
# Fit Huff model by totals
|
353
|
+
|
354
|
+
huff_model_fit3.summary()
|
355
|
+
# Show summary
|
356
|
+
|
357
|
+
|
243
358
|
# Buffer analysis:
|
244
359
|
|
245
360
|
Haslach_supermarkets_gdf = Haslach_supermarkets.get_geodata_gpd_original()
|
@@ -298,7 +413,8 @@ map_with_basemap(
|
|
298
413
|
Haslach_supermarkets_gdf
|
299
414
|
],
|
300
415
|
styles={
|
301
|
-
0: {
|
416
|
+
0: {
|
417
|
+
"name": "Isochrones",
|
302
418
|
"color": {
|
303
419
|
"segm_min": {
|
304
420
|
"3": "midnightblue",
|
@@ -310,11 +426,13 @@ map_with_basemap(
|
|
310
426
|
},
|
311
427
|
"alpha": 0.3
|
312
428
|
},
|
313
|
-
1: {
|
429
|
+
1: {
|
430
|
+
"name": "Districts",
|
314
431
|
"color": "black",
|
315
432
|
"alpha": 1
|
316
433
|
},
|
317
|
-
2: {
|
434
|
+
2: {
|
435
|
+
"name": "Supermarket chains",
|
318
436
|
"color": {
|
319
437
|
"Name": {
|
320
438
|
"Aldi S├╝d": "blue",
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: huff
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.5.1
|
4
4
|
Summary: huff: Huff Model Market Area Analysis
|
5
5
|
Author: Thomas Wieland
|
6
6
|
Author-email: geowieland@googlemail.com
|
@@ -28,14 +28,24 @@ Thomas Wieland [ORCID](https://orcid.org/0000-0001-5168-9846) [EMail](mailto:geo
|
|
28
28
|
See the /tests directory for usage examples of most of the included functions.
|
29
29
|
|
30
30
|
|
31
|
+
## Updates v1.5.1
|
32
|
+
- Extensions:
|
33
|
+
- HuffModel.ml_fit(): Fit Huff model parameters by empirical total market areas
|
34
|
+
- HuffModel.summary(): Goodnes-of-fit depends on fit_by
|
35
|
+
- load_market_areas(): Loading table with totals and including into InteractionMatrix, HuffModel and MCIModel objects
|
36
|
+
- Bugfixes:
|
37
|
+
- InteractionMatrix.summary(): NoneType parameter
|
38
|
+
- InteractionMatrix.huff_ml_fit(): Update estimates possible even if fit algorithm did not converge
|
39
|
+
|
40
|
+
|
31
41
|
## Features
|
32
42
|
|
33
43
|
- **Huff Model**:
|
34
44
|
- Defining origins and destinations with weightings
|
35
45
|
- Creating interaction matrix from origins and destinations
|
36
|
-
- Market simulation with basic Huff Model
|
37
46
|
- Different function types: power, exponential, logistic
|
38
|
-
- Huff model parameter estimation via Maximum Likelihood (ML)
|
47
|
+
- Huff model parameter estimation via Maximum Likelihood (ML) by probalities and customer flows
|
48
|
+
- Huff model market simulation
|
39
49
|
- **Multiplicative Competitive Interaction Model**:
|
40
50
|
- Log-centering transformation of interaction matrix
|
41
51
|
- Fitting MCI model with >= 2 independent variables
|
@@ -1,10 +1,10 @@
|
|
1
1
|
huff/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
huff/gistools.py,sha256=fgeE1IsUO7UIaawb23kuiz_Rlxn7T18iLLTA5yvgp74,7038
|
3
|
-
huff/models.py,sha256=
|
3
|
+
huff/models.py,sha256=IihaZmutJjdKqzTVXGVmcYbauFJImF-UPsZ2QCPzw8s,125182
|
4
4
|
huff/ors.py,sha256=JlO2UEishQX87PIiktksOrVT5QdB-GEWgjXcxoR_KuA,11929
|
5
5
|
huff/osm.py,sha256=9A-7hxeZyjA2r8w2_IqqwH14qq2Y9AS1GxVKOD7utqs,7747
|
6
6
|
huff/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
huff/tests/tests_huff.py,sha256=
|
7
|
+
huff/tests/tests_huff.py,sha256=eHnEiV8m7TjpAXnJqo1aZ0YlQCGHxK1iFXROEyhN5cU,12884
|
8
8
|
huff/tests/data/Haslach.cpg,sha256=OtMDH1UDpEBK-CUmLugjLMBNTqZoPULF3QovKiesmCQ,5
|
9
9
|
huff/tests/data/Haslach.dbf,sha256=GVPIt05OzDO7UrRDcsMhiYWvyXAPg6Z-qkiysFzj-fc,506
|
10
10
|
huff/tests/data/Haslach.prj,sha256=2Jy1Vlzh7UxQ1MXpZ9UYLs2SxfrObj2xkEkZyLqmGTY,437
|
@@ -23,8 +23,8 @@ huff/tests/data/Haslach_supermarkets.prj,sha256=2Jy1Vlzh7UxQ1MXpZ9UYLs2SxfrObj2x
|
|
23
23
|
huff/tests/data/Haslach_supermarkets.qmd,sha256=JlcOYzG4vI1NH1IuOpxwIPnJsCyC-pDRAI00TzEvNf0,2522
|
24
24
|
huff/tests/data/Haslach_supermarkets.shp,sha256=X7QbQ0BTMag_B-bDRbpr-go2BQIXo3Y8zMAKpYZmlps,324
|
25
25
|
huff/tests/data/Haslach_supermarkets.shx,sha256=j23QHX-SmdAeN04rw0x8nUOran-OCg_T6r_LvzzEPWs,164
|
26
|
-
huff/tests/data/Wieland2015.xlsx,sha256=
|
27
|
-
huff-1.
|
28
|
-
huff-1.
|
29
|
-
huff-1.
|
30
|
-
huff-1.
|
26
|
+
huff/tests/data/Wieland2015.xlsx,sha256=jUt9YcRrYL99AjxzXKMXD3o5erjd9r_jYfnALdrTQ3o,24333
|
27
|
+
huff-1.5.1.dist-info/METADATA,sha256=BXRKyUp5qIEoYjNpo_w9zpUwMTDTO_aegNgr67qj8ns,6187
|
28
|
+
huff-1.5.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
29
|
+
huff-1.5.1.dist-info/top_level.txt,sha256=nlzX-PxZNFmIxANIJMySuIFPihd6qOBkRlhIC28NEsQ,5
|
30
|
+
huff-1.5.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|