SearchLibrium 0.0.153__tar.gz → 0.0.155__tar.gz
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.
- {searchlibrium-0.0.153/src/SearchLibrium.egg-info → searchlibrium-0.0.155}/PKG-INFO +1 -1
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/pyproject.toml +1 -1
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/MixedLogitGSE.py +33 -5
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/__init__.py +2 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/harmony.py +22 -2
- searchlibrium-0.0.155/src/SearchLibrium/version.txt +1 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155/src/SearchLibrium.egg-info}/PKG-INFO +1 -1
- searchlibrium-0.0.153/src/SearchLibrium/version.txt +0 -1
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/MANIFEST.in +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/README.md +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/setup.cfg +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/BEHier.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/Halton.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/MixedLogit.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/RandomP.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/Two_Level_Nest.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/__main__.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/_choice_model.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/_device.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/banditsa.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/bhhh/minimize.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/boxcox_functions.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/call_meta.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/constraints_builder.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/data/Swissmetro_final.csv +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/data/TravelMode.csv +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/data/electricity.csv +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/hspbil.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/latent_class.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/main.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/main_debug.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/mdcev.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/misc.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/mixed_logit.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/mixed_nested.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/mixedrrm.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/multinomial_logit.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/multinomial_nested.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/multinomial_probit.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/ordered_logit.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/ordered_logit_mixed.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/predict.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/rrm.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/sample_data.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/sapbil.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/search.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/selection_models.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/setup.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/siman.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/test_lc_de.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/test_mario_searches.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/threshold.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/requires.txt +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/top_level.txt +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/data_generator/demonstrate_generation.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/data_generator/fit_recovery.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/data_generator/latent_class_gen.py +0 -0
- {searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/data_generator/print_synthetic_data.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SearchLibrium
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.155
|
|
4
4
|
Summary: A Python package for econometric models driven by search
|
|
5
5
|
Author: Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
|
|
6
6
|
Author-email: Zeke Ahern <z.ahern@qut.edu.au>
|
|
@@ -82,7 +82,7 @@ Documentation = "https://pypi.org/project/SearchLibrium/"
|
|
|
82
82
|
realpython = "SearchLibrium.__main__:main"
|
|
83
83
|
|
|
84
84
|
[tool.bumpver]
|
|
85
|
-
current_version = "0.0.
|
|
85
|
+
current_version = "0.0.155"
|
|
86
86
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
87
87
|
commit_message = "[skip ci] Bump version {old_version} -> {new_version}"
|
|
88
88
|
commit = true
|
|
@@ -11,6 +11,16 @@ Usage:
|
|
|
11
11
|
mxl = MixedLogitGSE()
|
|
12
12
|
mxl.setup(..., gradient_scores=g_avg, random_gamma=False)
|
|
13
13
|
mxl.fit()
|
|
14
|
+
|
|
15
|
+
Larch equivalence (kept in sync with test_runs_tours stage-5 mode model):
|
|
16
|
+
The model β_nk = μ_k + γ_k·g_nk + σ_k·η_nk decomposes term-by-term into a
|
|
17
|
+
plain Larch mixed logit, since β_nk multiplies x_k in the utility:
|
|
18
|
+
μ_k·x_k → ordinary fixed utility term P('c_k') * X('x_k')
|
|
19
|
+
γ_k·(g_nk·x_k) → systematic gradient interaction P('g_k') * X('x_k * g')
|
|
20
|
+
σ_k·(η_nk·x_k) → Normal random coefficient mixtures.append(Normal('c_k','s_k'))
|
|
21
|
+
random_gamma=True adds τ_k·z_nk·g_nk, i.e. promoting the γ_k loadings to
|
|
22
|
+
random coefficients too (Normal mixtures on the g_k params in the Larch build).
|
|
23
|
+
See stage5_destination_choice._estimate_mixed_logit for the mirrored build.
|
|
14
24
|
"""
|
|
15
25
|
|
|
16
26
|
import numpy as np
|
|
@@ -37,13 +47,24 @@ class MixedLogitGSE(MixedLogit):
|
|
|
37
47
|
def setup(self, *args, gradient_scores=None, random_gamma=False, **kwargs):
|
|
38
48
|
self.random_gamma = bool(random_gamma)
|
|
39
49
|
if gradient_scores is not None:
|
|
40
|
-
# Standardise to O(1)
|
|
50
|
+
# Standardise each gradient column to mean 0 / std 1 (O(1)) so the
|
|
51
|
+
# γ loadings are on a common scale and can't numerically overflow.
|
|
52
|
+
# Centering matters: an uncentred score folds a spurious γ·mean/std
|
|
53
|
+
# shift into μ; centring keeps μ interpretable as the population mean.
|
|
54
|
+
# A constant (zero-variance) column would divide by ~0 and blow up to
|
|
55
|
+
# ~1e8 — guard it by leaving such columns at 0 (they carry no gradient
|
|
56
|
+
# information anyway).
|
|
41
57
|
g = np.asarray(gradient_scores, dtype=float)
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
gmu = g.mean(axis=0, keepdims=True)
|
|
59
|
+
gsd = g.std(axis=0, keepdims=True)
|
|
60
|
+
gsd_safe = np.where(gsd < 1e-8, 1.0, gsd)
|
|
61
|
+
self.gradient_scores = (g - gmu) / gsd_safe
|
|
62
|
+
n_const = int(np.sum(gsd < 1e-8))
|
|
44
63
|
print(f"[MixedLogitGSE] Gradient loadings enabled (Kgrad={len(kwargs.get('randvars', {}))}, "
|
|
45
64
|
f"random_gamma={self.random_gamma}, "
|
|
46
|
-
f"
|
|
65
|
+
f"raw std range=[{float(gsd.min()):.2f}, {float(gsd.max()):.2f}] -> "
|
|
66
|
+
f"centred+standardised"
|
|
67
|
+
+ (f", {n_const} constant column(s) zeroed" if n_const else "") + ")")
|
|
47
68
|
else:
|
|
48
69
|
self.gradient_scores = None
|
|
49
70
|
super().setup(*args, **kwargs)
|
|
@@ -87,7 +108,14 @@ class MixedLogitGSE(MixedLogit):
|
|
|
87
108
|
self.Kgrad = self.Kr
|
|
88
109
|
self.Kgrad_w = self.Kr if self.random_gamma else 0
|
|
89
110
|
if self.Kgrad_w > 0:
|
|
90
|
-
|
|
111
|
+
# Seed the random-γ (τ·z) draws so a fit is reproducible across
|
|
112
|
+
# runs — unseeded np.random.randn made every fit non-deterministic
|
|
113
|
+
# (and non-comparable in a search). Reuse the model's own seed
|
|
114
|
+
# when set, mixing in Kgrad so it differs from the η draws' seed.
|
|
115
|
+
_seed = getattr(self, "seed", None)
|
|
116
|
+
rng = np.random.default_rng(None if _seed is None
|
|
117
|
+
else int(_seed) + 10007 * self.Kgrad)
|
|
118
|
+
self.gamma_draws = rng.standard_normal((self.N, self.Kgrad))
|
|
91
119
|
# Force JAX-only (scipy fallback doesn't handle gradient loadings)
|
|
92
120
|
self._jax = True
|
|
93
121
|
super().fit()
|
|
@@ -106,6 +106,7 @@ try:
|
|
|
106
106
|
from .latent_class import LatentClassMixedLogit
|
|
107
107
|
from .mdcev import MDCEVFitResult, MDCEVModel
|
|
108
108
|
from .multinomial_probit import MultinomialProbit
|
|
109
|
+
from .MixedLogitGSE import MixedLogitGSE
|
|
109
110
|
from .RandomP import RandomParameters
|
|
110
111
|
from .constraints_builder import ConstraintBuilder, create_constraints
|
|
111
112
|
from .search import Parameters
|
|
@@ -131,6 +132,7 @@ except ImportError as e:
|
|
|
131
132
|
from latent_class import LatentClassMixedLogit
|
|
132
133
|
from mdcev import MDCEVFitResult, MDCEVModel
|
|
133
134
|
from multinomial_probit import MultinomialProbit
|
|
135
|
+
from MixedLogitGSE import MixedLogitGSE
|
|
134
136
|
from RandomP import RandomParameters
|
|
135
137
|
from constraints_builder import ConstraintBuilder, create_constraints
|
|
136
138
|
from search import Parameters
|
|
@@ -949,10 +949,11 @@ class HarmonySearch(Search):
|
|
|
949
949
|
"""Identify groups of variables that measure similar constructs
|
|
950
950
|
and can be substituted for one another."""
|
|
951
951
|
groups = []
|
|
952
|
-
# Group 1: destination size measures
|
|
952
|
+
# Group 1: destination size measures (now includes per-type ACDC)
|
|
953
953
|
size_measures = [v for v in asvars
|
|
954
954
|
if v in {'ln_dest_trips', 'osm_destination_pull',
|
|
955
|
-
'acdc_aggl', 'osm_poi_intensity'}
|
|
955
|
+
'acdc_aggl', 'osm_poi_intensity'}
|
|
956
|
+
or v.startswith('acdc_aggl_')]
|
|
956
957
|
for i in range(len(size_measures)):
|
|
957
958
|
for j in range(i + 1, len(size_measures)):
|
|
958
959
|
groups.append((size_measures[i], size_measures[j]))
|
|
@@ -972,6 +973,25 @@ class HarmonySearch(Search):
|
|
|
972
973
|
for j in range(i + 1, len(osm_measures)):
|
|
973
974
|
groups.append((osm_measures[i], osm_measures[j]))
|
|
974
975
|
|
|
976
|
+
# Group 4: Per-type ACDC agglomeration terms (substitutable by OSM type)
|
|
977
|
+
per_type_aggl = [v for v in asvars if v.startswith('acdc_aggl_')]
|
|
978
|
+
for i in range(len(per_type_aggl)):
|
|
979
|
+
for j in range(i + 1, len(per_type_aggl)):
|
|
980
|
+
groups.append((per_type_aggl[i], per_type_aggl[j]))
|
|
981
|
+
|
|
982
|
+
# Group 5: Per-type ACDC competition terms (substitutable by OSM type)
|
|
983
|
+
per_type_comp = [v for v in asvars if v.startswith('acdc_comp_')]
|
|
984
|
+
for i in range(len(per_type_comp)):
|
|
985
|
+
for j in range(i + 1, len(per_type_comp)):
|
|
986
|
+
groups.append((per_type_comp[i], per_type_comp[j]))
|
|
987
|
+
|
|
988
|
+
# Group 6: Cross-substitution — agglomeration <-> competition for same type
|
|
989
|
+
for t in ['retail', 'food', 'leisure', 'parks', 'transit', 'cycleway', 'culture']:
|
|
990
|
+
aggl_var = f'acdc_aggl_{t}'
|
|
991
|
+
comp_var = f'acdc_comp_{t}'
|
|
992
|
+
if aggl_var in asvars and comp_var in asvars:
|
|
993
|
+
groups.append((aggl_var, comp_var))
|
|
994
|
+
|
|
975
995
|
return groups
|
|
976
996
|
|
|
977
997
|
def _get_forced_vars(self):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.155
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: SearchLibrium
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.155
|
|
4
4
|
Summary: A Python package for econometric models driven by search
|
|
5
5
|
Author: Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
|
|
6
6
|
Author-email: Zeke Ahern <z.ahern@qut.edu.au>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.0.153
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium/test_sapbil_vs_banditsa.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/SearchLibrium.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{searchlibrium-0.0.153 → searchlibrium-0.0.155}/src/data_generator/demonstrate_generation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|