Skip to content

Commit b537fac

Browse files
authored
1 parent 4f37707 commit b537fac

File tree

1 file changed

+23
-8
lines changed
  • numpy_ml/linear_models

1 file changed

+23
-8
lines changed

numpy_ml/linear_models/lm.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,18 +166,30 @@ def __init__(self, penalty="l2", gamma=0, fit_intercept=True):
166166
\left(
167167
\sum_{i=0}^N y_i \log(\hat{y}_i) +
168168
(1-y_i) \log(1-\hat{y}_i)
169-
\right) - \frac{\gamma}{2} ||\mathbf{b}||_2
169+
\right) - R(\mathbf{b}, \gamma)
170170
\right]
171-
172-
where :math:`\gamma` is a regularization weight, `N` is the number of
173-
examples in **y**, and **b** is the vector of model coefficients.
171+
172+
where
173+
174+
.. math::
175+
176+
R(\mathbf{b}, \gamma) = \left\{
177+
\begin{array}{lr}
178+
\frac{\gamma}{2} ||\mathbf{beta}||_2^2 & :\texttt{ penalty = 'l2'}\\
179+
\gamma ||\beta||_1 & :\texttt{ penalty = 'l1'}
180+
\end{array}
181+
\right.
182+
183+
is a regularization penalty, :math:`\gamma` is a regularization weight,
184+
`N` is the number of examples in **y**, and **b** is the vector of model
185+
coefficients.
174186
175187
Parameters
176188
----------
177189
penalty : {'l1', 'l2'}
178190
The type of regularization penalty to apply on the coefficients
179191
`beta`. Default is 'l2'.
180-
gamma : float in [0, 1]
192+
gamma : float
181193
The regularization weight. Larger values correspond to larger
182194
regularization penalties, and a value of 0 indicates no penalty.
183195
Default is 0.
@@ -235,21 +247,24 @@ def _NLL(self, X, y, y_pred):
235247
\text{NLL} = -\frac{1}{N} \left[
236248
\left(
237249
\sum_{i=0}^N y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i)
238-
\right) - \frac{\gamma}{2} ||\mathbf{b}||_2
250+
\right) - R(\mathbf{b}, \gamma)
239251
\right]
240252
"""
241253
N, M = X.shape
254+
beta, gamma = self.beta, self.gamma
242255
order = 2 if self.penalty == "l2" else 1
256+
norm_beta = np.linalg.norm(beta, ord=order)
257+
243258
nll = -np.log(y_pred[y == 1]).sum() - np.log(1 - y_pred[y == 0]).sum()
244-
penalty = 0.5 * self.gamma * np.linalg.norm(self.beta, ord=order) ** 2
259+
penalty = (gamma / 2) * norm_beta ** 2 if order == 2 else gamma * norm_beta
245260
return (penalty + nll) / N
246261

247262
def _NLL_grad(self, X, y, y_pred):
248263
"""Gradient of the penalized negative log likelihood wrt beta"""
249264
N, M = X.shape
250265
l1norm = lambda x: np.linalg.norm(x, 1) # noqa: E731
251266
p, beta, gamma = self.penalty, self.beta, self.gamma
252-
d_penalty = gamma * beta if p == "l2" else gamma * l1norm(beta) * np.sign(beta)
267+
d_penalty = gamma * beta if p == "l2" else gamma * np.sign(beta)
253268
return -(np.dot(y - y_pred, X) + d_penalty) / N
254269

255270
def predict(self, X):

0 commit comments

Comments
 (0)