-
Notifications
You must be signed in to change notification settings - Fork 8
Added binomial model #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
f08b18b
6490976
7768d00
333934f
5bce344
e0cba0c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,62 @@ | ||||||
| export binomial_model | ||||||
|
|
||||||
| """ | ||||||
| nlp_model, nls_model = binomial_model(A, b) | ||||||
|
|
||||||
| Return an instance of an `NLPModel` representing the binomial logistic regression | ||||||
| problem, and an `NLSModel` representing the system of equations formed by its gradient. | ||||||
|
|
||||||
| Minimize f(x) = sum(log(1+exp(a_i^T x)) - y_i a_i^T x) | ||||||
| where y_i in {0, 1}. | ||||||
|
|
||||||
| The NLS residual is defined as the gradient of f(x): | ||||||
| F(x) = A (p - b) | ||||||
| where p = sigmoid(A' x). | ||||||
| """ | ||||||
| function binomial_model(A, b) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| m, n = size(A) # m features, n samples | ||||||
|
|
||||||
| # Pre-allocate buffers | ||||||
| Ax = zeros(n) | ||||||
| p = zeros(n) | ||||||
| w = zeros(n) | ||||||
| tmp_n = zeros(n) | ||||||
|
|
||||||
| function resid!(r, x) | ||||||
| mul!(Ax, A', x) | ||||||
| @. p = 1.0 / (1.0 + exp(-Ax)) | ||||||
| @. tmp_n = p - b | ||||||
| mul!(r, A, tmp_n) | ||||||
| return r | ||||||
| end | ||||||
|
|
||||||
| function jacv!(Jv, x, v) | ||||||
| mul!(Ax, A', x) | ||||||
| @. w = 1.0 / (1.0 + exp(-Ax)) | ||||||
| @. w = w * (1.0 - w) | ||||||
|
|
||||||
| mul!(tmp_n, A', v) | ||||||
| @. tmp_n *= w | ||||||
| mul!(Jv, A, tmp_n) | ||||||
| return Jv | ||||||
| end | ||||||
|
|
||||||
| function jactv!(Jtv, x, v) | ||||||
| jacv!(Jtv, x, v) | ||||||
| end | ||||||
|
|
||||||
| function obj(x) | ||||||
| mul!(Ax, A', x) | ||||||
| # Stable computation of log(1+exp(z)) - b*z | ||||||
| return sum(@. (Ax > 0) * ((1 - b) * Ax + log(1 + exp(-Ax))) + (Ax <= 0) * (log(1 + exp(Ax)) - b * Ax)) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m a bit confused. If this is a nonlinear least-squares problem, the objective should be |
||||||
| end | ||||||
|
|
||||||
| function grad!(g, x) | ||||||
| resid!(g, x) | ||||||
| end | ||||||
|
|
||||||
| x0 = zeros(m) | ||||||
|
|
||||||
| return FirstOrderModel(obj, grad!, x0, name="Binomial"), | ||||||
| FirstOrderNLSModel(resid!, jacv!, jactv!, m, x0) | ||||||
| end | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand now, but it’s a bit confusing because the two models don’t represent the same problem. I suggest returning the NLPModel only. For that, you only need implement
objandgrad!. If I understand well, the currentjacv!andjactv!are actuallyhprod!(the product between the Hessian and a vector), hence why they are the same.It would be easy to write a generic wrapper to minimize$\tfrac{1}{2} \Vert \nabla f(x)\Vert^2$ for any given NLPModel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saravkin I think what you want to do is the following:
Your problems isn't a least-squares problem, so you only return the
NLPModel.