Fundamentos de Machine Learning
Vamos a aprender los fundamientos del Machine Learning
El Machine Learning se basa en modelos que aprenden patrones a partir de los datos. La Regresión Lineal es uno de los modelos más simples y busca predecir un valor numérico continuo a partir de una o varias variables. Por otro lado, la Regresión Logística se utiliza cuando el objetivo es clasificar datos en categorías, modelando probabilidades en lugar de valores continuos. Finalmente, los Árboles de Decisión son modelos interpretables que dividen los datos en ramas basadas en preguntas simples, permitiendo tanto clasificación como regresión según la estructura de los datos. Estos tres modelos forman la base de muchos sistemas inteligentes actuales y son ideales para comenzar a entender el aprendizaje automático.
Preparación del Entorno
1# Importamos librerías de manejo numérico y procesamiento de datos.
2import numpy as np
3import pandas as pd
4
5# Importamos scikit-learn, nuestra librería base para utilizar algoritmos de machine learning.
6import sklearn
7
8# Importamos los datasets de scikit-learn
9from sklearn import datasets
10
11# Importamos librerías de scikit-learn para manejo de regresión lineal/logística.
12from sklearn import linear_model
13
14# Importamos librerías de scikit-learn para uso de clasificación de bosque aleatorio.
15from sklearn.ensemble import RandomForestClassifier
16
17# Importamos librerías de scikit-learn para clusterización con k-means
18from sklearn.cluster import KMeans
19
20# Importamos librerías para manejo del rendimiento (performance) de nuestros modelos.
21from sklearn.metrics import mean_squared_error, r2_score, accuracy_score
22
23# Importamos librerías para graficar.
24import matplotlib.pyplot as plt
25from mpl_toolkits.mplot3d import Axes3D
26
27# Definimos el tamaño del graficado (opcional).
28plt.rcParams['font.size'] = 15
29
30# Importamos los dataset de ejemplo de sklearn
31from sklearn import datasets
32
33# Importamos la librería de regresión lineal de sklearn
34from sklearn import linear_model
35
36# Carga de los datos de ejemplo, en este caso los Iris
37iris = datasets.load_iris()
38
39print(iris)
1# Llevamos estos datos a un DataFrame de pandas
2data = pd.DataFrame(data=iris.data, columns=iris.feature_names)
3
4# Creamos la especie de la flor
5targetEspecies = pd.DataFrame(data=iris.target, columns=['especies'])
6
7# Unimos ambos DataFrame para clasificarlos por especie
8data = pd.concat([data, targetEspecies], axis=1)
9
10# Mezclamos en orden aleatorio para evitar el sesgo de ordenamiento, dando equilibrio a todas las especies
11data = data.sample(frac=1, random_state=1234)
12
13# Imprimimos los primeros datos
14data.head()
1data.head() # Resultado esperado:
2# sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) especies
3# 91 6.1 3.0 4.6 1.4 1
4# 63 6.1 2.9 4.7 1.4 1
5# 103 6.3 2.9 5.6 1.8 2
6# 6 4.6 3.4 1.4 0.3 0
7# 59 5.2 2.7 3.9 1.4 1
Separando nuestros datos - training y testing
Antes de comenzar a crear modelos, es importante dividir nuestro conjunto de datos en Entrenamiento (Training) y Pruebas (Testing).
1# Fracción de entrenamiento 0.8, hallamos el 80% del valor longitudinal de los datos del DataFrame
2Ntrain = int(data.shape[0] * 0.8)
3
4# Creamos y separamos los datos de entrenamiento
5train = data.iloc[:Ntrain, :]
6
7# Creamos y seleccionamos los datos del testing
8test = data.iloc[Ntrain:, :]
Regresión lineal
La regresión lineal intenta predecir una salida de valor numérico. La especie de la flor es una etiqueta o label. Así que intentemos pensar en un modelo en el que podamos predecir la salida de un número. Para este ejemplo, supongamos que queremos predecir petal width o ancho del pétalo (Index = 3 en el DataFrame). Para comenzar, construyamos un modelo con solo 1 feature, el petal length o largo del pétalo (Index = 2 en el DataFrame). Primero, observemos la relación entre petal length y petal width en los datos:
1# Definimos variables de los datos
2plengh = pd.DataFrame(data['petal length (cm)'])
3pwidth = pd.DataFrame(data['petal width (cm)'])
4
5# Creamos un plot comparando los datos de tamano de los petalos con la cantidad
6fig, axs = plt.subplots(1, 1, figsize = (5, 5))
7ax1 = axs
8ax1.scatter(plengh, pwidth)
9ax1.set_title('Petal Widht vs. Lenght')
10ax1.set_ylabel('Petal width')
11ax1.set_xlabel('Petal lenght')
1# Importamos el objeto de regresion lineal de sklearn
2linearRegression = linear_model.LinearRegression()
3
4# Ajustamos el modelo a nuestros datos, o sea realizamos la regresión sobre los datos, en este caso tamaño vs cantidad de pétalos
5linearRegression.fit(plengh, pwidth)
6
7# Imprimimos los coeficientes
8print('coef', linearRegression.coef_)
9
10# Imprimimos el sesgo o bias
11print('Bias', linearRegression.intercept_)
12coef [[0.41575542]]
13Bias [-0.36307552]
1# Graficamos la regresión
2
3# Definimos variables para acceder de forma más simple a las columnas de nuestros features
4plength = data["petal length (cm)"]
5pwidth = data["petal width (cm)"]
6
7# Definimos un arreglo desde el valor mínimo del petal length hasta el máximo +1, en pasos de 0.5
8xvals = np.arange(plength.min(), plength.max()+1, 0.5)
9
10# Ecuación de nuestra regresión lineal (coeficiente y bias previamente obtenidos)
11yvals = 0.41 * xvals - 0.36
12
13# Gráfica
14fig, axs = plt.subplots(1, 1, figsize = (5, 5))
15ax1 = axs
16ax1.scatter(plength, pwidth)
17ax1.plot(xvals, yvals, 'k', linewidth = 3, color = 'orange')
1# Vamos a predecir y a mostrar qué tan bueno es nuestro modelo pasándole los datos de prueba del largo de pétalo
2ypredic = linearRegression.predict(pd.DataFrame(test.iloc[:, 2]))
3
4# Calculamos el MSE
5print('MSE: %.2f' % mean_squared_error(pd.DataFrame(test.iloc[:, 3]), ypredic))
6
7# Calculamos el R squared
8print('R2: %.2f' % r2_score(pd.DataFrame(test.iloc[:, 3]), ypredic))
9MSE: 0.04
10R2: 0.94
Regresión logística
Similar a la regresión lineal, la regresión logística ajusta una línea con los coeficientes. Sin embargo, a diferencia de la regresión lineal, este modelo tiene como objetivo clasificar datos. A partir del ancho de los pétalos, podemos ver que hay 3 comportamientos distintos de cada una de las especies de flores. Usando el largo/ancho del sépalo y el largo/ancho del pétalo, nos gustaría clasificar a qué especie de flor pertenece cada punto de datos. Para hacer esto podemos emplear regresión logística. En la regresión logística binaria, estamos tratando de ajustar un logaritmo de relación impar; es decir, una probabilidad de una clase particular en relación con la otra clase. En este problema hay 3 especies, por lo que la fórmula está ligeramente adaptada. Afortunadamente, scikit-learn puede manejar problemas de etiquetas binarias o de etiquetas múltiples con mucha facilidad. Para construir un modelo de regresión logística se puede utilizar lo siguiente:
1# Preparamos de nuevo los datos de entrenamiento y prueba
2# La última columna recordemos es la etiqueta de la especie
3
4xtrain = train.iloc[:, :-1] # input, training
5ytrain = train.iloc[:, -1] # output, training
6xtest = test.iloc[:, :-1] # input, test
7ytest = test.iloc[:, -1] # output, test
8
9# Configuramos la regresión logística con el método de regresión logística de linear_model.
10model_2 = linear_model.LogisticRegression()
11
12# Ajustamos el modelo con los datos de entrenamiento.
13model_2.fit(xtrain, ytrain)
14
15# Hacer predicciones con el conjunto de prueba.
16ypred = model_2.predict(xtest)
17
18print(ypred)
19
20# Probamos el accuracy del modelo generado
21print("Testing accuracy =", accuracy_score(ytest, ypred))
22
23# Un ejemplo de la matriz de confusión con sklearn
24# Importamos el método de matriz de confusión desde sklearn
25from sklearn.metrics import confusion_matrix
26
27# Aplicamos la matriz a nuestros valores de testing y los valores de predicción generados.
28confusion_matrix(ytest, ypred)
1# Creamos el clasificador
2clf = RandomForestClassifier(n_estimators=3)
3
4# Entrenamos el modelo
5clf.fit(xtrain, ytrain)
6
7# Generamos predicción
8y_pred = clf.predict(xtest)
9
10# Probamos el modelo con accuracy
11print("Testing accuracy =", accuracy_score(ytest, y_pred))
12
13# Inicializamos el modelo KMeans.
14k2model = KMeans(n_clusters=2, random_state=42)
15
16# Ajustar todos los puntos de datos EXCEPTO para la especie.
17k2model.fit(data[["petal length (cm)", "petal width (cm)"]])
18
19# Calculamos e imprimimos la inercia desde el modelo de Kmeans.
20print("Inertia =", k2model.inertia_)
21
22# Calculamos e imprimimos la posición de los clústers.
23print("Centroids (x, y) =\n", k2model.cluster_centers_) Testing accuracy = 1.0
1# Resultados del modelo KMeans
2print("Inertia =", k2model.inertia_)
3print("Centroids (x, y) =\n", k2model.cluster_centers_)
4
5# Salida esperada:
6# Inertia = 86.39021984551397
7# Centroids (x, y) =
8# [[1.49215686 0.2627451 ]
9# [4.92525253 1.68181818]]
1# Graficamos los datos con la línea para setosa.
2f = plt.figure(figsize=(5,5))
3ax = f.add_subplot(1,1,1)
4
5# Setosa
6ax.scatter(data[data.iloc[:, -1]==0]["petal length (cm)"],
7 data[data.iloc[:, -1]==0]["petal width (cm)"],
8 c='k')
9
10# Versicolor
11ax.scatter(data[data.iloc[:, -1]==1]["petal length (cm)"],
12 data[data.iloc[:, -1]==1]["petal width (cm)"],
13 c='r')
14
15# Virginica
16ax.scatter(data[data.iloc[:, -1]==2]["petal length (cm)"],
17 data[data.iloc[:, -1]==2]["petal width (cm)"],
18 c='b')
19
20ax.legend(["Setosa", "Versicolor", "Virginica"])
21
22# Graficamos los centroides de los clústers (output en Petal Length x Petal Width)
23ax.plot(k2model.cluster_centers_[:,0],
24 k2model.cluster_centers_[:,1],
25 "g*", markersize=30)
26
27ax.set_xlabel("Petal Length")
28ax.set_ylabel("Petal Width")
29ax.set_title("Petal Length v. Width")
30f.tight_layout()
Comentarios
Cargando comentarios...