In [1]:
# Code attribution: Yiyin Shen, Tyler Caraza-Harter
# Imports
import sklearn
import sklearn.linear_model
import sklearn.datasets
import sklearn.inspection
import scipy.special
import numpy
import seaborn
import matplotlib.pyplot as plt
In [2]:
# Create a random dataset with two blobs
x, y = sklearn.datasets.make_moons(n_samples = 50, noise = 0.25, random_state = 42)
seaborn.relplot(x = x[:, 0], y = x[:, 1], hue = y)
Out[2]:
<seaborn.axisgrid.FacetGrid at 0x16d97e2f510>
In [3]:
# Logistic Regression
lr = sklearn.linear_model.LogisticRegression()
lr.fit(x, y)
plot = sklearn.inspection.DecisionBoundaryDisplay.from_estimator(lr, x, response_method = "predict_proba")
plot.ax_.scatter(x[:, 0], x[:, 1], c = y, edgecolor = "black")
Out[3]:
<matplotlib.collections.PathCollection at 0x16dd9c3b550>
In [4]:
# Plot the surface representing the probability prediction function
X, Y = numpy.meshgrid(numpy.arange(-3, 3, 0.1), numpy.arange(-3, 3, 0.1))
Z = scipy.special.expit(X * lr.coef_[0, 0] + Y * lr.coef_[0, 1] + lr.intercept_)
fig = plt.figure()
ax = fig.add_subplot(projection = "3d")
ax.plot_surface(X, Y, Z)
ax.view_init(45, 225)
In [5]:
# Plot the points again with labels
plot = sklearn.inspection.DecisionBoundaryDisplay.from_estimator(lr, x, response_method = "predict_proba")
plot.ax_.scatter(x[:, 0], x[:, 1], c = y, edgecolor = "black")
for i in range(10):
plot.ax_.text(x[i, 0], x[i, 1], str(i + 1), backgroundcolor = "black", color = "white", ha = "center", va = "center")
In [6]:
# Output the probability predictions
lr.predict_proba(x[0:10])
Out[6]:
array([[0.89446916, 0.10553084], [0.10044569, 0.89955431], [0.54765317, 0.45234683], [0.13455494, 0.86544506], [0.93221762, 0.06778238], [0.28619664, 0.71380336], [0.55352796, 0.44647204], [0.80242794, 0.19757206], [0.34959954, 0.65040046], [0.79166657, 0.20833343]])
In [7]:
# Shape of first ten rows of x and the coefficients
x[0:10], numpy.transpose(lr.coef_), lr.intercept_
Out[7]:
(array([[-0.16558082, 0.98314651], [ 1.07154991, -0.66052133], [ 0.44385737, 0.28645122], [ 1.77398267, 0.09389116], [-0.90705099, 0.69109036], [ 1.87975949, 0.75053422], [ 0.08930509, 0.02111957], [-0.54458356, 0.2390259 ], [ 0.434412 , -0.21230365], [-0.60688845, 0.14961562]]), array([[ 1.30379768], [-1.65273129]]), array([-0.29646629]))
In [8]:
# Use matrix operations to get the same predictions
p1 = 1 / (1 + numpy.exp(- (x[0:10] @ numpy.transpose(lr.coef_) + lr.intercept_)))
numpy.hstack([1 - p1, p1])
Out[8]:
array([[0.89446916, 0.10553084], [0.10044569, 0.89955431], [0.54765317, 0.45234683], [0.13455494, 0.86544506], [0.93221762, 0.06778238], [0.28619664, 0.71380336], [0.55352796, 0.44647204], [0.80242794, 0.19757206], [0.34959954, 0.65040046], [0.79166657, 0.20833343]])
In [9]:
# Use matrix operations to get the same predictions, again
p1 = scipy.special.expit(x[0:10] @ numpy.transpose(lr.coef_) + lr.intercept_)
numpy.hstack([1 - p1, p1])
Out[9]:
array([[0.89446916, 0.10553084], [0.10044569, 0.89955431], [0.54765317, 0.45234683], [0.13455494, 0.86544506], [0.93221762, 0.06778238], [0.28619664, 0.71380336], [0.55352796, 0.44647204], [0.80242794, 0.19757206], [0.34959954, 0.65040046], [0.79166657, 0.20833343]])