import seaborn as sns
sns.set_style('darkgrid')
plt.rcParams['animation.ffmpeg_path'] = '/home/uschmidt/bin/ffmpeg'
from matplotlib import animation, rc
from IPython.display import HTML
import matplotlib.patches as patches
plt.rcParams['font.size'] = 16
set_cell_width(75)
M = [[153,5],[154,6],[154,6],[155,6],[158,5],[159,7],[160,6],[161,5],[163,6],[164,7],[165,7],[165,6],
[165,7],[166,10],[167,9.5],[167,10],[168,10],[168,9],[170,10.5],[170,9.5],[170,8.5],[171,9],[173,10],
[174,8],[174,10],[174,9],[175,12],[175,11],[176,9],[177,10],[178,11],[178,11],[178,12],[179,10.5],
[179,11.5],[179,11],[180,13],[180,12],[183,12.5],[185,13]]
M = np.array(M)
M[:,0] /= 100 # convert to meters
#M = M[np.random.choice(len(M),size=20,replace=False)]
x, y = M[:,0], M[:,1]
X = np.stack((x, np.ones(len(M))),axis=-1)
Y = np.expand_dims(y,-1)
m_hat, b_hat = np.linalg.solve( X.T.dot(X), X.T.dot(Y) )
m_hat, b_hat = m_hat[0], b_hat[0]
plt.figure(figsize=(17,12))
plt.plot(x,y,'o',markersize=15)
plt.xlabel('height')
plt.ylabel('shoe size')
plt.ylim(3,15)
plt.xlim(1.5,1.9)
None;
$ \Huge f(x) = \color{orange}{m} \cdot x \color{gray}{+b} $
r = np.linspace(np.min(M[:,0]-0.2),np.max(M[:,0])+0.2)
ms = np.linspace(m_hat-2,m_hat+2,21)
ms_many = np.linspace(ms[0],ms[-1],1001)
def fm(m):
return (lambda x: m*x + b_hat)
plt.figure(figsize=(17,12))
plt.plot(x,y,'o',markersize=15)
plt.xlabel('height')
plt.ylabel('shoe size')
plt.plot(r,fm(m_hat)(r),'-',linewidth=5,label='f(x)')
plt.plot(1.66,fm(m_hat)(1.66),'o',markersize=15)
plt.text(1.665,7.7,'Prediction',color='C2',fontsize=20)
plt.ylim(3,15)
plt.xlim(1.5,1.9)
plt.legend()
None;
def C(m):
p = fm(m)(x)
return np.sum(np.abs(y-p))
def plot_points(ax=None):
return (plt.gca() if ax is None else ax).plot(x,y,'o',markersize=15)
def plot_line(m,ax=None):
return (plt.gca() if ax is None else ax).plot(r,fm(m)(r),linewidth=5)
fig, ax = plt.subplots(1,2, figsize=(24,10))
fig.set_tight_layout(True)
plt.close()
def animate_cost(i):
m = ms[i]
artists = []
for a in ax:
a.clear()
a = ax[0]
for _x,_y in zip(x,y):
artists.append(a.plot([_x,_x],[_y,fm(m)(_x)],'-',color='C8',alpha=1,linewidth=3))
artists.append(plot_points(a))
artists.append(plot_line(m,a))
a.set_xlabel('height')
a.set_ylabel('shoe size')
a.set_ylim(3,15)
a.set_xlim(1.5,1.9)
#a.set_xlim(0,1.9)
#a.set_ylim(b_hat,20)
a = ax[1]
artists.append(a.plot(ms_many,list(map(C,ms_many)),'-',color='C0',linewidth=5))
artists.append(a.plot(m,C(m),'o',color='C1',markersize=20))
a.set_xlabel('parameter m')
a.set_ylabel('cost')
return artists
anim = animation.FuncAnimation(fig, animate_cost, frames=0+1*len(ms), interval=250, blit=False)
HTML(anim.to_jshtml())
def dC(m):
p = fm(m)(x)
return np.sum(np.sign(y-p) * x)
def tangentm(m):
return lambda p: C(m) - dC(m)*(p-m)
fig, ax = plt.subplots(figsize=(17,12))
fig.set_tight_layout(True)
plt.close()
def get_m(m,t,i):
_m = m
for _ in range(i):
_m += t*dC(_m)/len(x)
return _m
def animate_learning(t=0.3,m_start=23.3):
def _animate(i):
artists = []
ax.clear()
artists.append(ax.plot(ms_many,list(map(C,ms_many)),'--',color='C0',linewidth=2))
ax.set_xlabel('parameter m')
ax.set_ylabel('cost')
m = get_m(m_start,t,i)
m_next = m + t*dC(m)/len(x)
tangent = tangentm(m)
p = 3
artists.append(ax.plot([m-p,m+p],[tangent(m-p),tangent(m+p)],'-k',linewidth=3,alpha=0.3))
ax.add_patch(patches.FancyArrowPatch(
(m,C(m)),(m_next,tangent(m_next)),arrowstyle='->',mutation_scale=30,linewidth=5)
)
artists.append(ax.plot(m,C(m),'.',color='C1',markersize=25))
#m = m_next
ax.set_ylim(20, 140)
ax.set_xlim((23, 27))
return artists
return _animate
anim = animation.FuncAnimation(fig, animate_learning(0.5), frames=30, interval=250, blit=False)
HTML(anim.to_jshtml())
anim = animation.FuncAnimation(fig, animate_learning(0.1,26.6), frames=50, interval=200, blit=False)
HTML(anim.to_jshtml())