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.
Files changed (65) hide show
  1. {searchlibrium-0.0.201/src/SearchLibrium.egg-info → searchlibrium-0.0.203}/PKG-INFO +1 -1
  2. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/pyproject.toml +1 -1
  3. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/__init__.py +3 -3
  4. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/latent_class.py +24 -4
  5. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixedrrm.py +4 -0
  6. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/ordered_logit.py +752 -2
  7. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/ordered_logit_mixed.py +4 -10
  8. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/search.py +226 -12
  9. searchlibrium-0.0.203/src/SearchLibrium/version.txt +1 -0
  10. {searchlibrium-0.0.201 → searchlibrium-0.0.203/src/SearchLibrium.egg-info}/PKG-INFO +1 -1
  11. searchlibrium-0.0.201/src/SearchLibrium/version.txt +0 -1
  12. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/LICENSE +0 -0
  13. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/MANIFEST.in +0 -0
  14. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/README.md +0 -0
  15. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/setup.cfg +0 -0
  16. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/BEHier.py +0 -0
  17. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Halton.py +0 -0
  18. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/MixedLogit.py +0 -0
  19. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/MixedLogitGSE.py +0 -0
  20. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Mode_Activity_Nested.py +0 -0
  21. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/RandomP.py +0 -0
  22. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/SEARCH_SM_MARIO.py +0 -0
  23. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/Two_Level_Nest.py +0 -0
  24. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/__main__.py +0 -0
  25. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/_choice_model.py +0 -0
  26. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/_device.py +0 -0
  27. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/banditsa.py +0 -0
  28. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/boxcox_functions.py +0 -0
  29. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/call_meta.py +0 -0
  30. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/constraints_builder.py +0 -0
  31. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/Swissmetro_final.csv +0 -0
  32. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/TravelMode.csv +0 -0
  33. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/data/electricity.csv +0 -0
  34. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/harmony.py +0 -0
  35. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/hspbil.py +0 -0
  36. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/logistic_regression.py +0 -0
  37. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/main.py +0 -0
  38. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/main_debug.py +0 -0
  39. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mdcev.py +0 -0
  40. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/misc.py +0 -0
  41. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixed_logit.py +0 -0
  42. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/mixed_nested.py +0 -0
  43. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_logit.py +0 -0
  44. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_nested.py +0 -0
  45. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/multinomial_probit.py +0 -0
  46. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/predict.py +0 -0
  47. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/rrm.py +0 -0
  48. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sample_data.py +0 -0
  49. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sapbil.py +0 -0
  50. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/selection_models.py +0 -0
  51. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/setup.py +0 -0
  52. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/siman.py +0 -0
  53. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/sparseea_agds.py +0 -0
  54. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_lc_de.py +0 -0
  55. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_mario_searches.py +0 -0
  56. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/test_sapbil_vs_banditsa.py +0 -0
  57. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/threshold.py +0 -0
  58. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium/zero_inflated_ordered_probit.py +0 -0
  59. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/SOURCES.txt +0 -0
  60. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/dependency_links.txt +0 -0
  61. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/entry_points.txt +0 -0
  62. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/requires.txt +0 -0
  63. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/src/SearchLibrium.egg-info/top_level.txt +0 -0
  64. {searchlibrium-0.0.201 → searchlibrium-0.0.203}/tests/test_per_alternative_random.py +0 -0
  65. {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.201
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.201"
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.square(beta)))
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
- return -loglik + l2 + l1, -grad + 2.0 * self.l2_penalty * beta + self._regularize_l1_grad(beta)
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))