Skip to content

Commit

Permalink
Updated linear.py with new argument names and module docstring
Browse files Browse the repository at this point in the history
Signed-off-by: Ayush Joshi <[email protected]>
  • Loading branch information
joshiayush committed Nov 22, 2023
1 parent 0e96d8e commit d5d2da1
Showing 1 changed file with 54 additions and 73 deletions.
127 changes: 54 additions & 73 deletions ai/linear_model/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,107 +13,87 @@
# limitations under the License.
# pylint: disable=too-many-function-args, invalid-name, missing-module-docstring
# pylint: disable=missing-class-docstring
"""A numpy-compatible linear regression implementation.
from typing import Union
#### Example
```python
import numpy as np
from sklearn import datasets
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
class LinearRegression:
"""`LinearRegression` fits a linear model with coefficients w = (w1, ..., wp)
to minimize the residual sum of squares between the observed targets in the
dataset, and the targets predicted by the linear approximation.
Hypothesis function for our `LinearRegression` :math:`\\hat y = b + wX`, where
`b` is the model's intercept and `w` is the coefficient of `X`.
The cost function or the loss function that we use is the Mean Squared Error
(MSE) between the predicted value and the true value. The cost function `(J)`
can be written as:
.. math::
J = \\dfrac{1}{m}\\sum_{i=1}^{n}(\\hat y_{i} - y_{i})^2
from ai.linear_model import LinearRegression
To achieve the best-fit regression line, the model aims to predict the target
value :math:`\\hat Y` such that the error difference between the predicted
value :math:`\\hat Y` and the true value :math:`Y` is minimum. So, it is very
important to update the `b` and `w` values, to reach the best value that
minimizes the error between the predicted `y` value and the true `y` value.
X, y = datasets.make_regression(
n_samples=100, n_features=1, noise=20, random_state=4
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
A linear regression model can be trained using the optimization algorithm
gradient descent by iteratively modifying the model’s parameters to reduce the
mean squared error (MSE) of the model on a training dataset. To update `b` and
`w` values in order to reduce the Cost function (minimizing RMSE value) and
achieve the best-fit line the model uses Gradient Descent. The idea is to
start with random `b` and `w` values and then iteratively update the values,
reaching minimum cost.
model = LinearRegression()
model.fit(X_train, y_train)
On differentiating cost function `J` with respect to `b`:
y_pred = model.predict(X_test)
.. math::
print(accuracy_score(y_pred, y_test))
```
"""

\\dfrac{dJ}{db} = \\dfrac{2}{n} \\cdot \\sum_{i=1}^{n}(
\\hat y_{i} - y_{i}
)
On differentiating cost function `J` with respect to `w`:
.. math::
from typing import Union

\\dfrac{dJ}{dw} = \\dfrac{2}{n} \\cdot \\sum_{i=1}^{n}(
\\hat y_{i} - y_{i}
) \\cdot x_{i}
import numpy as np

The above derivative functions are used for updating `weights` and `bias` in
each iteration.

Args:
lr: Model's learning rate. High value might over shoot the minimum loss,
while low values might make the model to take forever to learn.
n_iters: Maximum number of updations to make over the weights and bias in
order to reach to a effecient prediction that minimizes the loss.
class LinearRegression:
"""`LinearRegression` fits a linear model with coefficients w = (w1, ..., wp)
to minimize the residual sum of squares between the observed targets in the
dataset, and the targets predicted by the linear approximation.
"""
def __init__(self, *, lr: np.float16 = .01, n_iters: int = 1000):
def __init__(self, *, alpha: np.float16 = .01, n_iters: int = 1000):
"""Initializes model's `learning rate` and number of `iterations`.
Args:
lr: Model's learning rate. High value might over shoot the minimum loss,
while low values might make the model to take forever to learn.
alpha: Model's learning rate. High value might over shoot the minimum
loss, while low values might make the model to take forever to learn.
n_iters: Maximum number of updations to make over the weights and bias in
order to reach to a effecient prediction that minimizes the loss.
"""
self._lr = lr
self._alpha = alpha
self._n_iters = n_iters
self._is_fitted = False
self._bias = None
self._weights = None

def fit(self, X: np.ndarray, y: np.ndarray) -> None:
def fit(self, X: np.ndarray, y: np.ndarray) -> 'LinearRegression':
"""Fit the linear model on `X` given `y`.
Hypothesis function for our `LinearRegression` :math:`\\hat y = b + wX`, where
`b` is the model's intercept and `w` is the coefficient of `X`.
Hypothesis function for our `LinearRegression` :math:`\\hat y = b + wX`,
where `b` is the model's intercept and `w` is the coefficient of `X`.
The cost function or the loss function that we use is the Mean Squared Error
(MSE) between the predicted value and the true value. The cost function `(J)`
can be written as:
(MSE) between the predicted value and the true value. The cost function
`(J)` can be written as:
.. math::
J = \\dfrac{1}{m}\\sum_{i=1}^{n}(\\hat y_{i} - y_{i})^2
To achieve the best-fit regression line, the model aims to predict the target
value :math:`\\hat Y` such that the error difference between the predicted
value :math:`\\hat Y` and the true value :math:`Y` is minimum. So, it is very
important to update the `b` and `w` values, to reach the best value that
minimizes the error between the predicted `y` value and the true `y` value.
To achieve the best-fit regression line, the model aims to predict the
target value :math:`\\hat Y` such that the error difference between the
predicted value :math:`\\hat Y` and the true value :math:`Y` is minimum. So,
it is very important to update the `b` and `w` values, to reach the best
value that minimizes the error between the predicted `y` value and the true
`y` value.
A linear regression model can be trained using the optimization algorithm
gradient descent by iteratively modifying the model’s parameters to reduce the
mean squared error (MSE) of the model on a training dataset. To update `b` and
`w` values in order to reduce the Cost function (minimizing RMSE value) and
achieve the best-fit line the model uses Gradient Descent. The idea is to
start with random `b` and `w` values and then iteratively update the values,
reaching minimum cost.
gradient descent by iteratively modifying the model’s parameters to reduce
the mean squared error (MSE) of the model on a training dataset. To update
`b` and `w` values in order to reduce the Cost function (minimizing RMSE
value) and achieve the best-fit line the model uses Gradient Descent. The
idea is to start with random `b` and `w` values and then iteratively update
the values, reaching minimum cost.
On differentiating cost function `J` with respect to `b`:
Expand All @@ -135,7 +115,8 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> None:
each iteration.
Args:
X: Sample vector.
X: Training vectors, where `n_samples` is the number of samples and
`n_features` is the number of features.
y: Target vector.
"""
self._bias = 0
Expand All @@ -147,10 +128,10 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> None:
bias_d = 1 / X[0] * np.sum((y_pred - y))
weights_d = 1 / X[0] * np.dot(X.T, (y_pred - y))

self._bias = self._bias - (self._lr * bias_d)
self._weights = self._weights - (self._lr * weights_d)
self._bias = self._bias - (self._alpha * bias_d)
self._weights = self._weights - (self._alpha * weights_d)

self._is_fitted = True
return self

def predict(self, X: np.ndarray) -> np.ndarray:
"""Predict for `X` using the previously calculated `weights` and `bias`.
Expand All @@ -166,7 +147,7 @@ def predict(self, X: np.ndarray) -> np.ndarray:
ValueError: If shape of the given `X` differs from the shape of the `X`
given to the `fit` function.
"""
if self._is_fitted is False:
if self._weights is None or self._bias is None:
raise RuntimeError(
f'{self.__class__.__name__}: predict called before fitting data'
)
Expand Down

0 comments on commit d5d2da1

Please sign in to comment.