# /!\ I'm using Python 3
import plotly
import numpy as np
import plotly.plotly as py
import plotly.graph_objs as go
import matplotlib.pyplot as plt
import scipy.io as sio
from scipy import stats
%matplotlib inline
plotly.offline.init_notebook_mode(connected=True)
from IPython.core.display import display, HTML, Markdown
# The polling here is to ensure that plotly.js has already been loaded before
# setting display alignment in order to avoid a race condition.
display(HTML(
'<script>'
'var waitForPlotly = setInterval( function() {'
'if( typeof(window.Plotly) !== "undefined" ){'
'MathJax.Hub.Config({ SVG: { font: "STIX-Web" }, displayAlign: "center" });'
'MathJax.Hub.Queue(["setRenderer", MathJax.Hub, "SVG"]);'
'clearInterval(waitForPlotly);'
'}}, 250 );'
'</script>'
))
# Colorscales
def colorscale_list(cmap, number_colors, return_rgb_only=False):
cm = plt.get_cmap(cmap)
colors = [np.array(cm(i/number_colors)) for i in range(1, number_colors+1)]
rgb_colors_plotly = []
rgb_colors_only = []
for i, c in enumerate(colors):
col = 'rgb{}'.format(tuple(255*c[:-1]))
rgb_colors_only.append(col)
rgb_colors_plotly.append([i/number_colors, col])
rgb_colors_plotly.append([(i+1)/number_colors, col])
return rgb_colors_only if return_rgb_only else rgb_colors_plotly
import scipy.integrate as integrate
import colorlover as cl
def formatted(f):
return format(f, '.2f').rstrip('0').rstrip('.')
data = {}
trace = {}
trace_handwritten = {}
ranges = {}
layout = {}
label = '2D'
ranges[label] = {}
trace[label] = {}
data[label] = {}
data[label]['X'] = np.array([[1.,2],[1,3],[3,4],[2,4],[4,0],[6,2],[2,-3],[6,-2]])
data[label]['Y'] = np.ones(8)
data[label]['Y'][:4] = 0
# Plotting the 2D-set
ranges[label]['x_1'] = [int(np.min(data[label]['X'][:,0])-1), int(np.max(data[label]['X'][:,0])+1)]
ranges[label]['x_2'] = [int(np.min(data[label]['X'][:,1])-2), int(np.max(data[label]['X'][:,1])+2)]
trace[label]['data'] = go.Scatter(
x = data[label]['X'][:,0],
y = data[label]['X'][:,1],
mode = 'markers',
marker = dict(
size = 10,
color = data[label]['Y'],
colorbar = dict(
title = 'Color',
titleside = 'top',
tickmode = 'array',
tickvals = [0, 1],
ticktext = [' Blue Set',' Red Set'],
ticks = 'outside'
),
showscale = True,
line = dict(
width = 2,
color = 'rgb(0, 0, 0)'
),
colorscale = [
[0., 'rgb(69,117,180)'], [0.5, 'rgb(69,117,180)'],
[0.5, 'rgb(215,48,39)'], [1, 'rgb(215,48,39)']
]
),
showlegend = False
)
layout[label] = dict(
title = '{} set'.format(label),
xaxis = dict(
title = '$x$',
range = ranges[label]['x_1'],
ticklen = 5,
zeroline = False,
gridwidth = 2,
),
yaxis = dict(
title = '$y$',
range = ranges[label]['x_2'],
zeroline=False,
ticklen = 5,
gridwidth = 2,
),
legend = dict(
orientation = 'h',
y = -0.2
)
)
range_values = np.linspace(ranges[label]['x_1'][0], ranges[label]['x_1'][1], 20)
trace_handwritten[label] = go.Scatter(
x = range_values,
y = range_values-1.5,
mode = 'lines',
line = dict(
color = ('SeaGreen'),
width = 4,
dash = 'longdash'),
name = 'Handwritten separating line'
)
fig = dict(data=[trace[label]['data'], trace_handwritten[label]], layout=layout[label])
plotly.offline.iplot(fig)
label = '3D'
ranges[label] = {}
trace[label] = {}
data[label] = {}
data[label]['X'] = np.array([[2.,1,2],[3,2,3],[4,2,4],[3,1,2],[1,4,-1],[2,3,0],[1,2,0],[0,1,0]])
data[label]['Y'] = np.ones(8)
data[label]['Y'][:4] = 0
# Plotting the 2D-set
trace[label]['data'] = go.Scatter3d(
x = data[label]['X'][:,0],
y = data[label]['X'][:,1],
z = data[label]['X'][:,2],
mode = 'markers',
marker = dict(
size = 7,
color = data[label]['Y'],
colorbar = dict(
title = 'Color',
titleside = 'top',
tickmode = 'array',
tickvals = [0, 1],
ticktext = [' Blue Set',' Red Set'],
ticks = 'outside'
),
showscale = True,
line = dict(
width = 2,
color = 'rgb(0, 0, 0)'
),
colorscale = [
[0., 'rgb(69,117,180)'], [0.5, 'rgb(69,117,180)'],
[0.5, 'rgb(215,48,39)'], [1, 'rgb(215,48,39)']
]
),
showlegend = False
)
ranges[label]['x_1'] = [int(np.min(data[label]['X'][:,0])-1), int(np.max(data[label]['X'][:,0])+1)]
ranges[label]['x_2'] = [int(np.min(data[label]['X'][:,1])-2), int(np.max(data[label]['X'][:,1])+2)]
ranges[label]['x_3'] = [int(np.min(data[label]['X'][:,2])-2), int(np.max(data[label]['X'][:,2])+2)]
layout[label] = dict(
title = '{} set'.format(label)
)
x1_range_values = np.linspace(ranges[label]['x_1'][0], ranges[label]['x_1'][1], 100)
x2_range_values = np.linspace(ranges[label]['x_2'][0], ranges[label]['x_2'][1], 100)
x_1, x_2 = np.meshgrid(x1_range_values, x2_range_values)
trace_handwritten[label] = go.Surface(
x = x_1,
y = x_2,
z = 0*x_1+1,
name = 'Handwritten separating plane',
surfacecolor = 0*x_1,
cauto = False,
colorscale = [[0., 'SeaGreen'], [1., 'SeaGreen']],
opacity=0.7,
showscale=False
)
fig = dict(data=[trace[label]['data'], trace_handwritten[label]], layout=layout[label])
plotly.offline.iplot(fig)
# Plotting the separating line
traces = []
arrows = []
v = np.array([4, -4])
traces.append(
go.Scatter(
x = range_values,
y = -v[0]*range_values/v[1],
mode = 'lines',
name = 'Separating line after applying the algorithm',
line = dict(
width = 2,
color = 'Green',
dash = 'solid'
),
hoverlabel = dict(
namelength = -1
),
showlegend = True
)
)
arrows.append(
dict(
ax=3,
ay=-v[0]*3/v[1],
axref='x',
ayref='y',
x=3+v[0]/(np.linalg.norm(v)),
y=-v[0]*3/v[1]+v[1]/(np.linalg.norm(v)),
xref='x',
yref='y',
showarrow=True,
arrowhead=3,
arrowsize=1,
arrowwidth=2,
arrowcolor='Purple',
xshift=0,
yshift=0
)
)
layout_arrows = dict(
title = '2D set',
xaxis = dict(
title = '$x$',
ticklen = 5,
zeroline = False,
range=[0,8]
),
yaxis = dict(
title = '$y$',
zeroline = False,
range=[-3.5, 4.5],
ticklen = 5
),
legend = dict(
orientation = 'h',
y = -0.2
),
annotations=arrows,
height=900,
width=900
)
plotly.offline.iplot(go.Figure(data=traces+[trace['2D']['data']], layout=layout_arrows))
# Plotting the separating plane
v = np.array([-1, 2, -3])
traces = []
arrows = []
label = '3D'
ranges[label]['x_1'] = [int(np.min(data[label]['X'][:,0])-1), int(np.max(data[label]['X'][:,0])+1)]
ranges[label]['x_2'] = [int(np.min(data[label]['X'][:,1])-2), int(np.max(data[label]['X'][:,1])+2)]
ranges[label]['x_3'] = [int(np.min(data[label]['X'][:,2])-2), int(np.max(data[label]['X'][:,2])+2)]
x1_range_values = np.linspace(ranges[label]['x_1'][0], ranges[label]['x_1'][1], 100)
x2_range_values = np.linspace(ranges[label]['x_2'][0], ranges[label]['x_2'][1], 100)
traces.append(
go.Surface(
x = x_1,
y = x_2,
z = (-v[0]*x_1-v[1]*x_2)/v[2],
name = 'Separating plane after applying the algorithm',
surfacecolor = 0*x_1,
cauto = False,
colorscale = [[0., 'Green'], [1., 'Green']],
opacity = 0.7,
showscale = False
)
)
layout_arrows = dict(
title = '3D set'
)
plotly.offline.iplot(go.Figure(data=traces+[trace['3D']['data']], layout=layout_arrows))
def perceptron_rule(X, Y):
nb_trials, dimension = X.shape
w = np.ones(X.shape[1])
w_values = [np.copy(w)]
while True:
# is the readout vector still changing?
# (to halt the loop, in case it isn't)
still_changing = False
for i in range(nb_trials):
w += (Y[i]-int(w.dot(X[i])>=0))*X[i]
if np.any(w_values[-1] != w):
still_changing = True
w_values.append(np.copy(w))
if not still_changing:
break
# Returning all the readout weight vectors,
# except those of the last step
# (throughout which the readout vector didn't change)
return np.array(w_values[:-nb_trials])
perceptron_rule(data['2D']['X'], data['2D']['Y'])
legend_every = 5
values = perceptron_rule(data['2D']['X'], data['2D']['Y'])
#colors = cl.scales['{}'.format(len(values))]['seq']['Greens']
colors = colorscale_list('Greens', len(values)+3, return_rgb_only=True)
# Plotting the evolution
traces = []
arrows = []
for i, v in enumerate(values):
traces.append(
go.Scatter(
x = range_values,
y = -v[0]*range_values/v[1],
mode = 'lines',
name = 'Separating line at iteration {}'.format(i+1),
line = dict(
width = 2,
color = colors[i+2],
dash = 'solid'
),
hoverlabel = dict(
namelength = -1
),
showlegend = (i % legend_every == 0)
)
)
arrows.append(
dict(
ax=.5,
ay=-v[0]*.5/v[1],
axref='x',
ayref='y',
x=.5+v[0]/(2*np.linalg.norm(v)),
y=-v[0]*.5/v[1]+v[1]/(2*np.linalg.norm(v)),
xref='x',
yref='y',
showarrow=True,
arrowhead=3,
arrowsize=1,
arrowwidth=2,
arrowcolor='Purple',
xshift=0,
yshift=0,
)
)
layout_arrows = dict(
title = '2D set',
xaxis = dict(
title = '$x$',
ticklen = 5,
zeroline = False,
range=[0,8]
),
yaxis = dict(
title = '$y$',
zeroline = False,
range=[-3.5, 4.5],
ticklen = 5
),
legend = dict(
orientation = 'h',
y = -0.2
),
annotations=arrows,
height=900,
width=900
)
plotly.offline.iplot(go.Figure(data=traces+[trace['2D']['data']], layout=layout_arrows))
perceptron_rule(data['3D']['X'], data['3D']['Y'])
legend_every = 5
values = perceptron_rule(data['3D']['X'], data['3D']['Y'])
#colors = cl.scales['{}'.format(len(values))]['seq']['Greens']
colors = colorscale_list('Greens', len(values)+3, return_rgb_only=True)
# Plotting the evolution
traces = []
arrows = []
label = '3D'
ranges[label]['x_1'] = [int(np.min(data[label]['X'][:,0])-1), int(np.max(data[label]['X'][:,0])+1)]
ranges[label]['x_2'] = [int(np.min(data[label]['X'][:,1])-2), int(np.max(data[label]['X'][:,1])+2)]
ranges[label]['x_3'] = [int(np.min(data[label]['X'][:,2])-2), int(np.max(data[label]['X'][:,2])+2)]
x1_range_values = np.linspace(ranges[label]['x_1'][0], ranges[label]['x_1'][1], 100)
x2_range_values = np.linspace(ranges[label]['x_2'][0], ranges[label]['x_2'][1], 100)
for i, v in enumerate(values):
traces.append(
go.Surface(
x = x_1,
y = x_2,
z = (-v[0]*x_1-v[1]*x_2)/v[2],
name = 'Step {}'.format(i+1),
surfacecolor = 0*x_1,
cauto = False,
colorscale = [[0., colors[i+2]], [1., colors[i+2]]],
opacity = 0.5,
showscale = False,
showlegend = (i % legend_every == 0)
)
)
layout_arrows = dict(
title = '3D set',
height = 900,
width = 900
)
plotly.offline.iplot(go.Figure(data=traces+[trace['3D']['data']], layout=layout_arrows))