Implementación de SVM y Kernel SVM con Scikit-Learn de Python

    UN máquinas de vectores soporte (SVM) es un tipo de algoritmo de clasificación de Machine Learning supervisado. Las SVM se introdujeron inicialmente en la década de 1960 y luego se perfeccionaron en la década de 1990. Sin embargo, es solo ahora que se están volviendo extremadamente populares, debido a su capacidad para lograr resultados brillantes. Las SVM se implementan de una manera única en comparación con otros algoritmos de Machine Learning.

    En este artículo veremos qué son los algoritmos de máquinas de vectores de soporte, la breve teoría detrás de la máquina de vectores de soporte y su implementación en la biblioteca Scikit-Learn de Python. Luego avanzaremos hacia un concepto avanzado de SVM, conocido como Kernel SVM, y también lo implementaremos con la ayuda de Scikit-Learn.

    SVM simple

    En el caso de datos separables linealmente en dos dimensiones, como se muestra en la Figura 1, un algoritmo de Machine Learning típico intenta encontrar un límite que divida los datos de tal manera que se pueda minimizar el error de clasificación errónea. Si observa de cerca la Fig. 1, puede haber varios límites que dividan correctamente los puntos de datos. Las dos líneas discontinuas y una línea continua clasifican los datos correctamente.

    Fig 1: Límites de decisión múltiple

    SVM se diferencia de los otros algoritmos de clasificación en la forma en que elige el límite de decisión que maximiza la distancia desde los puntos de datos más cercanos de todas las clases. Una SVM no solo encuentra un límite de decisión; encuentra el límite de decisión más óptimo.

    El límite de decisión más óptimo es el que tiene un margen máximo desde los puntos más cercanos de todas las clases. Los puntos más cercanos al límite de decisión que maximizan la distancia entre el límite de decisión y los puntos se denominan vectores de apoyo, como se ve en la figura 2. El límite de decisión en el caso de máquinas de vectores de apoyo se denomina clasificador de margen máximo, o hiperplano de margen máximo. .

    Fig 2: Límite de decisión con vectores de soporte

    Hay matemáticas complejas involucradas detrás de encontrar los vectores de soporte, calcular el margen entre el límite de decisión y los vectores de soporte y maximizar este margen. En este tutorial no entraremos en detalles de las matemáticas, más bien veremos cómo se implementan SVM y Kernel SVM a través de la biblioteca Python Scikit-Learn.

    Implementación de SVM con Scikit-Learn

    El conjunto de datos que vamos a usar en esta sección es el mismo que usamos en la sección de clasificación del tutorial del árbol de decisiones.

    Nuestra tarea es predecir si un billete de moneda bancaria es auténtico o no basándonos en cuatro atributos del billete, es decir, la asimetría de la imagen transformada wavelet, la variación de la imagen, la entropía de la imagen y la curtosis de la imagen. Este es un problema de clasificación binaria y usaremos el algoritmo SVM para resolver este problema. El resto de la sección consta de pasos estándar de Machine Learning.

    Importación de bibliotecas

    El siguiente script importa las bibliotecas necesarias:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    

    Importar el conjunto de datos

    Los datos están disponibles para su descarga en el siguiente enlace:

    https://drive.google.com/file/d/13nw-uRXPY8XIZQxKRNZ3yYlho-CYm_Qt/view

    La información detallada sobre los datos está disponible en el siguiente enlace:

    https://archive.ics.uci.edu/ml/datasets/banknote+authentication

    Descargue el conjunto de datos del enlace de Google Drive y guárdelo localmente en su máquina. Para este ejemplo, el archivo CSV para el conjunto de datos se almacena en la carpeta “Conjuntos de datos” de la unidad D en mi computadora con Windows. El script lee el archivo de esta ruta. Puede cambiar la ruta del archivo de su computadora en consecuencia.

    Para leer datos de un archivo CSV, la forma más sencilla es utilizar read_csv método de la biblioteca de pandas. El siguiente código lee datos de billetes de moneda bancaria en el marco de datos de pandas:

    bankdata = pd.read_csv("D:/Datasets/bill_authentication.csv")
    

    Análisis exploratorio de datos

    Hay formas prácticamente ilimitadas de analizar conjuntos de datos con una variedad de bibliotecas de Python. En aras de la simplicidad, solo verificaremos las dimensiones de los datos y veremos los primeros registros. Para ver las filas y columnas y de los datos, ejecute el siguiente comando:

    bankdata.shape
    

    En la salida verá (1372,5). Esto significa que el conjunto de datos de billetes de banco tiene 1372 filas y 5 columnas.

    Para tener una idea de cómo se ve realmente nuestro conjunto de datos, ejecute el siguiente comando:

    bankdata.head()
    

    La salida se verá así:

    Clase de entropía de curtosis de asimetría de varianza

    03.621608.6661-2,8073-0,446990
    14.545908.1674-2,4586-1.462100
    23.86600-2,63831.92420.106450
    33.456609.5228-4.0112-3.594400
    40.32924-4.45524.5718-0,988800

    Puede ver que todos los atributos del conjunto de datos son numéricos. La etiqueta también es numérica, es decir, 0 y 1.

    Preprocesamiento de datos

    El preprocesamiento de datos implica (1) dividir los datos en atributos y etiquetas y (2) dividir los datos en conjuntos de entrenamiento y prueba.

    Para dividir los datos en atributos y etiquetas, ejecute el siguiente código:

    X = bankdata.drop('Class', axis=1)
    y = bankdata['Class']
    

    En la primera línea del script anterior, todas las columnas del bankdata el marco de datos se almacena en el X variable excepto la columna “Clase”, que es la columna de la etiqueta. los drop() método elimina esta columna.

    En la segunda línea, solo la columna de clase se almacena en el y variable. En este momento X variable contiene atributos mientras y variable contiene las etiquetas correspondientes.

    Una vez que los datos se dividen en atributos y etiquetas, el último paso previo al procesamiento es dividir los datos en conjuntos de entrenamiento y prueba. Afortunadamente, el model_selection biblioteca de la biblioteca Scikit-Learn contiene la train_test_split método que nos permite dividir sin problemas los datos en conjuntos de prueba y entrenamiento.

    Ejecute el siguiente script para hacerlo:

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)
    

    Entrenando el algoritmo

    Hemos dividido los datos en conjuntos de entrenamiento y prueba. Ahora es el momento de entrenar a nuestro SVM en los datos de entrenamiento. Scikit-Learn contiene el svm biblioteca, que contiene clases integradas para diferentes algoritmos SVM. Dado que vamos a realizar una tarea de clasificación, usaremos la clase de clasificador de vectores de soporte, que se escribe como SVC en el Scikit-Learn’s svm biblioteca. Esta clase toma un parámetro, que es el tipo de kernel. Esto es muy importante. En el caso de una SVM simple, simplemente establecemos este parámetro como “lineal”, ya que las SVM simples solo pueden clasificar datos separables linealmente. Veremos núcleos no lineales en la siguiente sección.

    los fit Se llama al método de la clase SVC para entrenar el algoritmo en los datos de entrenamiento, que se pasan como un parámetro al fit método. Ejecute el siguiente código para entrenar el algoritmo:

    from sklearn.svm import SVC
    svclassifier = SVC(kernel="linear")
    svclassifier.fit(X_train, y_train)
    

    Haciendo predicciones

    Para hacer predicciones, el predict método del SVC se utiliza la clase. Eche un vistazo al siguiente código:

    y_pred = svclassifier.predict(X_test)
    

    Evaluar el algoritmo

    La matriz de confusión, la precisión, la recuperación y las medidas F1 son las métricas más utilizadas para las tareas de clasificación. Scikit-Learn’s metrics biblioteca contiene el classification_report y confusion_matrix métodos, que se pueden utilizar fácilmente para averiguar los valores de estas métricas importantes.

    Aquí está el código para encontrar estas métricas:

    from sklearn.metrics import classification_report, confusion_matrix
    print(confusion_matrix(y_test,y_pred))
    print(classification_report(y_test,y_pred))
    

    Resultados

    Los resultados de la evaluación son los siguientes:

    [[152    0]
     [  1  122]]
                  precision   recall   f1-score   support
    
               0       0.99     1.00       1.00       152
               1       1.00     0.99       1.00       123
    
    avg / total        1.00     1.00       1.00       275
    

    De los resultados se puede observar que SVM superó ligeramente el algoritmo del árbol de decisión. Solo hay una clasificación errónea en el caso del algoritmo SVM en comparación con cuatro clasificaciones erróneas en el caso del algoritmo del árbol de decisión.

    SVM de kernel

    En la sección anterior vimos cómo se puede utilizar el algoritmo SVM simple para encontrar el límite de decisión para datos separables linealmente. Sin embargo, en el caso de datos separables de forma no lineal, como el que se muestra en la Fig. 3, no se puede utilizar una línea recta como límite de decisión.

    Fig 3: Datos separables de forma no lineal

    En el caso de datos separables de forma no lineal, no se puede utilizar el algoritmo SVM simple. Más bien, se utiliza una versión modificada de SVM, llamada Kernel SVM.

    Básicamente, el kernel SVM proyecta las dimensiones inferiores de los datos separables no linealmente a datos separables linealmente en dimensiones superiores de tal manera que los puntos de datos que pertenecen a clases diferentes se asignan a dimensiones diferentes. Nuevamente, hay matemáticas complejas involucradas en esto, pero no tiene que preocuparse por eso para usar SVM. Más bien, podemos simplemente usar la biblioteca Scikit-Learn de Python para implementar y usar el kernel SVM.

    Implementación de Kernel SVM con Scikit-Learn

    La implementación de Kernel SVM con Scikit-Learn es similar a la simple SVM. En esta sección, usaremos los famosos conjunto de datos de iris para predecir la categoría a la que pertenece una planta basándose en cuatro atributos: ancho del sépalo, largo del sépalo, ancho del pétalo y largo del pétalo.

    El conjunto de datos se puede descargar desde el siguiente enlace:

    https://archive.ics.uci.edu/ml/datasets/iris4

    El resto de los pasos son pasos típicos de Machine Learning y necesitan muy poca explicación hasta que llegamos a la parte donde entrenamos nuestro Kernel SVM.

    Importación de bibliotecas

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    

    Importar el conjunto de datos

    url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
    
    # Assign colum names to the dataset
    colnames = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class']
    
    # Read dataset to pandas dataframe
    irisdata = pd.read_csv(url, names=colnames)
    

    Preprocesamiento

    X = irisdata.drop('Class', axis=1)
    y = irisdata['Class']
    

    Prueba de tren dividida

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)
    

    Entrenando el algoritmo

    Para entrenar el kernel SVM, usamos el mismo SVC clase de Scikit-Learn’s svm biblioteca. La diferencia radica en el valor del parámetro kernel de la SVC clase. En el caso de la SVM simple, usamos “lineal” como valor para el parámetro del kernel. Sin embargo, para el kernel SVM puede usar kernel gaussiano, polinomial, sigmoide o computable. Implementaremos núcleos polinomiales, gaussianos y sigmoides para ver cuál funciona mejor para nuestro problema.

    1. Núcleo polinomial

    En el caso de núcleo polinomial, también debe pasar un valor para el degree parámetro de la SVC clase. Este es básicamente el grado del polinomio. Eche un vistazo a cómo podemos usar un núcleo polinomial para implementar SVM del núcleo:

    from sklearn.svm import SVC
    svclassifier = SVC(kernel="poly", degree=8)
    svclassifier.fit(X_train, y_train)
    

    Haciendo predicciones

    Una vez que hemos entrenado el algoritmo, el siguiente paso es hacer predicciones sobre los datos de prueba.

    Ejecute el siguiente script para hacerlo:

    y_pred = svclassifier.predict(X_test)
    

    Evaluar el algoritmo

    Como de costumbre, el paso final de cualquier algoritmo de Machine Learning es realizar evaluaciones para el núcleo polinomial. Ejecute el siguiente script:

    from sklearn.metrics import classification_report, confusion_matrix
    print(confusion_matrix(y_test, y_pred))
    print(classification_report(y_test, y_pred))
    

    La salida para el kernel SVM usando kernel polinomial se ve así:

    [[11  0  0]
     [ 0 12  1]
     [ 0  0  6]]
                     precision   recall   f1-score   support
    
        Iris-setosa       1.00     1.00       1.00        11
    Iris-versicolor       1.00     0.92       0.96        13
     Iris-virginica       0.86     1.00       0.92         6
    
        avg / total       0.97     0.97       0.97        30
    

    Ahora repitamos los mismos pasos para los núcleos gaussiano y sigmoide.

    2. Kernel gaussiano

    Eche un vistazo a cómo podemos usar el kernel polinomial para implementar el SVM del kernel:

    from sklearn.svm import SVC
    svclassifier = SVC(kernel="rbf")
    svclassifier.fit(X_train, y_train)
    

    Para usar el kernel gaussiano, debe especificar ‘rbf’ como valor para el parámetro Kernel de la clase SVC.

    Predicción y evaluación

    y_pred = svclassifier.predict(X_test)
    
    from sklearn.metrics import classification_report, confusion_matrix
    print(confusion_matrix(y_test, y_pred))
    print(classification_report(y_test, y_pred))
    

    La salida del Kernel SVM con el kernel gaussiano se ve así:

    [[11  0  0]
     [ 0 13  0]
     [ 0  0  6]]
                     precision   recall   f1-score   support
    
        Iris-setosa       1.00     1.00       1.00        11
    Iris-versicolor       1.00     1.00       1.00        13
     Iris-virginica       1.00     1.00       1.00         6
    
        avg / total       1.00     1.00       1.00        30
    

    3. Núcleo sigmoideo

    Finalmente, usemos un kernel sigmoide para implementar Kernel SVM. Eche un vistazo al siguiente guión:

    from sklearn.svm import SVC
    svclassifier = SVC(kernel="sigmoid")
    svclassifier.fit(X_train, y_train)
    

    Para usar el kernel sigmoide, debe especificar ‘sigmoide’ como valor para el kernel parámetro de la SVC clase.

    Predicción y evaluación

    y_pred = svclassifier.predict(X_test)
    
    from sklearn.metrics import classification_report, confusion_matrix
    print(confusion_matrix(y_test, y_pred))
    print(classification_report(y_test, y_pred))
    

    La salida del Kernel SVM con el kernel Sigmoid se ve así:

    [[ 0  0 11]
     [ 0  0 13]
     [ 0  0  6]]
                     precision   recall   f1-score   support
    
        Iris-setosa       0.00     0.00       0.00        11
    Iris-versicolor       0.00     0.00       0.00        13
     Iris-virginica       0.20     1.00       0.33         6
    
        avg / total       0.04     0.20       0.07        30
    

    Comparación del rendimiento del kernel

    Si comparamos el rendimiento de los diferentes tipos de núcleos, podemos ver claramente que el núcleo sigmoide es el peor. Esto se debe a que la función sigmoidea devuelve dos valores, 0 y 1, por lo que es más adecuada para problemas de clasificación binaria. Sin embargo, en nuestro caso teníamos tres clases de salida.

    Entre el kernel gaussiano y el kernel polinomial, podemos ver que el kernel gaussiano logró una tasa de predicción perfecta del 100%, mientras que el kernel polinomial clasificó erróneamente una instancia. Por lo tanto, el kernel gaussiano se desempeñó ligeramente mejor. Sin embargo, no existe una regla estricta y rápida sobre qué kernel se desempeña mejor en cada escenario. Se trata de probar todos los núcleos y seleccionar el que tenga los mejores resultados en su conjunto de datos de prueba.

    Recursos

    ¿Quiere obtener más información sobre SVM, Scikit-Learn y otros algoritmos útiles de Machine Learning? Recomiendo consultar algunos recursos más detallados, como uno de estos libros:

    Conclusión

    En este artículo estudiamos SVMs simples y de kernel. Estudiamos la intuición detrás del algoritmo SVM y cómo se puede implementar con la biblioteca Scikit-Learn de Python. También estudiamos diferentes tipos de kernels que se pueden usar para implementar kernel SVM. Le sugiero que intente implementar estos algoritmos en conjuntos de datos del mundo real disponibles en lugares como kaggle.com.

    También le sugiero que explore las matemáticas reales detrás de la SVM. Aunque no necesariamente lo necesitará para utilizar el algoritmo SVM, sigue siendo muy útil saber qué está sucediendo realmente detrás de la escena mientras su algoritmo encuentra límites de decisión.

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *