I am attempting to implement a perceptron. I have loaded a 100x2 array of values between 0 and 100. Each item in the array has a label of either -1 or 1.
I believe the perceptron is working, however I cannot plot decision boundary as shown here: plot decision boundary matplotlib
When I run my code I only see a single color background. I would expect to see two colors, one color for each label in my data set (-1 and 1).
My current output, I expect to see 2 colors for the background (-1 or 1)
An example of what I hope to see, from the sklearn documentation
import numpy as np
from matplotlib import pyplot as plt
def generate_data():
#generate a dataset that is linearly seperable
group_1 = np.random.randint(50, 100, size=(50,2))
group_1_labels = np.full((50,1), 1)
group_2 = np.random.randint(0, 49, size =(50,2))
group_2_labels = np.full((50,1), -1)
#add a bias value of -1
bias = np.full((50,1), -1)
#add labels, upper right quadrant are 1, lower left are -1
group_1_with_bias = np.hstack((group_1, bias))
group_2_with_bias = np.hstack((group_2, bias))
group_1_labeled = np.hstack((group_1_with_bias, group_1_labels))
group_2_labeled = np.hstack((group_2_with_bias, group_2_labels))
#merge our labeled data and shuffle!
merged_data = np.vstack((group_1_labeled, group_2_labeled))
np.random.shuffle(merged_data)
return merged_data
data = generate_data()
#load data, strip labels, add a -1 bias value
X = data[:, :3]
#create labels matrix
l = np.ravel(data[:, 3:])
def perceptron_sgd(X, l, c, epochs):
#initialize weights
w = np.zeros(3)
errors = []
for epoch in range(epochs):
total_error = 0
for i, x in enumerate(X):
if (np.dot(x, w) * l[i]) <= 0:
total_error += (np.dot(x, w) * l[i])
w = w + c * (x * l[i])
errors.append(total_error * -1)
print "epoch " + str(epoch) + ": " + str(w)
return w, errors
def classify(X, l, w):
z = np.dot(X, w)
print z
z[z <= 0] = -1
z[z > 0] = 1
#return a matrix of predicted labels
return z
w, errors = perceptron_sgd(X, l, .001, 36)
# X - some data in 2dimensional np.array
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .2), np.arange(y_min, y_max, .2))
# here "model" is your model's prediction (classification) function
Z = classify(np.c_[xx.ravel(), yy.ravel()], l, w[:-1]) #strip the bias from weights
# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.axis('off')
#Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=l, cmap=plt.cm.Paired)
I got it to work.
Standardized your X
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(X[:, :-1])
X_trans = np.column_stack((scaler.transform(X[:, :-1]), X[:, -1]))
Better initialization than zero.
#initialize weights
r = np.sqrt(2)
w = np.random.uniform(-r, r, (3,))
Add learned biases during prediction
z = np.dot(X, w[:-1]) + w[-1]
Standardize during prediction as well (using standardization learned from input)
Z = classify(scaler.transform(np.c_[xx.ravel(), yy.ravel()]),
l, w) #strip the bias from weights
Generally, always a good idea to standardize the inputs.
Entire code:
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
def generate_data():
#generate a dataset that is linearly seperable
group_1 = np.random.randint(50, 100, size=(50,2))
group_1_labels = np.full((50,1), 1)
group_2 = np.random.randint(0, 49, size =(50,2))
group_2_labels = np.full((50,1), -1)
#add a bias value of -1
bias = np.full((50,1), -1)
#add labels, upper right quadrant are 1, lower left are -1
group_1_with_bias = np.hstack((group_1, bias))
group_2_with_bias = np.hstack((group_2, bias))
group_1_labeled = np.hstack((group_1_with_bias, group_1_labels))
group_2_labeled = np.hstack((group_2_with_bias, group_2_labels))
#merge our labeled data and shuffle!
merged_data = np.vstack((group_1_labeled, group_2_labeled))
np.random.shuffle(merged_data)
return merged_data
data = generate_data()
#load data, strip labels, add a -1 bias value
X = data[:, :3]
#create labels matrix
l = np.ravel(data[:, 3:])
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(X[:, :-1])
X_trans = np.column_stack((scaler.transform(X[:, :-1]), X[:, -1]))
def perceptron_sgd(X, l, c, epochs):
#initialize weights
r = np.sqrt(2)
w = np.random.uniform(-r, r, (3,))
errors = []
for epoch in range(epochs):
total_error = 0
for i, x in enumerate(X):
if (np.dot(x, w) * l[i]) <= 0:
total_error += (np.dot(x, w) * l[i])
w = w + c * (x * l[i])
errors.append(total_error * -1)
print("epoch " + str(epoch) + ": " + str(w))
return w, errors
def classify(X, l, w):
z = np.dot(X, w[:-1]) + w[-1]
print(z)
z[z <= 0] = -1
z[z > 0] = 1
#return a matrix of predicted labels
return z
w, errors = perceptron_sgd(X_trans, l, .01, 25)
# X - some data in 2dimensional np.array
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, .1), np.arange(y_min, y_max, .1))
# here "model" is your model's prediction (classification) function
Z = classify(scaler.transform(np.c_[xx.ravel(), yy.ravel()]), l, w) #strip the bias from weights
# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
#plt.axis('off')
#Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=l, cmap=plt.cm.Paired)
Related
Im trying to recreate Conways game of life where the average color of the surrounding cells will be the color of the new dead cell created, although I'm having issues trying to count the surrounding neighbors of a certain cell in order to determine if that cell should be dead or alive.
def count_neighbors(self, i, j):
neighbors = []
r_sum = 0
g_sum = 0
b_sum = 0
''' The range(-1, 2) in the for loop allows the loop to check the cells in the positions
relative to the current cell, which are the eight cells surrounding it.'''
for x in range(-1, 2):
for y in range(-1, 2):
if (x, y) == (0, 0):
continue
if 0 <= int(i) + x < len(self._board) and 0 <= int(j) + y < len(self._board):
if self._board[i + x][j + y] != (0, 0, 0):
neighbors.append(self._board[i + x][j + y])
r_sum += self._board[i + x][j + y][0]
g_sum += self._board[i + x][j + y][1]
b_sum += self._board[i + x][j + y][2]
num_neighbors = len(neighbors)
if num_neighbors == 0:
return 0, (0, 0, 0)
return num_neighbors, (r_sum // num_neighbors, g_sum // num_neighbors, b_sum // num_neighbors)
I am trying to create an Euclidean algorithm (to solve Bezout's Relation) for 2 polynomials in the GF(2^8).
I currently have this code for my different operations
class ReedSolomon:
gfSize = 256
genPoly = 285
log = [0]*gfSize
antilog = [0]*gfSize
def _genLogAntilogArrays(self):
self.antilog[0] = 1
self.log[0] = 0
self.antilog[255] = 1
for i in range(1,255):
self.antilog[i] = self.antilog[i-1] << 1
if self.antilog[i] >= self.gfSize:
self.antilog[i] = self.antilog[i] ^ self.genPoly
self.log[self.antilog[i]] = i
def __init__(self):
self._genLogAntilogArrays()
def _galPolynomialDivision(self,dividend, divisor):
result = dividend.copy()
for i in range(len(dividend) - (len(divisor)-1)):
coef = result[i]
if coef != 0:
for j in range(1, len(divisor)):
if divisor[j] != 0:
result[i + j] ^= self._galMult(divisor[j], coef) # équivalent result[i + j] += -divisor[j] * coef car dans un champ GF(2) addition <=> substraction <=> XOR
remainderIndex = -(len(divisor)-1)
return result[:remainderIndex], result[remainderIndex:]
def _galMultiplicationPolynomiale(self, x,y):
result = [0]*(len(x)+len(y)-1)
for i in range(len(x)):
for j in range(len(y)):
result[i+j] ^= self._galMult(x[i],y[j])
return result
def _galMult(self,x,y):
if ((x == 0) or (y == 0)):
val = 0
else:
val = self.antilog[(self.log[x] + self.log[y])%255]
return val
def _galPolynomialAddition(self, a, b):
polSum = [0] * max(len(a), len(b))
for index in range(0, len(a)):
polSum[index + len(polSum) - len(a)] = a[index]
for index in range(0, len(b)):
polSum[index + len(polSum) - len(b)] ^= b[index]
return (polSum)
And here is my euclidean algorithm :
def _galEuclideanAlgorithm(self,a,b):
r0 = a.copy()
r1 = b.copy()
u0 = [1]
u1 = [0]
v0 = [0]
v1 = [1]
while max(r1) != 0:
print(r1)
q,r = self._galPolynomialDivision(r0,r1)
r0 = self._galPolynomialAddition(self._galMultiplicationPolynomiale(q,r1),r)
r1,r0 = self._galPolynomialAddition(r0,self._galMultiplicationPolynomiale(q,r1)),r1.copy()
u1,u0 = self._galPolynomialAddition(u0,self._galMultiplicationPolynomiale(q,u1)),u1.copy()
v1,v0 = self._galPolynomialAddition(v0,self._galMultiplicationPolynomiale(q,v1)),v1.copy()
return r1,u1,v1
I don't understand my issue where my algorithm is looping, here is my remainder output with my tests:
rs = ReedSolomon()
a = [1,15,7,8,0,11]
b = [1,0,0,0,0,0,0]
print(rs._galEuclideanAlgorithm(b,a))
#Console output
'''
[1, 15, 7, 8, 0, 11]
[0, 0, 82, 37, 120, 11, 105]
[1, 15, 7, 8, 0, 11]
[0, 0, 82, 37, 120, 11, 105]
[1, 15, 7, 8, 0, 11]
[0, 0, 82, 37, 120, 11, 105]
[1, 15, 7, 8, 0, 11]
'''
I know it might seem like I'm throwing some code just expecting an answer, but I'm genuinely searching for the error.
Thanks in advance !
I created a Python package called galois that does this. galois extends NumPy arrays to operate over Galois fields. The code is written in Python but JIT compiled with Numba for speed. In addition to array arithmetic, it also supports polynomials over Galois fields. ...And Reed-Solomon codes are implemented too :)
The Extended Euclidean Algorithm to solve the Bezout identity for two polynomials in GF(2^8) would be solved this way. Below is an abbreviated chunk of source code. You can see my full source code here.
def poly_egcd(a, b):
field = a.field
zero = Poly.Zero(field)
one = Poly.One(field)
r2, r1 = a, b
s2, s1 = one, zero
t2, t1 = zero, one
while r1 != zero:
q = r2 / r1
r2, r1 = r1, r2 - q*r1
s2, s1 = s1, s2 - q*s1
t2, t1 = t1, t2 - q*t1
# Make the GCD polynomial monic
c = r2.coeffs[0] # The leading coefficient
if c > 1:
r2 /= c
s2 /= c
t2 /= c
return r2, s2, t2
And here is a complete example using the galois library and the polynomials from your example. (I'm assuming the highest-degree coefficient is first?)
In [1]: import galois
In [2]: GF = galois.GF(2**8)
In [3]: print(GF.properties)
GF(2^8):
characteristic: 2
degree: 8
order: 256
irreducible_poly: x^8 + x^4 + x^3 + x^2 + 1
is_primitive_poly: True
primitive_element: x
In [4]: a = galois.Poly([1,15,7,8,0,11], field=GF); a
Out[4]: Poly(x^5 + 15x^4 + 7x^3 + 8x^2 + 11, GF(2^8))
In [5]: b = galois.Poly([1,0,0,0,0,0,0], field=GF); b
Out[5]: Poly(x^6, GF(2^8))
In [6]: d, s, t = galois.poly_egcd(a, b); d, s, t
Out[6]:
(Poly(1, GF(2^8)),
Poly(78x^5 + 7x^4 + 247x^3 + 74x^2 + 152, GF(2^8)),
Poly(78x^4 + 186x^3 + 45x^2 + x + 70, GF(2^8)))
In [7]: a*s + b*t == d
Out[7]: True
I need to fill with different colors (green and red maybe) the two sides of a graph. I'm using the following code:
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib
range_x = [-1, 0, 1, 2]
range_y = [-5, -3, -1, 1]
ax = sns.lineplot(x = range_x, y = range_y, markers = True)
sns.lineplot(ax = ax, x = [range_x[0], range_x[-1]], y = [0, 0], color = 'black')
sns.lineplot(ax = ax, x = [0, 0], y = [range_y[0], range_y[-1]], color = 'black')
ax.fill_between(range_x, range_y, facecolor = 'red', alpha = 0.5)
plt.savefig('test_fig', bbox_inches = 'tight')
plt.close()
With that code I get the following figure:
But obviously this is a fail, because I want red color all above the blue line. Besides I want my x and y axis in a remarkable way, I get it with x axis but I don't know why I can't get it with y axis.
Thanks you very much in advance!
Something like this?:
ax = sns.lineplot(x = range_x, y = range_y, markers = True)
sns.lineplot(ax = ax, x = [range_x[0], range_x[-1]], y = [0, 0], color = 'black')
sns.lineplot(ax = ax, x = [0, 0], y = [range_y[0], range_y[-1]], color = 'black')
ax.fill_between(range_x, range_y,[ax.get_ylim()[1]]*len(range_x), facecolor = 'red', alpha = 0.5)
ax.fill_between(range_x, range_y,[ax.get_ylim()[0]]*len(range_x), facecolor = 'green', alpha = 0.5)
From the documentation of fill_between:
y2 : array (length N) or scalar, optional, default: 0
The y coordinates of the nodes defining the second curve.
So I wanted to see if I could make fractal flames using matplotlib and figured a good test would be the sierpinski triangle. I modified a working version I had that simply performed the chaos game by normalizing the x range from -2, 2 to 0, 400 and the y range from 0, 2 to 0, 200. I also truncated the x and y coordinates to 2 decimal places and multiplied by 100 so that the coordinates could be put in to a matrix that I could apply a color map to. Here's the code I'm working on right now (please forgive the messiness):
import numpy as np
import matplotlib.pyplot as plt
import math
import random
def f(x, y, n):
N = np.array([[x, y]])
M = np.array([[1/2.0, 0], [0, 1/2.0]])
b = np.array([[.5], [0]])
b2 = np.array([[0], [.5]])
if n == 0:
return np.dot(M, N.T)
elif n == 1:
return np.dot(M, N.T) + 2*b
elif n == 2:
return np.dot(M, N.T) + 2*b2
elif n == 3:
return np.dot(M, N.T) - 2*b
def norm_x(n, minX_1, maxX_1, minX_2, maxX_2):
rng = maxX_1 - minX_1
n = (n - minX_1) / rng
rng_2 = maxX_2 - minX_2
n = (n * rng_2) + minX_2
return n
def norm_y(n, minY_1, maxY_1, minY_2, maxY_2):
rng = maxY_1 - minY_1
n = (n - minY_1) / rng
rng_2 = maxY_2 - minY_2
n = (n * rng_2) + minY_2
return n
# Plot ranges
x_min, x_max = -2.0, 2.0
y_min, y_max = 0, 2.0
# Even intervals for points to compute orbits of
x_range = np.arange(x_min, x_max, (x_max - x_min) / 400.0)
y_range = np.arange(y_min, y_max, (y_max - y_min) / 200.0)
mat = np.zeros((len(x_range) + 1, len(y_range) + 1))
random.seed()
x = 1
y = 1
for i in range(0, 100000):
n = random.randint(0, 3)
V = f(x, y, n)
x = V.item(0)
y = V.item(1)
mat[norm_x(x, -2, 2, 0, 400), norm_y(y, 0, 2, 0, 200)] += 50
plt.xlabel('x0')
plt.ylabel('y')
fig = plt.figure(figsize=(10,10))
plt.imshow(mat, cmap="spectral", extent=[-2,2, 0, 2])
plt.show()
The mathematics seem solid here so I suspect something weird is going on with how I'm handling where things should go into the 'mat' matrix and how the values in there correspond to the colormap.
If I understood your problem correctly, you need to transpose your matrix using the method .T. So just replace
fig = plt.figure(figsize=(10,10))
plt.imshow(mat, cmap="spectral", extent=[-2,2, 0, 2])
plt.show()
by
fig = plt.figure(figsize=(10,10))
ax = gca()
ax.imshow(mat.T, cmap="spectral", extent=[-2,2, 0, 2], origin="bottom")
plt.show()
The argument origin=bottom tells to imshow to have the origin of your matrix at the bottom of the figure.
Hope it helps.
I was trying to put labes on the streamlines around a body whose symmetric profile is generated by a vortex and a uniform flow, so far I must get something like this (with labels)
which I get it with the next code:
import numpy as np
import matplotlib.pyplot as plt
vortex_height = 18.0
h = vortex_height
vortex_intensity = 55.0
cv = vortex_intensity
permanent_speed = 10.0
U1 = permanent_speed
Y, X = np.mgrid[-25:25:100j, -25:25:100j]
U = 5.0 + 37.0857 * (Y - 18.326581) / (X ** 2 + (Y - 18.326581) ** 2) +- 37.0857 * (Y + 18.326581) / (X ** 2 + (Y + 18.326581) ** 2)
V = - 37.0857 * (X) / (X ** 2 + (Y - 18.326581) ** 2) + 37.0857 * (X) / (X ** 2 + (Y + 18.326581) ** 2)
speed = np.sqrt(U*U + V*V)
plt.streamplot(X, Y, U, V, color=U, linewidth=2, cmap=plt.cm.autumn)
plt.colorbar()
#CS = plt.contour(U, v, speed)
#plt.clabel(CS, inline=1, fontsize=10)
#f, (ax1, ax2) = plt.subplots(ncols=2)
#ax1.streamplot(X, Y, U, V, density=[0.5, 1])
#lw = 5*speed/speed.max()
#ax2.streamplot(X, Y, U, V, density=0.6, color='k', linewidth=lw)
plt.savefig("stream_plot5.png")
plt.show()
So I was changing the next example code (which use pylab):
from numpy import exp,arange
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
# the function that I'm going to plot
def z_func(x,y):
return (1-(x**2+y**3))*exp(-(x**2+y**2)/2)
x = arange(-3.0,3.0,0.1)
y = arange(-3.0,3.0,0.1)
X,Y = meshgrid(x, y) # grid of point
Z = z_func(X, Y) # evaluation of the function on the grid
im = imshow(Z,cmap=cm.RdBu) # drawing the function
# adding the Contour lines with labels
cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2)
clabel(cset,inline=True,fmt='%1.1f',fontsize=10)
colorbar(im) # adding the colobar on the right
# latex fashion title
title('$z=(1-x^2+y^3) e^{-(x^2+y^2)/2}$')
show()
with this plot:
And finally I get it like this:
import numpy as np
from numpy import exp,arange,log
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
# PSI = streamline
def streamLine(x, y, U = 5, hv = 18.326581, cv = 37.0857):
x2 = x ** 2
y2plus = (y + hv) ** 2
y2minus = (y - hv) ** 2
PSI_1 = U * y
PSI_2 = 0.5 * cv * log(x2 + y2minus)
PSI_3 = - 0.5 * cv * log(x2 + y2plus)
psi = PSI_1 + PSI_2 + PSI_3
return psi
"""
def streamLine(x, y):
return 0.5 * 37.0857 * log(x ** 2 + (y - 18.326581) ** 2)
# (5.0 * y + 0.5 * 37.0857 * math.log(x ** 2 + (y - 18.326581) ** 2) - 0.5 * 37.0857 * math.log(x ** 2 + (y + 18.326581) ** 2))
"""
x = arange(-20.0,20.0,0.1)
y = arange(-20.0,20.0,0.1)
X,Y = meshgrid(x, y) # grid of point
#Z = z_func(X, Y) # evaluation of the function on the grid
Z= streamLine(X, Y)
im = imshow(Z,cmap=cm.RdBu) # drawing the function
# adding the Contour lines with labels
cset = contour(Z,arange(-5,6.5,0.2),linewidths=2,cmap=cm.Set2)
clabel(cset,inline=True,fmt='%1.1f',fontsize=9)
colorbar(im) # adding the colobar on the right
# latex fashion title
title('$phi= 5.0 y + (1/2)* 37.0857 log(x^2 + (y - 18.326581)^2)-(1/2)* 37.085...$')
show()
#print type(Z)
#print len(Z)
But then I get the next plot:
which is something that keeps me wondering what's wrong because the axis are not where they should be.
contour() draws contour lines of a scalar field, and streamplot() is draw of vector field,
Vector fields can be constructed out of scalar fields using the gradient operator.
Here is an example:
import numpy as np
from numpy import exp,arange,log
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show,streamplot
# PSI = streamline
def f(x, y, U = 5, hv = 18.326581, cv = 37.0857):
x2 = x ** 2
y2plus = (y + hv) ** 2
y2minus = (y - hv) ** 2
PSI_1 = U * y
PSI_2 = 0.5 * cv * log(x2 + y2minus)
PSI_3 = - 0.5 * cv * log(x2 + y2plus)
psi = PSI_1 + PSI_2 + PSI_3
return psi
x = arange(-20.0,20.0,0.1)
y = arange(-20.0,20.0,0.1)
X,Y = meshgrid(x, y) # grid of point
#Z = z_func(X, Y) # evaluation of the function on the grid
Z= f(X, Y)
dx, dy = 1e-6, 1e-6
U = (f(X+dx, Y) - f(X, Y))/dx
V = (f(X, Y+dy) - f(X, Y))/dy
streamplot(X, Y, U, V, linewidth=1, color=(0, 0, 1, 0.3))
cset = contour(X, Y, Z,arange(-20,20,2.0),linewidths=2,cmap=cm.Set2)
clabel(cset,inline=True,fmt='%1.1f',fontsize=9)
colorbar(im) # adding the colobar on the right
# latex fashion title
title('$phi= 5.0 y + (1/2)* 37.0857 log(x^2 + (y - 18.326581)^2)-(1/2)* 37.085...$')
show()
output: