Machine Learning 101 — Perceptron
Perceptron es uno de los patrones más simples y antiguos en Machine Learning. Este patrón se utiliza para realizar la clasificación binaria de datos en dos categorías y está basado en el concepto de la neurona biológica y su forma de procesar la información.
En este patrón recibe una entrada y se obtiene un output binario. Cada entrada tiene un peso (w por weight), que representa la importancia de esa entrada para la clasificación. Luego suma los pesos de todas las entradas y, si la suma supera un umbral(thershold), produce una salida positiva. De lo contrario, produce una salida negativa. Esta clasificación se realiza mediante lo que llamamos una función de activación.
El entrenamiento del perceptrón se realiza mediante la actualización de los pesos en función de los errores cometidos en la clasificación. Si el perceptrón clasifica mal una entrada, se ajustan los pesos para disminuir el error. Este proceso se repite hasta que el perceptrón aprenda a clasificar correctamente todas las entradas.
Como implementamos el patrón en python
A continuación comparto el código para implementar este patron junto a unas funciones para realizar las pruebas, se puede modificar el set de datos para ver distintas salidas.
import numpy as np
class Perceptron:
def __init__(self, learning_rate=0.01, n_iters=1000):
self.lr = learning_rate
self.n_iters = n_iters
self.activation_func = self._unit_step_func
self.weights = None
self.bias = None
def fit(self, X, y): # Entrenamiento
n_samples, n_features = X.shape
# init param
self.weights = np.zeros(n_features)
self.bias = 0
y_ = np.array([1 if i > 0 else 0 for i in y])
# Estos dos bucles representan la función de enumeración
for _ in range(self.n_iters):
for idx, x_i in enumerate(X):
linear_output = np.dot(x_i, self.weights) + self.bias
y_predicted = self.activation_func(
linear_output) # Función de activación
# Perceptron - funcion de actualización
update = self.lr * (y_[idx] - y_predicted)
self.weights += update * x_i
self.bias += update
def predict(self, X): # predicción
linear_output = np.dot(X, self.weights) + self.bias
y_predicted = self.activation_func(linear_output)
return y_predicted
def _unit_step_func(self, x):
return np.where(x >= 0, 1, 0)
# Test de la implementación
if __name__ == "__main__":
# Imports
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn import datasets
def accuracy(y_true, y_pred):
accuracy = np.sum(y_true == y_pred) / len(y_true)
return accuracy
X, y = datasets.make_blobs(
n_samples=150, n_features=2, centers=2, cluster_std=1.05, random_state=2
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=123
)
p = Perceptron(learning_rate=0.01, n_iters=1000)
p.fit(X_train, y_train)
predictions = p.predict(X_test)
print("Perceptron - Presisición de la clasificación",
accuracy(y_test, predictions))
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.scatter(X_train[:, 0], X_train[:, 1], marker="o", c=y_train)
x0_1 = np.amin(X_train[:, 0])
x0_2 = np.amax(X_train[:, 0])
x1_1 = (-p.weights[0] * x0_1 - p.bias) / p.weights[1]
x1_2 = (-p.weights[0] * x0_2 - p.bias) / p.weights[1]
ax.plot([x0_1, x0_2], [x1_1, x1_2], "k")
ymin = np.amin(X_train[:, 1])
ymax = np.amax(X_train[:, 1])
ax.set_ylim([ymin - 3, ymax + 3])
plt.show()
Hay 3 funciones a tener en cuenta
- Función linear: es una operación matemática que calcula la suma ponderada de las entradas y los pesos asociados a cada una. Esta suma ponderada es la entrada de la función de activación.
- Función de enumeración: se utiliza para clasificar los datos de entrada en diferentes categorías. Se puede utilizar una función de enumeración para predecir la clase a la que pertenece un objeto en función de sus características.
- Función de activación: es una función no lineal que toma la entrada del perceptrón y produce una salida binaria, es decir, un valor de “1” o “0”. La función de activación más comúnmente utilizada en el perceptrón es la función escalón de Heaviside, que produce una salida de “1” si la entrada es mayor que un umbral, y una salida de “0” en caso contrario. Otras funciones de activación comunes incluyen la función sigmoide y la función de unidad lineal rectificada (ReLU).
Podes ver este código y el de los otros artículos en este repositorio.