Linear regression model
A linear regression model is defined as follows:
Using matrix notation, we can express it as:
Given observations (or training data)
By setting
When
So, we modifiy the loss function with
therefore
If we let w = np.linalg.solve(A, b)
in Python.
Here is an implementation in Python:
class LinearRegressor:
def __init__(self, alpha=1.0e-2, intercept=True):
self.alpha = alpha
self.intercept = intercept
self.w = None
def fit(self, X, y):
# _X : # (N, D)
_X = np.hstack([np.ones(len(X)).reshape(-1, 1), X]) if self.intercept else X
_, D = _X.shape
# _y : (N, 1)
_y = y.reshape(-1, 1) if y.ndim == 1 else y
# w = A^{-1} b : (D, 1)
A = (_X.T @ _X) + self.alpha * np.eye(D) # (D, D)
b = _X.T @ _y # (D, 1)
self.w = np.linalg.solve(A, b)
return self
def predict(self, X):
_X = np.hstack([np.ones(len(X)).reshape(-1, 1), X]) if self.intercept else X
return (_X @ self.w).ravel() # (N, )
A visualization with simulated data. The true surface is colored as red, the prediction surface is colored as blue, and red points are observations (training data).
Data was generated as follows:
import numpy as np
## The number of data
N = 30
## The number of data dimensions
D = 2
## The true function
def f_true(X):
return np.sin(X[:, 0]) + (1 / (1 + np.exp(-X[:, 1])))
## Observations
X = np.random.uniform(low=-np.pi, high=np.pi, size=(N, D))
y = f_true(X) + np.random.normal(scale=1.0, size=(N,))
## Build and train a model
lr = LinearRegressor(intercept=True).fit(X, y)
The graph was generated as follows:
# Visualization
import plotly.graph_objects as go
## Preparation
r = np.pi
g = np.linspace(-r, r)
xx1, xx2 = np.meshgrid(g, g)
G = np.vstack([xx1.ravel(), xx2.ravel()]).T
zz = lr.predict(G).reshape(len(g), len(g))
zz_true = f_true(G).reshape(len(g), len(g))
## Plot
fig = go.Figure(
data=[
# Prediction surface
go.Surface(
x=xx1,
y=xx2,
z=zz,
colorscale="Blues",
showscale=False,
opacity=0.5,
),
# True surface
go.Surface(
x=xx1,
y=xx2,
z=zz_true,
colorscale="Reds",
showscale=False,
opacity=0.5,
),
# Observations
go.Scatter3d(
x=X[:, 0],
y=X[:, 1],
z=y,
mode="markers",
marker=dict(size=1, color="red"),
),
]
)
fig.update_layout(
autosize=False,
margin=dict(l=0, r=0, t=0, b=0),
scene=dict(
xaxis=dict(title="x1"),
yaxis=dict(title="x2"),
zaxis=dict(title="y"),
),
showlegend=False,
)
fig.show()
Discussion