import matplotlib.pyplot as plt
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import numpy as np
Geometric interpretation of Linear Regression
ML
from latexify import latexify, format_axes
=2) latexify(columns
# Define points
= (1, 3)
A = (2, 1)
B = (0, 0)
Origin
# Plot vectors
*Origin, *A, angles='xy', scale_units='xy', scale=1, color='b', label='$v_1$')
plt.quiver(*Origin, *B, angles='xy', scale_units='xy', scale=1, color='r', label='$v_2$')
plt.quiver(
# Set axis limits
-2, 4)
plt.xlim(-2, 4)
plt.ylim(
# Add legend
plt.legend()
# Show plot
=0.1)
plt.grid(alpha
= plt.gca()
ax
format_axes(ax)'equal')
ax.set_aspect('../figures/linear-regression/geoemetric-span-1.pdf', bbox_inches='tight') plt.savefig(
# Now, create v3 = v1 + v2 and v4 = v1 - v2 and plot
= (A[0] + B[0], A[1] + B[1])
C = (A[0] - B[0], A[1] - B[1])
D
# Set axis limits
-2, 4)
plt.xlim(-2, 4)
plt.ylim(
*Origin, *A, angles='xy', scale_units='xy', scale=1, color='b', label='$v_1$')
plt.quiver(*Origin, *B, angles='xy', scale_units='xy', scale=1, color='r', label='$v_2$')
plt.quiver(*Origin, *C, angles='xy', scale_units='xy', scale=1, color='g', label='$v_3$')
plt.quiver(*Origin, *D, angles='xy', scale_units='xy', scale=1, color='y', label='$v_4$')
plt.quiver(
= plt.gca()
ax
format_axes(ax)
plt.legend()
'equal')
ax.set_aspect('../figures/linear-regression/geoemetric-span-2.pdf', bbox_inches='tight') plt.savefig(
= np.array(A)
A_arr = np.array(B)
B_arr
= np.zeros((2, 2))
AB_matrix # First column is A, second column is B
0] = A_arr
AB_matrix[:, 1] = B_arr
AB_matrix[:,
print(AB_matrix)
[[1. 2.]
[3. 1.]]
def new_vector(AB_matrix, alpha):
return AB_matrix @ alpha
print(new_vector(AB_matrix, np.array([1, -1])))
[-1. 2.]
# Generate a bunch of alphas
= np.random.uniform(-3, 3, size=(30000, 2))
alphas = []
new_vecs for i, alpha in enumerate(alphas):
new_vecs.append(new_vector(AB_matrix, alpha))
= np.array(new_vecs) new_vecs
= new_vecs
t 0], t[:, 1], alpha=0.2)
plt.scatter(t[:, -3, 3)
plt.xlim(-3, 3)
plt.ylim(= plt.gca()
ax
format_axes(ax)'equal')
ax.set_aspect('../figures/linear-regression/geoemetric-span-3.pdf', bbox_inches='tight') plt.savefig(
= np.array([1, 2])
A = np.array([2, 4])
B
= np.zeros((2, 2))
AB_matrix # First column is A, second column is B
0] = A
AB_matrix[:, 1] = B
AB_matrix[:,
print(AB_matrix)
[[1. 2.]
[2. 4.]]
# Generate a bunch of alphas
= np.random.uniform(-3, 3, size=(10000, 2))
alphas = []
new_vecs for i, alpha in enumerate(alphas):
new_vecs.append(new_vector(AB_matrix, alpha))
= np.array(new_vecs)
new_vecs
0], new_vecs[:, 1], alpha=0.2, s=2)
plt.scatter(new_vecs[:, = plt.gca()
ax -3, 3)
plt.xlim(-3, 3)
plt.ylim(
format_axes(ax)'equal')
ax.set_aspect('../figures/linear-regression/geoemetric-span-4.pdf', bbox_inches='tight') plt.savefig(
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
# Create a figure and 3D axis
= plt.figure(figsize=(8, 6))
fig = fig.add_subplot(111, projection='3d')
ax
# Define the surface plot
= np.linspace(0, 2.2, 100)
X = np.linspace(-2.2, 1, 100)
Y = np.meshgrid(X, Y)
X, Y = X
Z
# Plot the surface
= ax.plot_surface(X, Y, Z, alpha=0.3, rstride=100, cstride=100)
surf
# Define points
= np.array([1, 1, 1])
A = np.array([0, 0, 0])
D = np.array([2, -2, 2])
B
# Mark the origin
*D, color='black', label='Origin')
ax.scatter(
# Plot vectors with labels including the vector
0], D[1], D[2], A[0], A[1], A[2], color='b', label=f'$X_1 = {A.tolist()}$', arrow_length_ratio=0.1)
ax.quiver(D[0], D[1], D[2], B[0], B[1], B[2], color='r', label=f'$X_2 = {B.tolist()}$', arrow_length_ratio=0.1)
ax.quiver(D[
# Set axis labels
'$x$', fontsize=12)
ax.set_xlabel('$y$', fontsize=12)
ax.set_ylabel('$z$', fontsize=12)
ax.set_zlabel(
# Set legend
ax.legend()
# Adjust view angle
=15, azim=-35)
ax.view_init(elev
# Customize grid lines
='dashed', color='white', alpha=0.2) # Adjust color here
ax.grid(linestyle
"../figures/linear-regression/geometric-1.pdf", bbox_inches='tight') plt.savefig(
# Create a figure and 3D axis
= plt.figure(figsize=(8, 6))
fig = fig.add_subplot(111, projection='3d')
ax
# Define the surface plot
= np.linspace(0, 10.2, 300)
X = np.linspace(-5, 5, 300)
Y = np.meshgrid(X, Y)
X, Y = X
Z
# Plot the surface
= ax.plot_surface(X, Y, Z, alpha=0.3, rstride=100, cstride=100,)
surf
# Define points
= np.array([1, 1, 1])
A = np.array([0, 0, 0])
D = np.array([2, -2, 2])
B = np.array([8.8957, 0.6130, 1.7761])
y_vec
# Mark the origin
*D, color='black', label='Origin')
ax.scatter(
# Plot vectors with labels including the vector
0], D[1], D[2], A[0], A[1], A[2], color='b', label=f'$X_1 = {A.tolist()}$', arrow_length_ratio=0.1)
ax.quiver(D[0], D[1], D[2], B[0], B[1], B[2], color='r', label=f'$X_2 = {B.tolist()}$', arrow_length_ratio=0.1)
ax.quiver(D[0], D[1], D[2], y_vec[0], y_vec[1], y_vec[2], color='g', label=f'$y = {y_vec.tolist()}$', arrow_length_ratio=0.1)
ax.quiver(D[
# Set axis labels
'$x$', fontsize=12)
ax.set_xlabel('$y$', fontsize=12)
ax.set_ylabel('$z$', fontsize=12)
ax.set_zlabel(
# Set legend
ax.legend()
# Adjust view angle
=15, azim=-35)
ax.view_init(elev
# Customize grid lines
='dashed', color='white', alpha=0.2) # Adjust color here
ax.grid(linestyle
"../figures/linear-regression/geometric-2.pdf", bbox_inches="tight")
plt.savefig(
= np.zeros((3, 2))
X_matrix 0] = A
X_matrix[:, 1] = B
X_matrix[:,
print(X_matrix)
= np.linalg.inv(X_matrix.T @ X_matrix) @ X_matrix.T @ y_vec
theta_hat
print(theta_hat)
= X_matrix @ theta_hat
y_hat print(y_hat)
# Plot y_hat vector
0], D[1], D[2], y_hat[0], y_hat[1], y_hat[2], color='y', label=f'$\hat y = {list(map(lambda x: round(x, 4), y_hat))}$', arrow_length_ratio=0.1)
ax.quiver(D[
plt.legend()"../figures/linear-regression/geometric-3.pdf", bbox_inches="tight")
plt.savefig(
# perpendiculat vector
= y_vec - y_hat
perp_vec # Plot perp vector with y_hat as origin
0], y_hat[1], y_hat[2], perp_vec[0], perp_vec[1], perp_vec[2], color='m', label=f'$y - \hat y = {list(map(lambda x: round(x, 4), perp_vec))}$', arrow_length_ratio=0.1)
ax.quiver(y_hat[
plt.legend()"../figures/linear-regression/geometric-4.pdf", bbox_inches="tight") plt.savefig(
[[ 1. 2.]
[ 1. -2.]
[ 1. 2.]]
[2.97445 1.180725]
[5.3359 0.613 5.3359]
perp_vec
array([ 3.5598, 0. , -3.5598])
0] X_matrix[:,
array([1., 1., 1.])
@X_matrix[:, 0] perp_vec
-1.3322676295501878e-15
@X_matrix[:, 1] perp_vec
-2.6645352591003757e-15
@ perp_vec X_matrix.T
array([-1.33226763e-15, -2.66453526e-15])