SearchLibrium 0.0.201__tar.gz → 0.0.203__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.201/src/SearchLibrium.egg-info → searchlibrium-0.0.203}/PKG-INFO +1 -1
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/pyproject.toml +1 -1
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/__init__.py +3 -3
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/latent_class.py +24 -4
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixedrrm.py +4 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/ordered_logit.py +752 -2
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/ordered_logit_mixed.py +4 -10
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/search.py +226 -12
- searchlibrium-0.0.203/src/SearchLibrium/version.txt +1 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203/src/SearchLibrium.egg-info}/PKG-INFO +1 -1
- searchlibrium-0.0.201/src/SearchLibrium/version.txt +0 -1
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/LICENSE +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/MANIFEST.in +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/README.md +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/setup.cfg +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/BEHier.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Halton.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/MixedLogit.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/MixedLogitGSE.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/RandomP.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Two_Level_Nest.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/__main__.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/_choice_model.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/_device.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/banditsa.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/boxcox_functions.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/call_meta.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/constraints_builder.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/Swissmetro_final.csv +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/TravelMode.csv +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/electricity.csv +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/harmony.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/hspbil.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/logistic_regression.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/main.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/main_debug.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mdcev.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/misc.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixed_logit.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixed_nested.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_logit.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_nested.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_probit.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/predict.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/rrm.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sample_data.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sapbil.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/selection_models.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/setup.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/siman.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sparseea_agds.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_lc_de.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_mario_searches.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/threshold.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/zero_inflated_ordered_probit.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/requires.txt +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/top_level.txt +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/tests/test_per_alternative_random.py +0 -0
- {searchlibrium-0.0.201 → searchlibrium-0.0.203}/tests/test_zero_inflated_ordered_probit.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.203
|
|
4
4
|
Summary: Automated specification search for discrete choice models (logit, mixed logit, nested logit, RRM and more) using metaheuristic optimisation
|
|
5
5
|
Author: Mario Fernando Taco Morales, Alexander Paz, Prithvi Beeramole, Robert Burdett
|
|
6
6
|
Author-email: Zeke Ahern <z.ahern@qut.edu.au>
|
|
@@ -100,7 +100,7 @@ Documentation = "https://pypi.org/project/SearchLibrium/"
|
|
|
100
100
|
realpython = "SearchLibrium.__main__:main"
|
|
101
101
|
|
|
102
102
|
[tool.bumpver]
|
|
103
|
-
current_version = "0.0.
|
|
103
|
+
current_version = "0.0.203"
|
|
104
104
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
105
105
|
commit_message = "[skip ci] Bump version {old_version} -> {new_version}"
|
|
106
106
|
commit = true
|
|
@@ -116,7 +116,7 @@ try:
|
|
|
116
116
|
from .Halton import Halton
|
|
117
117
|
from .rrm import RandomRegret
|
|
118
118
|
from .mixedrrm import MixedRandomRegret
|
|
119
|
-
from .ordered_logit import OrderedLogit, OrderedLogitLong
|
|
119
|
+
from .ordered_logit import OrderedLogit, OrderedLogitLong, ExplodedLogit, MixedExplodedLogit
|
|
120
120
|
from .selection_models import BinaryProbit, HeckmanTwoStep
|
|
121
121
|
from .zero_inflated_ordered_probit import ZeroInflatedOrderedProbit, ZeroInflatedProbit
|
|
122
122
|
from .latent_class import LatentClassMixedLogit
|
|
@@ -146,7 +146,7 @@ except ImportError as e:
|
|
|
146
146
|
from Halton import Halton
|
|
147
147
|
from rrm import RandomRegret
|
|
148
148
|
from mixedrrm import MixedRandomRegret
|
|
149
|
-
from ordered_logit import OrderedLogit, OrderedLogitLong
|
|
149
|
+
from ordered_logit import OrderedLogit, OrderedLogitLong, ExplodedLogit
|
|
150
150
|
from selection_models import BinaryProbit, HeckmanTwoStep
|
|
151
151
|
from zero_inflated_ordered_probit import ZeroInflatedOrderedProbit, ZeroInflatedProbit
|
|
152
152
|
from latent_class import LatentClassMixedLogit
|
|
@@ -173,7 +173,7 @@ __all__ = [
|
|
|
173
173
|
"DiscreteChoiceModel",
|
|
174
174
|
"MultinomialLogit", "LogisticRegression", "MixedLogit",
|
|
175
175
|
"NestedLogit", "MultiLayerNestedLogit", "MixedNested", "Halton",
|
|
176
|
-
"RandomRegret", "MixedRandomRegret", "OrderedLogit", "OrderedLogitLong",
|
|
176
|
+
"RandomRegret", "MixedRandomRegret", "OrderedLogit", "OrderedLogitLong", "ExplodedLogit", "MixedExplodedLogit",
|
|
177
177
|
"BinaryProbit", "HeckmanTwoStep",
|
|
178
178
|
"ZeroInflatedOrderedProbit", "ZeroInflatedProbit",
|
|
179
179
|
"LatentClassMixedLogit", "MDCEVFitResult", "MDCEVModel", "MultinomialProbit",
|
|
@@ -105,7 +105,7 @@ class LatentClassMixedLogit(DiscreteChoiceModel):
|
|
|
105
105
|
def setup(self, X, y, varnames, ids, alts, avail=None, fit_intercept=False,
|
|
106
106
|
membership_vars=None, member_params_spec=None,
|
|
107
107
|
class_params_spec=None, l1_penalty=None, l2_penalty=None,
|
|
108
|
-
panels=None):
|
|
108
|
+
sd_penalty=None, panels=None):
|
|
109
109
|
X = np.asarray(X, dtype=float)
|
|
110
110
|
y = np.asarray(y, dtype=float)
|
|
111
111
|
ids = np.asarray(ids)
|
|
@@ -131,6 +131,8 @@ class LatentClassMixedLogit(DiscreteChoiceModel):
|
|
|
131
131
|
self.l1_penalty = float(l1_penalty)
|
|
132
132
|
if l2_penalty is not None:
|
|
133
133
|
self.l2_penalty = float(l2_penalty)
|
|
134
|
+
if sd_penalty is not None:
|
|
135
|
+
self.sd_penalty = float(sd_penalty)
|
|
134
136
|
|
|
135
137
|
order = np.lexsort((alts, ids))
|
|
136
138
|
X = X[order]
|
|
@@ -613,10 +615,22 @@ class LatentClassMixedLogit(DiscreteChoiceModel):
|
|
|
613
615
|
|
|
614
616
|
def objective(beta):
|
|
615
617
|
value, grad = grad_fn(self.jnp.asarray(beta), weights_backend)
|
|
616
|
-
l2 = self.l2_penalty * float(self.jnp.sum(self.jnp.
|
|
618
|
+
l2 = self.l2_penalty * float(self.jnp.sum(self.jnp.sum(beta)))
|
|
617
619
|
l1 = self.l1_penalty * float(self.jnp.sum(self.jnp.abs(beta)))
|
|
620
|
+
# sd_penalty on br_w (SD) parameters - they are at the end of each class's beta vector
|
|
621
|
+
sd = 0.0
|
|
622
|
+
if hasattr(self, 'sd_penalty') and self.sd_penalty > 0:
|
|
623
|
+
# Find Kbw (number of SD params) for this class
|
|
624
|
+
# br_w params are the last Kbw params in the class beta vector
|
|
625
|
+
if self._class_specs is not None and class_idx is not None:
|
|
626
|
+
K = X_c.shape[2] # Kf + Kr for this class
|
|
627
|
+
# Assuming Kr random params => Kbw = Kr (uncorrelated) or Kr - correlationLength (correlated)
|
|
628
|
+
# For simplicity, use the last Kbw params where Kbw = number of random params
|
|
629
|
+
Kbw = getattr(self, '_Kbw', getattr(self, 'Kr', 0))
|
|
630
|
+
if Kbw > 0 and len(beta) >= Kbw:
|
|
631
|
+
sd = self.sd_penalty * float(self.jnp.sum(self.jnp.square(beta[-Kbw:])))
|
|
618
632
|
grad_l1 = self._regularize_l1_grad(np.asarray(beta))
|
|
619
|
-
return float(value) + l2 + l1, np.asarray(grad, dtype=float) + 2.0 * self.l2_penalty * np.asarray(beta) + grad_l1
|
|
633
|
+
return float(value) + l2 + l1 + sd, np.asarray(grad, dtype=float) + 2.0 * self.l2_penalty * np.asarray(beta) + grad_l1
|
|
620
634
|
else:
|
|
621
635
|
def objective(beta):
|
|
622
636
|
utilities = np.einsum("njk,k->nj", X_c, beta)
|
|
@@ -630,7 +644,13 @@ class LatentClassMixedLogit(DiscreteChoiceModel):
|
|
|
630
644
|
grad = np.einsum("nj,njk->k", diff, X_c)
|
|
631
645
|
l2 = self.l2_penalty * float(np.sum(beta * beta))
|
|
632
646
|
l1 = self.l1_penalty * float(np.sum(np.abs(beta)))
|
|
633
|
-
|
|
647
|
+
# sd_penalty on br_w (SD) parameters
|
|
648
|
+
sd = 0.0
|
|
649
|
+
if hasattr(self, 'sd_penalty') and self.sd_penalty > 0:
|
|
650
|
+
Kbw = getattr(self, '_Kbw', getattr(self, 'Kr', 0))
|
|
651
|
+
if Kbw > 0 and len(beta) >= Kbw:
|
|
652
|
+
sd = self.sd_penalty * float(np.sum(np.square(beta[-Kbw:])))
|
|
653
|
+
return -loglik + l2 + l1 + sd, -grad + 2.0 * self.l2_penalty * beta + self._regularize_l1_grad(beta)
|
|
634
654
|
|
|
635
655
|
result = minimize(
|
|
636
656
|
objective,
|
|
@@ -11,6 +11,10 @@ class MixedRandomRegret(RandomRegret, MixedLogit):
|
|
|
11
11
|
RandomRegret.__init__(self, **kwargs)
|
|
12
12
|
MixedLogit.__init__(self, halton_opts=halton_opts, distributions=distributions)
|
|
13
13
|
self.fn_generate_draws = self.generate_draws_halton
|
|
14
|
+
# Store penalty parameters for use in fit
|
|
15
|
+
self.reg_penalty = getattr(self, 'reg_penalty', 0.5)
|
|
16
|
+
self.l1_penalty = getattr(self, 'l1_penalty', 0.1)
|
|
17
|
+
self.sd_penalty = getattr(self, 'sd_penalty', 0.001)
|
|
14
18
|
|
|
15
19
|
def _n(self):
|
|
16
20
|
return getattr(self, 'N', getattr(self, 'nb_samples', 0))
|