1- import numpy as np
21import matplotlib .pyplot as plt
2+ import numpy as np
33from matplotlib .colors import ListedColormap
44
55
66class Perceptron :
7- """Perceptron classifier.
8-
9- Parameters
10- ----------
11- eta : float
12- Learning rate (between 0.0 and 1.0).
13- n_iter : int
14- Passes over the training dataset.
15- random_state : int
16- RNG seed for weight initialization.
17-
18- Attributes
19- ----------
20- w_ : 1d-array
21- Weights after fitting.
22- b_ : float
23- Bias unit after fitting.
24- errors_ : list[int]
25- Number of misclassifications (updates) in each epoch.
26- """
7+ """Perceptron classifier."""
278
289 def __init__ (self , eta : float = 0.01 , n_iter : int = 50 , random_state : int = 1 ):
2910 self .eta = eta
3011 self .n_iter = n_iter
3112 self .random_state = random_state
32- self .w_ : np .ndarray | None = None
33- self .b_ : float | None = None
3413 self .errors_ : list [int ] = []
3514
3615 def fit (self , X : np .ndarray , y : np .ndarray ) -> "Perceptron" :
@@ -42,8 +21,9 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
4221
4322 for _ in range (self .n_iter ):
4423 errors = 0
45- for xi , target in zip (X , y ):
46- update = self .eta * (target - self .predict (xi ))
24+ for xi , target in zip (X , y , strict = True ):
25+ update = self .eta * (int (target ) - int (self .predict (xi )))
26+ assert self .w_ is not None and self .b_ is not None
4727 self .w_ += update * xi
4828 self .b_ += update
4929 errors += int (update != 0.0 )
@@ -52,33 +32,37 @@ def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
5232
5333 def net_input (self , X : np .ndarray ) -> np .ndarray | float :
5434 """Calculate net input."""
35+ assert self .w_ is not None and self .b_ is not None
5536 return np .dot (X , self .w_ ) + self .b_
5637
57- def predict (self , X : np .ndarray ) -> np .ndarray | int :
38+ def predict (self , X : np .ndarray ) -> np .ndarray :
5839 """Return class label after unit step."""
5940 return np .where (self .net_input (X ) >= 0.0 , 1 , 0 )
6041
6142
62- def plot_decision_regions (X : np .ndarray , y : np .ndarray , classifier : Perceptron , resolution : float = 0.02 ) -> None :
43+ def plot_decision_regions (
44+ X : np .ndarray ,
45+ y : np .ndarray ,
46+ classifier : Perceptron ,
47+ resolution : float = 0.02 ,
48+ ) -> None :
6349 """Plot decision regions for a 2D dataset and a fitted classifier."""
6450 markers = ("o" , "s" , "^" , "v" , "<" )
6551 colors = ("red" , "blue" , "lightgreen" , "gray" , "cyan" )
6652 cmap = ListedColormap (colors [: len (np .unique (y ))])
6753
68- # decision surface
6954 x1_min , x1_max = X [:, 0 ].min () - 1 , X [:, 0 ].max () + 1
7055 x2_min , x2_max = X [:, 1 ].min () - 1 , X [:, 1 ].max () + 1
7156 xx1 , xx2 = np .meshgrid (
7257 np .arange (x1_min , x1_max , resolution ),
7358 np .arange (x2_min , x2_max , resolution ),
7459 )
75- lab = classifier . predict ( np .array ( [xx1 .ravel (), xx2 .ravel ()]). T )
76- lab = lab .reshape (xx1 .shape )
60+ grid = np .c_ [xx1 .ravel (), xx2 .ravel ()]
61+ lab = classifier . predict ( grid ) .reshape (xx1 .shape )
7762 plt .contourf (xx1 , xx2 , lab , alpha = 0.3 , cmap = cmap )
7863 plt .xlim (xx1 .min (), xx1 .max ())
7964 plt .ylim (xx2 .min (), xx2 .max ())
8065
81- # class points
8266 for idx , cl in enumerate (np .unique (y )):
8367 plt .scatter (
8468 x = X [y == cl , 0 ],
0 commit comments