psolr 0.1.0__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.
psolr-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.4
2
+ Name: psolr
3
+ Version: 0.1.0
4
+ Summary: Metaheuristic-Optimized Logistic Regression (PSO-LR / MOLR)
5
+ Home-page: https://github.com/JEET-123/pso-logistic-regression
6
+ Author: Koustav Dutta
7
+ Author-email: Koustav Dutta <koustavdutta.dgp@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/JEET-123/pso-logistic-regression
10
+ Project-URL: Repository, https://github.com/JEET-123/pso-logistic-regression
11
+ Project-URL: Issues, https://github.com/yourusername/pso-logistic-regression/issues
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: numpy>=1.20
19
+ Requires-Dist: scikit-learn>=1.2
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # PSO-LR: Metaheuristic-Optimized Logistic Regression (MOLR)
25
+
26
+ **PSO-LR** is an open-source, sklearn-compatible implementation of
27
+ **Metaheuristic-Optimized Logistic Regression (MOLR)**, where model parameters
28
+ are estimated using **Particle Swarm Optimization (PSO)** instead of
29
+ gradient-based solvers.
30
+
31
+ This framework preserves the classical interpretability of logistic regression
32
+ while improving robustness, global convergence behavior, and stability in
33
+ noisy or ill-conditioned datasets.
34
+
35
+ ---
36
+
37
+ ## Motivation
38
+
39
+ Traditional logistic regression relies on gradient-based optimization
40
+ (LBFGS, Newton-CG, SGD). These methods can struggle when data exhibits:
41
+
42
+ - Multicollinearity
43
+ - Noisy or sparse signals
44
+ - Poor conditioning
45
+ - Strong regularization requirements
46
+
47
+ PSO-LR replaces gradient descent with a **population-based global optimizer**,
48
+ making it suitable for:
49
+
50
+ - Marketing analytics
51
+ - Choice modeling
52
+ - Behavioral modeling
53
+ - Econometrics
54
+ - High-noise real-world datasets
55
+
56
+ ---
57
+
58
+ ## Key Features
59
+
60
+ - Binary & Multinomial Logistic Regression
61
+ - Particle Swarm Optimization (PSO)
62
+ - Early stopping for efficiency
63
+ - L1 / L2 regularization
64
+ - Hard coefficient constraints
65
+ - Fully sklearn-compatible API
66
+ - Interpretable coefficients & odds ratios
67
+ - Domain-independent design
68
+
69
+ ---
70
+
71
+ ## Mathematical Formulation
72
+
73
+ The logistic model remains unchanged:
74
+
75
+ \[
76
+ P(y=1|x) = \sigma(x^\top \beta)
77
+ \]
78
+
79
+ The regularized negative log-likelihood is optimized using PSO:
80
+
81
+ \[
82
+ \min_{\beta} \; -\mathcal{L}(\beta) + \lambda \Omega(\beta)
83
+ \]
84
+
85
+ PSO searches the parameter space globally without requiring gradients,
86
+ ensuring robust convergence.
87
+
88
+ ---
89
+
90
+ ## Installation
91
+
92
+ ```bash
93
+ pip install psolr
psolr-0.1.0/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # PSO-LR: Metaheuristic-Optimized Logistic Regression (MOLR)
2
+
3
+ **PSO-LR** is an open-source, sklearn-compatible implementation of
4
+ **Metaheuristic-Optimized Logistic Regression (MOLR)**, where model parameters
5
+ are estimated using **Particle Swarm Optimization (PSO)** instead of
6
+ gradient-based solvers.
7
+
8
+ This framework preserves the classical interpretability of logistic regression
9
+ while improving robustness, global convergence behavior, and stability in
10
+ noisy or ill-conditioned datasets.
11
+
12
+ ---
13
+
14
+ ## Motivation
15
+
16
+ Traditional logistic regression relies on gradient-based optimization
17
+ (LBFGS, Newton-CG, SGD). These methods can struggle when data exhibits:
18
+
19
+ - Multicollinearity
20
+ - Noisy or sparse signals
21
+ - Poor conditioning
22
+ - Strong regularization requirements
23
+
24
+ PSO-LR replaces gradient descent with a **population-based global optimizer**,
25
+ making it suitable for:
26
+
27
+ - Marketing analytics
28
+ - Choice modeling
29
+ - Behavioral modeling
30
+ - Econometrics
31
+ - High-noise real-world datasets
32
+
33
+ ---
34
+
35
+ ## Key Features
36
+
37
+ - Binary & Multinomial Logistic Regression
38
+ - Particle Swarm Optimization (PSO)
39
+ - Early stopping for efficiency
40
+ - L1 / L2 regularization
41
+ - Hard coefficient constraints
42
+ - Fully sklearn-compatible API
43
+ - Interpretable coefficients & odds ratios
44
+ - Domain-independent design
45
+
46
+ ---
47
+
48
+ ## Mathematical Formulation
49
+
50
+ The logistic model remains unchanged:
51
+
52
+ \[
53
+ P(y=1|x) = \sigma(x^\top \beta)
54
+ \]
55
+
56
+ The regularized negative log-likelihood is optimized using PSO:
57
+
58
+ \[
59
+ \min_{\beta} \; -\mathcal{L}(\beta) + \lambda \Omega(\beta)
60
+ \]
61
+
62
+ PSO searches the parameter space globally without requiring gradients,
63
+ ensuring robust convergence.
64
+
65
+ ---
66
+
67
+ ## Installation
68
+
69
+ ```bash
70
+ pip install psolr
@@ -0,0 +1,3 @@
1
+ from .model import PSOLogisticRegression
2
+
3
+ __all__ = ["PSOLogisticRegression"]
@@ -0,0 +1,201 @@
1
+ """
2
+ Metaheuristic-Optimized Logistic Regression (MOLR / PSO-LR)
3
+ =========================================================
4
+
5
+ Author: Koustav Dutta (PhD Research)
6
+ License: MIT
7
+
8
+ Description:
9
+ ------------
10
+ A fully sklearn-compatible Logistic Regression model where
11
+ parameter estimation is performed using Particle Swarm Optimization (PSO)
12
+ instead of gradient-based solvers.
13
+ """
14
+
15
+ import numpy as np
16
+ from sklearn.base import BaseEstimator, ClassifierMixin
17
+ from sklearn.preprocessing import LabelBinarizer
18
+
19
+
20
+ class PSOLogisticRegression(BaseEstimator, ClassifierMixin):
21
+ """
22
+ Metaheuristic-Optimized Logistic Regression (MOLR / PSO-LR)
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ penalty="l2",
28
+ C=1.0,
29
+ pop_size=40,
30
+ max_iter=200,
31
+ inertia=0.7,
32
+ c1=1.5,
33
+ c2=1.5,
34
+ tol=1e-4,
35
+ patience=10,
36
+ bounds=None,
37
+ random_state=None,
38
+ multi_class="auto"
39
+ ):
40
+ self.penalty = penalty
41
+ self.C = C
42
+ self.pop_size = pop_size
43
+ self.max_iter = max_iter
44
+ self.inertia = inertia
45
+ self.c1 = c1
46
+ self.c2 = c2
47
+ self.tol = tol
48
+ self.patience = patience
49
+ self.bounds = bounds
50
+ self.random_state = random_state
51
+ self.multi_class = multi_class
52
+
53
+ # ------------------------------------------------------------------
54
+ # Utility Functions
55
+ # ------------------------------------------------------------------
56
+
57
+ def _sigmoid(self, z):
58
+ return 1.0 / (1.0 + np.exp(-z))
59
+
60
+ def _softmax(self, z):
61
+ z = z - np.max(z, axis=1, keepdims=True)
62
+ exp_z = np.exp(z)
63
+ return exp_z / exp_z.sum(axis=1, keepdims=True)
64
+
65
+ def _apply_bounds(self, particles):
66
+ if self.bounds is None:
67
+ return particles
68
+ low, high = self.bounds
69
+ return np.clip(particles, low, high)
70
+
71
+ # ------------------------------------------------------------------
72
+ # Loss Functions
73
+ # ------------------------------------------------------------------
74
+
75
+ def _binary_loss(self, beta, X, y):
76
+ logits = X @ beta
77
+ p = self._sigmoid(logits)
78
+ eps = 1e-9
79
+
80
+ loss = -np.mean(
81
+ y * np.log(p + eps) + (1 - y) * np.log(1 - p + eps)
82
+ )
83
+
84
+ if self.penalty == "l2":
85
+ loss += 0.5 * np.sum(beta ** 2) / self.C
86
+ elif self.penalty == "l1":
87
+ loss += np.sum(np.abs(beta)) / self.C
88
+
89
+ return loss
90
+
91
+ def _multinomial_loss(self, theta, X, Y):
92
+ B = theta.reshape(self.n_classes_, self.n_features_)
93
+ logits = X @ B.T
94
+ P = self._softmax(logits)
95
+ eps = 1e-9
96
+
97
+ loss = -np.mean(np.sum(Y * np.log(P + eps), axis=1))
98
+ loss += 0.5 * np.sum(B ** 2) / self.C
99
+
100
+ return loss
101
+
102
+ # ------------------------------------------------------------------
103
+ # PSO Optimizer with Early Stopping
104
+ # ------------------------------------------------------------------
105
+
106
+ def _pso_optimize(self, loss_fn, dim):
107
+ rng = np.random.default_rng(self.random_state)
108
+
109
+ particles = rng.normal(0, 0.1, size=(self.pop_size, dim))
110
+ velocities = rng.normal(0, 0.01, size=(self.pop_size, dim))
111
+
112
+ particles = self._apply_bounds(particles)
113
+
114
+ personal_best = particles.copy()
115
+ personal_scores = np.array([loss_fn(p) for p in particles])
116
+
117
+ global_best = personal_best[np.argmin(personal_scores)]
118
+ global_score = np.min(personal_scores)
119
+
120
+ no_improve = 0
121
+
122
+ for _ in range(self.max_iter):
123
+ for i in range(self.pop_size):
124
+ r1, r2 = rng.random(), rng.random()
125
+
126
+ velocities[i] = (
127
+ self.inertia * velocities[i]
128
+ + self.c1 * r1 * (personal_best[i] - particles[i])
129
+ + self.c2 * r2 * (global_best - particles[i])
130
+ )
131
+
132
+ particles[i] += velocities[i]
133
+ particles[i] = self._apply_bounds(particles[i])
134
+
135
+ score = loss_fn(particles[i])
136
+
137
+ if score < personal_scores[i]:
138
+ personal_best[i] = particles[i]
139
+ personal_scores[i] = score
140
+
141
+ new_global_score = np.min(personal_scores)
142
+
143
+ if abs(global_score - new_global_score) < self.tol:
144
+ no_improve += 1
145
+ if no_improve >= self.patience:
146
+ break
147
+ else:
148
+ no_improve = 0
149
+
150
+ global_best = personal_best[np.argmin(personal_scores)]
151
+ global_score = new_global_score
152
+
153
+ return global_best
154
+
155
+ # ------------------------------------------------------------------
156
+ # sklearn API
157
+ # ------------------------------------------------------------------
158
+
159
+ def fit(self, X, y):
160
+ X = np.asarray(X)
161
+ y = np.asarray(y)
162
+
163
+ self.n_features_ = X.shape[1]
164
+
165
+ if self.multi_class == "auto":
166
+ self.multi_class_ = "multinomial" if len(np.unique(y)) > 2 else "binary"
167
+ else:
168
+ self.multi_class_ = self.multi_class
169
+
170
+ if self.multi_class_ == "binary":
171
+ self.classes_ = np.array([0, 1])
172
+ loss_fn = lambda b: self._binary_loss(b, X, y)
173
+ self.coef_ = self._pso_optimize(loss_fn, self.n_features_)
174
+
175
+ else:
176
+ lb = LabelBinarizer()
177
+ Y = lb.fit_transform(y)
178
+ self.classes_ = lb.classes_
179
+ self.n_classes_ = Y.shape[1]
180
+
181
+ dim = self.n_classes_ * self.n_features_
182
+ loss_fn = lambda t: self._multinomial_loss(t, X, Y)
183
+
184
+ theta = self._pso_optimize(loss_fn, dim)
185
+ self.coef_ = theta.reshape(self.n_classes_, self.n_features_)
186
+
187
+ return self
188
+
189
+ def predict_proba(self, X):
190
+ X = np.asarray(X)
191
+
192
+ if self.multi_class_ == "binary":
193
+ p = self._sigmoid(X @ self.coef_)
194
+ return np.vstack([1 - p, p]).T
195
+
196
+ logits = X @ self.coef_.T
197
+ return self._softmax(logits)
198
+
199
+ def predict(self, X):
200
+ probs = self.predict_proba(X)
201
+ return self.classes_[np.argmax(probs, axis=1)]
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.4
2
+ Name: psolr
3
+ Version: 0.1.0
4
+ Summary: Metaheuristic-Optimized Logistic Regression (PSO-LR / MOLR)
5
+ Home-page: https://github.com/JEET-123/pso-logistic-regression
6
+ Author: Koustav Dutta
7
+ Author-email: Koustav Dutta <koustavdutta.dgp@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/JEET-123/pso-logistic-regression
10
+ Project-URL: Repository, https://github.com/JEET-123/pso-logistic-regression
11
+ Project-URL: Issues, https://github.com/yourusername/pso-logistic-regression/issues
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: numpy>=1.20
19
+ Requires-Dist: scikit-learn>=1.2
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # PSO-LR: Metaheuristic-Optimized Logistic Regression (MOLR)
25
+
26
+ **PSO-LR** is an open-source, sklearn-compatible implementation of
27
+ **Metaheuristic-Optimized Logistic Regression (MOLR)**, where model parameters
28
+ are estimated using **Particle Swarm Optimization (PSO)** instead of
29
+ gradient-based solvers.
30
+
31
+ This framework preserves the classical interpretability of logistic regression
32
+ while improving robustness, global convergence behavior, and stability in
33
+ noisy or ill-conditioned datasets.
34
+
35
+ ---
36
+
37
+ ## Motivation
38
+
39
+ Traditional logistic regression relies on gradient-based optimization
40
+ (LBFGS, Newton-CG, SGD). These methods can struggle when data exhibits:
41
+
42
+ - Multicollinearity
43
+ - Noisy or sparse signals
44
+ - Poor conditioning
45
+ - Strong regularization requirements
46
+
47
+ PSO-LR replaces gradient descent with a **population-based global optimizer**,
48
+ making it suitable for:
49
+
50
+ - Marketing analytics
51
+ - Choice modeling
52
+ - Behavioral modeling
53
+ - Econometrics
54
+ - High-noise real-world datasets
55
+
56
+ ---
57
+
58
+ ## Key Features
59
+
60
+ - Binary & Multinomial Logistic Regression
61
+ - Particle Swarm Optimization (PSO)
62
+ - Early stopping for efficiency
63
+ - L1 / L2 regularization
64
+ - Hard coefficient constraints
65
+ - Fully sklearn-compatible API
66
+ - Interpretable coefficients & odds ratios
67
+ - Domain-independent design
68
+
69
+ ---
70
+
71
+ ## Mathematical Formulation
72
+
73
+ The logistic model remains unchanged:
74
+
75
+ \[
76
+ P(y=1|x) = \sigma(x^\top \beta)
77
+ \]
78
+
79
+ The regularized negative log-likelihood is optimized using PSO:
80
+
81
+ \[
82
+ \min_{\beta} \; -\mathcal{L}(\beta) + \lambda \Omega(\beta)
83
+ \]
84
+
85
+ PSO searches the parameter space globally without requiring gradients,
86
+ ensuring robust convergence.
87
+
88
+ ---
89
+
90
+ ## Installation
91
+
92
+ ```bash
93
+ pip install psolr
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ psolr/__init__.py
5
+ psolr/model.py
6
+ psolr.egg-info/PKG-INFO
7
+ psolr.egg-info/SOURCES.txt
8
+ psolr.egg-info/dependency_links.txt
9
+ psolr.egg-info/requires.txt
10
+ psolr.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ numpy>=1.20
2
+ scikit-learn>=1.2
@@ -0,0 +1 @@
1
+ psolr
@@ -0,0 +1,31 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "psolr"
7
+ version = "0.1.0"
8
+ description = "Metaheuristic-Optimized Logistic Regression (PSO-LR / MOLR)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "Koustav Dutta", email = "koustavdutta.dgp@gmail.com"}
14
+ ]
15
+
16
+ dependencies = [
17
+ "numpy>=1.20",
18
+ "scikit-learn>=1.2"
19
+ ]
20
+
21
+ classifiers = [
22
+ "Programming Language :: Python :: 3",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Intended Audience :: Science/Research",
25
+ "Topic :: Scientific/Engineering :: Artificial Intelligence"
26
+ ]
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/JEET-123/pso-logistic-regression"
30
+ Repository = "https://github.com/JEET-123/pso-logistic-regression"
31
+ Issues = "https://github.com/yourusername/pso-logistic-regression/issues"
psolr-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
psolr-0.1.0/setup.py ADDED
@@ -0,0 +1,30 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="psolr",
5
+ version="0.1.0",
6
+ author="Koustav Dutta",
7
+ author_email="koustavdutta.dgp@gmail.com",
8
+ description="Metaheuristic-Optimized Logistic Regression using Particle Swarm Optimization",
9
+ long_description=open("README.md", encoding="utf-8").read(),
10
+ long_description_content_type="text/markdown",
11
+ url="https://github.com/JEET-123/pso-logistic-regression",
12
+ packages=find_packages(),
13
+ python_requires=">=3.8",
14
+ install_requires=[
15
+ "numpy>=1.20",
16
+ "scikit-learn>=1.2"
17
+ ],
18
+ classifiers=[
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Intended Audience :: Science/Research/Management/Corporate",
23
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
24
+ "Topic :: Scientific/Engineering :: Information Analysis",
25
+ "Topic :: Scientific/Engineering :: Machine Learning",
26
+ "Topic :: Scientific/Engineering :: Metaheurestic Algorithms",
27
+ "Topic :: Scientific/Engineering :: Neuroevolutionary Algorithm"
28
+ ],
29
+ license="MIT",
30
+ )