Skip to content

Commit 60087f4

Browse files
authored
Merge pull request deutranium#180 from Lashuk1729/master
Implemented the Perceptron Algorithm in Python Language.
2 parents d161fa3 + 91dae94 commit 60087f4

File tree

9 files changed

+167
-0
lines changed

9 files changed

+167
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Perceptron Learning Algorithm:
2+
---
3+
4+
>Note: This code is implemented from algorithm proposed by Frank Rosenblatt in 1943, later refined and carefully analyzed by Minsky and Papert in 1969.
5+
6+
A single perceptron can only be used to implement linearly separable functions. It takes both real and boolean inputs and associates a set of weights to them, along with a bias.
7+
8+
Our goal is to find the w vector that can perfectly classify positive inputs and negative inputs in our data. I will get straight to the algorithm. Here goes:
9+
10+
![perceptron algorithm](./images/algorithm.png "Algorthm")
11+
12+
- We initialize w with some random vector.
13+
- We then iterate over all the examples in the data, (P U N) both positive and negative examples.
14+
- Now if an input x belongs to P, ideally the dot product w.x be greater than or equal to 0.
15+
- And if x belongs to N, the dot product MUST be less than 0.
16+
---
17+
18+
## Steps to run the code:
19+
20+
1. Make sure you have Python 3.7 and a text editor installed.
21+
2. Install the required packages using pip install -r requirements.txt.
22+
3. In the main directory Run `python3 main.py` or `python main.py`.
23+
4. And wait for the results.
24+
25+
---
26+
## Result on the Dummy Dataset:
27+
28+
![perceptron result](./images/perceptron.gif "Results After Each Epoch")
29+
30+
Result of Perceptron after Every Epoch
Loading
Loading
Loading
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import numpy as np
2+
from perceptron import Perceptron
3+
from plotting import plot, plot_error_history
4+
5+
"""0. Create dataset"""
6+
train_data = ( # x, y, target
7+
(0.2, 0.3, 0),
8+
(0.8, 7, 0),
9+
(2, 1, 0),
10+
(2, 4, 0),
11+
(1, 1, 0),
12+
(2, 1, 0),
13+
(2, 2.8, 0),
14+
(2, 2.2, 0),
15+
(3, 1, 0),
16+
(5, 3, 1),
17+
(5, 4, 1),
18+
(4, 5, 1),
19+
(4, 7, 1),
20+
(5, 5.1, 1),
21+
(5.5, 6, 1),
22+
(6, 5, 1),
23+
(6, 6.5, 1),
24+
(6, 7, 1)
25+
)
26+
27+
validate_data = (
28+
(1, 1),
29+
(2, 2),
30+
(2, 1),
31+
(5, 4),
32+
(6, 5),
33+
(6, 6)
34+
)
35+
36+
X_train = np.array([x[:2] for x in train_data]) # list comprehension
37+
X_validate = np.array([x[:2] for x in validate_data]) # list comprehension
38+
y = np.array([x[-1] for x in train_data])
39+
40+
"""1.Initialization perceptron"""
41+
perceptron = Perceptron(epochs=25, eta=0.01)
42+
43+
"""2.perceptron training"""
44+
perceptron.train(X_train, target=y)
45+
print(f'Weights: {perceptron.w}')
46+
47+
"""3.Prediction"""
48+
prediction = perceptron.predict(X_train)
49+
print(f'Output (Y): {prediction}')
50+
51+
print('last')
52+
plot(X_train, prediction, perceptron, 25, None, perceptron.w)
53+
plot_error_history(perceptron.err)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import numpy as np
2+
from plotting import plot
3+
from sklearn.metrics import accuracy_score
4+
5+
"""
6+
File: perceptron.py
7+
Author: Lashuk1729
8+
Description: Perceptron Rule
9+
"""
10+
11+
12+
class Perceptron(object):
13+
14+
def __init__(self, eta: float = 0.01, epochs: int = 50):
15+
self.eta = eta # learning reate
16+
self.epochs = epochs
17+
18+
def train(self, X: np.ndarray, target: np.ndarray): # Perceptron Rule
19+
self.w = np.zeros(1 + X.shape[1])
20+
self.err = []
21+
22+
print('Training progress..')
23+
for epoch in range(self.epochs):
24+
errors = 0
25+
for x, y in zip(X, target):
26+
update = self.eta * (y - self.predict(x))
27+
self.w[1:] += update * x
28+
self.w[0] += update
29+
errors += int(update != 0.0)
30+
31+
accuracy = int(accuracy_score(self.predict(X), target) * 100)
32+
self.err.append(accuracy)
33+
plot(X, target, self, epoch, accuracy, self.w)
34+
return self
35+
36+
def dot_product(self, X: np.ndarray) -> np.float64:
37+
return np.dot(X, self.w[1:]) + self.w[0]
38+
39+
def predict(self, X: np.ndarray) -> int:
40+
return np.where(self.dot_product(X) >= 0.0, 1, 0)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from mlxtend.plotting import plot_decision_regions
2+
import matplotlib.pyplot as plt
3+
4+
5+
def plot(x, prediction, clf, epoch=None, accuracy=None, weights=None):
6+
plot_decision_regions(x, prediction, clf=clf)
7+
8+
plt.title(f'Perceptron {weights}')
9+
10+
if epoch is not None:
11+
plt.annotate(f'Epoch: {epoch}', xy=(2, 0), xytext=(5, 0.5))
12+
13+
if accuracy is not None:
14+
plt.annotate(f'Accuracy: {accuracy}%', xy=(2, 0), xytext=(5, 0))
15+
16+
plt.xlabel('x')
17+
plt.ylabel('y')
18+
plt.show()
19+
20+
21+
def plot_error_history(err):
22+
print(len(err))
23+
plt.plot(err)
24+
plt.show()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mlxtend==0.19.0
2+
numpy==1.19.5
3+
matplotlib==3.3.2
4+
scikit_learn==1.0
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import numpy as np
2+
3+
4+
x = [1, 2]
5+
w = [1, 1, 1]
6+
7+
8+
def net_input(X: np.ndarray) -> np.float64:
9+
return np.dot(X, w[1:]) + w[0]
10+
11+
12+
def predict(X: np.ndarray) -> int:
13+
return 1.0 if net_input(X) >= 0.0 else 0.0
14+
15+
16+
print(predict(x))

0 commit comments

Comments
 (0)