|
|
@@ -1,25 +1,54 @@
|
|
|
"""
|
|
|
- Providing class for logistic regression utilities with polynomial
|
|
|
+ The file provides a class for logistic regression utilities with polynomial
|
|
|
logit (log odds) function:
|
|
|
|
|
|
- p(x|pars) = 1/(1 + exp(-F(x|b(pars))))
|
|
|
+ p(x|pars) = 1/(1 + exp(-F(x|beta(pars))))
|
|
|
|
|
|
with log odds F of polynomial form:
|
|
|
|
|
|
- F(x|b) = sum_{i=0}^degree b_i x^i
|
|
|
+ F(x|beta) = sum_{j=0}^degree beta_j x^j
|
|
|
|
|
|
with decision function (aka logit) F and parameters
|
|
|
|
|
|
- b(pars) = [b(pars)_i]_{i=0}^degree
|
|
|
+ beta(pars) = [beta(pars)_j]_{j=0}^degree
|
|
|
|
|
|
- where pars are regression parameters. Coefficients
|
|
|
- b(pars) can be constrained to be monotonic function of x by using
|
|
|
- monotonic cubic transformation:
|
|
|
+ where pars are regression parameters, len(pars) = degree + 1.
|
|
|
+
|
|
|
+ Coefficients beta(pars) can be constrained to be monotonic
|
|
|
+ function of x by using monotonic cubic transformation:
|
|
|
|
|
|
- b(pars) = mc.forward_map(pars)
|
|
|
+ beta(pars) = mc.forward_map(pars)
|
|
|
|
|
|
where mc is module mono_cubic2.
|
|
|
|
|
|
+ NOTES: The model defines the conditional probability
|
|
|
+
|
|
|
+ Prob(Y = y|x, pars) = 1/(1 + exp(-s(y) F(x| beta(pars))))
|
|
|
+
|
|
|
+ where
|
|
|
+
|
|
|
+ s(y) = 2*y - 1
|
|
|
+
|
|
|
+ with x in R and y in {0,1}. For degree = 1 this is standard logistic regression
|
|
|
+
|
|
|
+ beta(pars) = (pars[0], pars[1]).
|
|
|
+
|
|
|
+ For degree = 3 and mono = True the coefficients beta(pars) are constrained to be
|
|
|
+ monotonic by using monotonic cubic transformation.
|
|
|
+
|
|
|
+ We have data
|
|
|
+
|
|
|
+ {(x_i, y_i) : x_i in R, y_i in {0,1}, i = 0, ..., n-1 }
|
|
|
+
|
|
|
+ and the model is fit to data by minimizing negative log-likelihood function:
|
|
|
+
|
|
|
+ nlff = -sum_i log(Prob(Y = y_i| x_i, pars)) : neg. log likelihood
|
|
|
+
|
|
|
+ with respect to parameters pars. We can have regularization term in cost function
|
|
|
+ and this case we minimize cost function:
|
|
|
+
|
|
|
+ cost(pars) = nllf(pars) + lambda ||pars||^2
|
|
|
+
|
|
|
Author: Martin Horvat, January 2026
|
|
|
"""
|
|
|
|
|
|
@@ -80,11 +109,11 @@ def safe_expit(x, max_exp = 700): return 1/(1 + safe_exp(-x, max_exp))
|
|
|
|
|
|
to model function
|
|
|
|
|
|
- f(x|pars) = 1/(1 + exp(-F(x|beta))) beta = beta(pars)
|
|
|
+ f(x|pars) = 1/(1 + exp(-F(x|beta(pars))))
|
|
|
|
|
|
with log odds of polynomial form:
|
|
|
|
|
|
- log(f(x|pars)/(1 - f(x|pars))) = F(x|beta) beta = beta(pars)
|
|
|
+ log(f(x|pars)/(1 - f(x|pars))) = F(x| beta(pars))
|
|
|
|
|
|
where F is decision function (aka logit)
|
|
|
|
|
|
@@ -92,7 +121,7 @@ def safe_expit(x, max_exp = 700): return 1/(1 + safe_exp(-x, max_exp))
|
|
|
|
|
|
and coefficients
|
|
|
|
|
|
- beta = [beta_i(pars)]_{i=0}^degrees
|
|
|
+ beta(pars) = [beta_i(pars)]_{i=0}^degrees
|
|
|
|
|
|
Conditional probability
|
|
|
|
|
|
@@ -100,17 +129,17 @@ def safe_expit(x, max_exp = 700): return 1/(1 + safe_exp(-x, max_exp))
|
|
|
|
|
|
with
|
|
|
|
|
|
- s(y) = 2*y -1
|
|
|
+ s(y) = 2*y -1
|
|
|
"""
|
|
|
class LogisticPolyRegression:
|
|
|
|
|
|
"""
|
|
|
- Constructor
|
|
|
+ Class constructor.
|
|
|
|
|
|
Input:
|
|
|
degree: int, degree of polynomial
|
|
|
mono: boolean, default False
|
|
|
- lambda: None or tuple float, L1 and L2 regularization
|
|
|
+ lambda: None or tuple float, L2 regularization
|
|
|
|
|
|
"""
|
|
|
def __init__(self, degree = 1, mono = False, lam = None):
|
|
|
@@ -286,8 +315,7 @@ class LogisticPolyRegression:
|
|
|
return (val[0] + pen[0], val[1] + pen[1]) if jac else val + pen
|
|
|
|
|
|
return val
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
"""
|
|
|
Estimate parameters.
|
|
|
|
|
|
@@ -376,7 +404,9 @@ class LogisticPolyRegression:
|
|
|
thresh: float, default 0.5, threshold value for classification
|
|
|
|
|
|
Return:
|
|
|
- {"n": n, "k":k, "dof":n-k,
|
|
|
+ {"n": n,
|
|
|
+ "k": r,
|
|
|
+ "dof": n - r,
|
|
|
"LLF": log_likelihood,
|
|
|
"AIC": AIC,
|
|
|
"BIC": BIC,
|
|
|
@@ -421,7 +451,8 @@ class LogisticPolyRegression:
|
|
|
"n": n, "k": k, "dof": dof}
|
|
|
|
|
|
"""
|
|
|
- Calculation of asymptotic variance-covariance matrix of parameters pars
|
|
|
+ Calculation of asymptotic variance-covariance matrix of regression
|
|
|
+ parameters pars
|
|
|
|
|
|
cov_{asymp}[pars] = H^{-1}
|
|
|
|
|
|
@@ -441,8 +472,8 @@ class LogisticPolyRegression:
|
|
|
array of rxr floats; r = degree + 1
|
|
|
|
|
|
Ref:
|
|
|
- https://stats.stackexchange.com/questions/89484/how-to-compute-the-standard-errors-of-a-logistic-regressions-coefficients
|
|
|
- https://goodboychan.github.io/machine_learning/2020/09/14/02-Regularized-likelihood-methods.html
|
|
|
+ * https://stats.stackexchange.com/questions/89484/how-to-compute-the-standard-errors-of-a-logistic-regressions-coefficients
|
|
|
+ * https://goodboychan.github.io/machine_learning/2020/09/14/02-Regularized-likelihood-methods.html
|
|
|
"""
|
|
|
def cov(self, x, y, pars):
|
|
|
|
|
|
@@ -478,7 +509,6 @@ class LogisticPolyRegression:
|
|
|
# covariance matrix C_params = H^-1
|
|
|
return np.linalg.inv(H)
|
|
|
|
|
|
-
|
|
|
"""
|
|
|
Calculating quantiles of the model parameters at given probabilities p
|
|
|
for normal distribution of parameters:
|