Tema 4. Aplicación de técnicas de aprendizaje no supervisado.pdf
Document Details
Uploaded by BelievableLobster
Tags
Full Transcript
Aplicación de técnicas de aprendizaje automático no supervisado Tema 4 Aplicación de técnicas de aprendizaje no supervisado 0 Aplicación de técnicas de aprendizaje automático no supervisado Ejemplo de reduccion de dimensionalidad empleando PCA En el tema anterior hemos estudiado las técnicas de apre...
Aplicación de técnicas de aprendizaje automático no supervisado Tema 4 Aplicación de técnicas de aprendizaje no supervisado 0 Aplicación de técnicas de aprendizaje automático no supervisado Ejemplo de reduccion de dimensionalidad empleando PCA En el tema anterior hemos estudiado las técnicas de aprendizaje supervisado, en las cuales trabajamos con un conjunto de datos etiquetados, esto es, que ya tienen asociada una categoría. Sin embargo, la gran mayoría de los problemas a resolver en aprendizaje automático hacen referencia a conjuntos de datos no etiquetados. Resolución a mano En el tema anterior habiamos estudiado el caso de un programa de IA que reconocia si un captcha había sido resuelto por un humano o por una maquina. En ese ejercicio disponiamos de un conjunto de datos que empleabamos para entrenamiento, y que se muestra en la siguiente matriz, una vez estandarizados En el aprendizaje no supervisado tratamos de encontrar algoritmos que realicen las tareas de agrupamiento de esos conjuntos de datos no etiquetados para crear categorías. Dentro de las tareas en aprendizaje no supervisado podemos distinguir las siguientes: Reducción de dimensionalidad: que permite disminuir el número de variables de entrada del conjunto de datos eliminando valores repetidos, que no ofrecen información o fuertemente correlacionados. Se usa PCA para ello. Agrupamiento: se basa en juntar instancias similares en grupos. Aquí caben técnicas como K-Means, agrupamiento aglomerativo y partitivo. Basados en densidad: permiten agrupar los registros de datos en conjuntos que coinciden con zonas de alta densidad de datos, aun con la existencia de muchos valores fuera de rango. Detección de anomalías: determina un estándar de datos “normales” para luego identificar los datos que se salen de esa estándar. Los métodos generadores como la mezcla gaussiana permiten identificar estos datos. La matriz de covarianza es la que se muestra a continuación El siguiente paso es calcular los valores y vectores propios. Empezaremos calculando los valores propios, para lo cual vamos a resolver un sistema de ecuaciones de la forma ȁ 𝑆 − 𝜆 ∙ 𝐼ȁ = 0 donde S es la matriz de covarianza, λ el conjunto de valores propios e I la matriz identidad. En la página https://mxncalc.com/es/autovaloresautovectores-calculadora podemos resolver la ecuación. Los valores propios son 𝜆1 = 2.829 𝜆2 = 1.095 𝜆3 = 0.980 𝜆4 = 0.404 𝜆5 = 0.224 𝜆6 = 0.092 𝜆7 = 0.063 𝜆8 = 0.003 𝜆6 = 0.000 Y los vectores propios son Como hemos comentado en el apartado anterior, en muchos problemas es posible reducir el número de variables de los registros de datos, bien porque no ofrecen información, bien porque están correlacionadas entre sí. Por otro lado, tener conjuntos de datos con demasiadas variables o -1.818 3.906 5.882 5.930 3.649 0.341 -0.806 -0.529 -9.331 13.488 -1.717 -0.649 -16.064 2.180 0.747 -3.880 -3.178 -1.764 -0.540 -0.217 1.090 0.096 -0.057 -1.031 0.239 -0.634 0.378 0.364 -0.684 -0.343 0.157 -0.796 0.016 0.321 0.074 -0.218 -0.100 -2.132 -0.279 1.352 0.331 -0.034 0.299 -0.648 -0.128 1.267 -2.351 0.069 0.296 2.164 -1.732 -0.884 2.186 -0.809 2.558 -2.356 0.551 0.392 -3.116 2.558 0.337 0.507 -0.285 -0.068 0.396 0.289 -1.580 1.185 0.256 0.684 0.264 0.213 1 1 1 1 1 1 1 1 1 La varianza se conserva en un 95 por ciento con los cinco primeros componentes, tal y como se puede ver aquí 70 Aplicación de técnicas de aprendizaje automático no supervisado 2.829+1.095+0.980+0.404+0.224)/(2.829+1. 095+0.980+0.404+0.224+0.092+0.063+0.003 +0.000)=0.972≈97 % Nos quedamos con las cinco primeras componentes y a partir de ahí la matriz que se obtiene es la siguiente Resolución del ejemplo de PCA anterior con Python sin Scikit-learn import numpy as np import pandas as pd from scipy import stats from sklearn.preprocessing import StandardScaler df=pd.read_csv(r'D:\Unidad USB\uoc\aprendizaje computacional\PEC1_2022\small.csv') #convierte SHAPE a binario. y=pd.get_dummies(df.SHAPE,prefix='SHAPE') #selecciona las columnas con los datos numéricos TIME=df["TIME"] STROKE=df["STROKE"] MSE=df["MSE"] SSE=df["SSE"] CERR=df["CERR"] #estandariza las columnas TIME_STD=stats.zscore(TIME,axis=0) STROKE_STD=stats.zscore(STROKE,axis=0) MSE_STD=stats.zscore(MSE,axis=0) SSE_STD=stats.zscore(SSE,axis=0) CERR_STD = stats.zscore(CERR,axis=0) #selecciona las columnas de los binarios de SHAPE SHAPE_0=y['SHAPE_0'] SHAPE_1=y['SHAPE_1'] SHAPE_2=y['SHAPE_2'] SHAPE_3=y['SHAPE_3'] #crea el data frame df_std=pd.DataFrame({'TIME':TIME_STD, 'STROKE': STROKE_STD, 'MSE':MSE_STD, 'SSE':SSE_STD,'CERR': CERR_STD, 'SHAPE_0':SHAPE_0,'SHAPE_1':SHAPE_1, 'SHAPE_2':SHAPE_2, 'SHAPE_3':SHAPE_3}) print(df_std) #obtiene la matriz de covarianza covarianza=np.cov(df_std,rowvar=False) #obtiene valores y vectores propios valores_propios, vectores_propios=np.linalg.eig(covarianza) vectores_propios=vectores_propios.T # argsort devuelve un vector que indica la posicion ordenada -primero, segundo, etc..- de #cada elemento del array que se introduce como parámetro, ordenándola de menor a mayor componentes_ordenados =np.argsort(valores_propios)[::1] #obtiene la matriz de proyeccion y el nuevo espacio de variables de menor dimensio matriz_proyeccion = vectores_propios[componentes_ordenados[:6]] #multiplicamos la matriz de proyeccion por los datos X_t=np.dot(df_std,matriz_proyeccion.T) print(X_t) 71 dimensiones provoca que la distancia en términos absolutos entre dos de esos registros sea muy grande con lo que hay demasiada dispersión y los registros de prueba que se empleen estén demasiado separados de los registros de entrenamiento con los que se creó el modelo. Podemos reducir la dimensionalidad proyectando el conjunto de registros de datos sobre un subespacio del mismo con menos dimensiones -proyección – o bien partiendo del hecho de que la mayor parte de los registros de datos de alta dimensionalidad quedan cerca de una variedad de d dimensiones o variables, contenida en un espacio de n dimensiones o variables, que es el conjunto de registros de datos de alta dimensionalidad. En el siguiente apartado vamos a trabajar con las técnicas más conocidas para reducir la dimensionalidad, fundamentalmente el análisis de componentes principales o Principal Component Analysis -PCA-. Es una técnica estadística de aprendizaje no supervisado que permite eliminar variables correlacionadas a través de la rotación de los registros de datos, de tal manera que las variables rotadas ya no están correlacionadas entre sí linealmente, eligiendo un subconjunto de ellas -las más relevantes- que será con el que se trabaje en las restantes técnicas de aprendizaje no supervisado. PCA puede realizar una gran reducción de dimensionalidad al trabajar sobre variables correlacionadas, mejorando los resultados obtenidos por las técnicas de aprendizaje no supervisado. La técnica de PCA consta de los siguientes pasos empleando Scikit-Learn: En primer lugar se deben estandarizar o normalizar los datos, para lo cual se usa StandardScaler. Una vez hecho esto se centran los datos restando la media de cada variable. El segundo paso consiste en crear la matriz de covarianza. La matriz de covarianza es una matriz de la forma siguiente Aplicación de técnicas de aprendizaje automático no supervisado 𝒎 ̅̅̅̅ ∑𝒊(𝒙𝟏𝒊 − ̅̅̅ ∑𝒊(𝒙𝟏𝒊 − ̅̅̅ 𝒙𝟏 ) ∙ (𝒙𝟏𝒊 − ̅̅̅ 𝒙𝟏 ) ∑𝒊(𝒙𝟏𝒊 − ̅̅̅ 𝒙𝟏 ) ∙ (𝒙𝒎 𝒙𝟏 ) ∙ (𝒙𝟐𝒊 − ̅̅̅ 𝒙𝟐 ) 𝒊 −𝒙 ) … 𝒏−𝟏 𝒏−𝟏 𝒏−𝟏 𝟐 ̅̅̅ 𝟐 ) ∙ (𝒙𝒎 − ̅̅̅̅ 𝟐 𝟐 ̅̅̅ 𝟐 ∑𝒊(𝒙𝟐𝒊 − ̅̅̅ ∑ 𝒙𝟐 ) ∙ (𝒙𝟏𝒊 − ̅̅̅ 𝒙𝟏 ) ∑𝒊(𝒙𝟐𝒊 − ̅̅̅ (𝒙 − 𝒙 𝒙𝒎 ) 𝒊 𝒊 𝒙 ) ∙ (𝒙𝒊 − 𝒙 ) 𝒊 … 𝒏−𝟏 𝒏−𝟏 𝒏 −… 𝟏 … … 𝒎 𝟏 𝒎 𝟐 𝒎 𝒎 𝒎 ̅̅̅𝟏 𝒎 ̅̅̅𝟐 ̅̅̅̅ ̅̅̅̅ ̅̅̅̅ ̅̅̅̅ ∑𝒊(𝒙𝒎 ∑𝒊(𝒙𝒎 𝒊 − 𝒙 ) ∙ (𝒙𝒊 − 𝒙 ) 𝒊 − 𝒙 ) ∙ (𝒙𝒊 − 𝒙 ) ∑𝒊(𝒙𝒊 − 𝒙 ) ∙ (𝒙𝒊 − 𝒙 ) … [ ] 𝒏−𝟏 𝒏−𝟏 𝒏−𝟏 donde xm son las diferentes variables con n valores cada una, ̅̅̅̅ 𝑥 𝑚 es la media de cada una de esas variables, y cada uno de los términos de la diagonal de la matriz es la expresión de la varianza -𝜎𝑥 𝑚𝑥 𝑚 - de una variable dada xm, que mide la variabilidad de los valores de una variables respecto a su media, mientras que los términos no diagonales son las covarianzas, que expresan la corrrelación entre dos variables diferentes - 𝜎𝑥 𝑚𝑥 𝑘 -. El siguiente paso es obtener los valores y vectores propios de la matriz de covarianza, empleando un método llamado descomposición en valores singulares -SVD-,y a partir de ellos calcular las componentes principales. Este método implica la conversión de la matriz de covarianza en el producto de tres matrices 𝑨=𝑼∙𝑺∙𝑽 donde U es la matriz inversa de vectores propios, V la de vectores propios y S la matriz diagonal de valores propios. Los vectores propios son columnas de valores, que corresponden a características “virtuales” que guardan la varianza, esto es, se crean como una combinación de las características existentes del conjunto de datos, pero con la mínima correlación posible entre ellas, a diferencia de los atributos característicos del conjunto de datos, que pueden estar muy correlacionados entre sí. En términos matemáticos, las componentes principales son los vectores propios y son las direcciones de los nuevos ejes del hiperplano que contiene todos los puntos del conjunto de datos. La primera componente principal es la que contiene la mayor cantidad de varianza, la segunda componente principal es la que contiene la segunda mayor cantidad de varianza, y así sucesivamente. Hay tantas componentes principales como variables hay en cada registro del conjunto de datos. Los valores propios asociados a los vectores propios indican la importancia de las componentes princi Resolucion del ejemplo de PCA anterior en Python empleando StandardScaler import numpy as np import pandas as pd from scipy import stats from sklearn.preprocessing import StandardScaler df=pd.read_csv(r'D:\Unidad USB\uoc\aprendizaje computacional\PEC1_2022\small.csv') #convierte SHAPE a binario. y=pd.get_dummies(df.SHAPE,prefix='SHAPE') #selecciona las columnas con los datos numéricos TIME=df["TIME"] STROKE=df["STROKE"] MSE=df["MSE"] SSE=df["SSE"] CERR=df["CERR"] df_2=pd.DataFrame({'TIME':TIME, 'STROKE': STROKE, 'MSE':MSE, 'SSE':SSE,'CERR': CERR}) #estandariza las columnas estandarizador = StandardScaler() df_std_2=estandarizador.fit_transform(df_2) TIME_STD=df_std_2[:,0] STROKE_STD=df_std_2[:,1] MSE_STD=df_std_2[:,2] SSE_STD=df_std_2[:,3] CERR_STD=df_std_2[:,4] #selecciona las columnas de los binarios de SHAPE SHAPE_0=y['SHAPE_0'] SHAPE_1=y['SHAPE_1'] SHAPE_2=y['SHAPE_2'] SHAPE_3=y['SHAPE_3'] #crea el data frame df_std=pd.DataFrame({'TIME':TIME_STD, 'STROKE': STROKE_STD, 'MSE':MSE_STD, 'SSE':SSE_STD,'CERR': CERR_STD, 'SHAPE_0':SHAPE_0,'SHAPE_1':SHAPE_1, 'SHAPE_2':SHAPE_2, 'SHAPE_3':SHAPE_3}) print(df_std) #obtiene la matriz de covarianza covarianza=np.cov(df_std,rowvar=False) #obtiene valores y vectores propios valores_propios, vectores_propios=np.linalg.eig(covarianza) vectores_propios=vectores_propios.T componentes_ordenados =np.argsort(valores_propios)[::1] #obtiene la matriz de proyeccion y el nuevo espacio de variables de menor dimension matriz_proyeccion = vectores_propios[componentes_ordenados[:6]] X_t=np.dot(df_std,matriz_proyeccion.T) print(X_t) Resolución del ejemplo de PCA anterior en Python empleando Scikit-Learn # partimos del dataframe df_std from sklearn.decomposition import PCA pca=PCA(n_components=0.95) pca.fit(df_std) datos_pca=pca.transform(df_std) print('datos originales:{}'.format(str(df_std.shape))) print('datos reducidos:{}'.format(str(datos_pca.shape))) df_pca=pd.DataFrame(data=datos_pca, columns=['CP1', 'CP2', 'CP3','CP4', 'CP5'']) print(df_pca) 72 Aplicación de técnicas de aprendizaje automático no supervisado import numpy as np import pandas as pd from scipy import stats from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import OneHotEncoder df=pd.read_csv(r'D:\Unidad USB\uoc\aprendizaje computacional\PEC1_2022\small.csv') #convierte SHAPE a binario. encoder = OneHotEncoder(handle_unknown='ignore') encoder_df = pd.DataFrame(encoder.fit_transform(df[['SHAPE']]).toarra y()) #m une las columnas creadas con one-hot-encoding con el dataframe df = df.join(encoder_df) #borra la columna df.drop('SHAPE', axis=1, inplace=True) #ver el dataframe print(df) #estandariza las columnas estandarizador = StandardScaler() df_std=estandarizador.fit_transform(df) print(df_std) #obtiene la matriz de covarianza covarianza=np.cov(df_std,rowvar=False) #obtiene valores y vectores propios valores_propios, vectores_propios=np.linalg.eig(covarianza) vectores_propios=vectores_propios.T componentes_ordenados =np.argsort(valores_propios)[::1] #obtiene la matriz de proyeccion y el nuevo espacio de variables de menor dimension matriz_proyeccion = vectores_propios[componentes_ordenados[:6]] X_t=np.dot(df_std,matriz_proyeccion.T) print(X_t) Resolución del ejemplo de PCA anterior empleando StandardScaler y on-hotenconding – segundo método- -pales dentro del conjunto -la mayor varianza- y se ordenan de mayor a menor. A continuación, se lleva a cabo la proyección, esto es, la reducción de los m componentes principales a un número d donde n_components indica el número de componentes principales, o bien el porcentaje de conservación de la varianza que tiene que ofrecer el algoritmo -el 95 por ciento o 0.95 de manera habitualEl método transform() de PCA nos devuelve la matriz de componentes principales que conforma el nuevo conjunto de datos reducidos nuevo_conjunto_datos=pca.transform(dataframe) #partimos del dataframe df_std from sklearn.model_selection train_test_split from sklearn.discriminant_analysis LinearDiscriminantAnalysis as LDA from sklearn.SVM y=df["CLASS"] X_ent, X_pru, y_ent,y_pru train_test_split(df_std,y,test_size=0.2, random_state=43) lda=LDA(n_components=6) ldaX_ent=lda.fit_transform(X_ent,y_ent) ldaX_pru=lda.transform(X_pru) import import = Ejemplo de analisis discriminante lineal con Scikit-learn. Crea dos conjuntos de datos con dimensionalidad reducida para clasificación. 73 donde dataframe es el conjunto de datos original preferiblemente estandarizado- Existen otras muchas técnicas de reducción dimensionalidad entre la que podemos destacar de la Análisis discriminante lineal (ADL): es un método de extracción de características que corresponde a las técnicas de aprendizaje supervisado dado que requiere que los datos estén etiquetados, y que consta de los siguientes pasos: o Se calculan los vectores medios de dimensión d para las clases que conforman los datos o Se calculan las matrices de dispersión para cada clase y entre ellas Aplicación de técnicas de aprendizaje automático no supervisado o Se calculan los vectores y valores propios para cada matriz de dispersión o Se ordenan los vectores propios de forma análoga a como se ha hecho en PCA o A continuación se crea la matriz de proyección a partir de los vectores propios como se ha hecho en PCA o Por último, la matriz de proyección se emplea para transformar el conjunto de datos en otro con menos dimensiones Incrustación Lineal Local (LLE): es una técnica de aprendizaje de variedades en la que se comprueba cual es la distancia entre cada registro del conjunto de datos con sus vecinos más próximos, esto es, que cada registro xi se pueda representar como una función lineal de los vecinos xj con pesos wi,j, y que la distancia cuadrática entre xi y esa función lineal sea mínima, obteniendo una matriz de pesos W como se expresa a continuación 𝒎 #partimos del dataframe df_std from sklearn.manifold import LocallyLinearEmbedding incrustacion_lineal_local=LocallyLinearEmbedding(n_com ponents=6,n_neighbors=5) datos_lle=incrustacion_lineal_local.fit_transform(df_std) print('datos originales:{}'.format(str(df_std.shape))) print('datos reducidos:{}'.format(str(datos_lle.shape))) df_lle=pd.DataFrame(data=datos_lle, 'CP2', 'CP3','CP4', 'CP5','CP6']) print(df_lle) columns=['CP1', Ejemplo de uso de LLE con Scikit-Learn 𝟐 𝒎 ̂ = 𝒂𝒓𝒈𝒎𝒊𝒏 𝑾 ∑ (𝒙(𝒊) − ∑ 𝒘𝒊,𝒋 ∙ 𝒙(𝒋) ) ⏟ 𝑾 𝒊=𝟏 𝒋=𝟏 donde la suma de los pesos wi,j es 1 para cada registro. Después busca la representación del conjunto de datos con menos dimensiones que preserve mejor estas distancias, generando una matriz Z de la forma 𝒎 𝒎 𝟐 ̂ = 𝒂𝒓𝒈𝒎𝒊𝒏 𝒁 ∑ (𝒛(𝒊) − ∑ 𝒘𝒊,𝒋 ∙ 𝒛(𝒋) ) ⏟ 𝒁 𝒊=𝟏 𝒋=𝟏 Proyecciones aleatorias: reduce la dimensionalidad del conjunto de datos en base a proyecciones aleatorias lineales, que se ha demostrado que conserva bien las distancias -Johnson, Lindenstrauss-. Escalado multidimensional: reduce la dimensionalidad manteniendo las distancias 74 Aplicación de técnicas de aprendizaje automático no supervisado Ejemplo de K-Means resuelto a mano Partimos de los datos estándarizados obtenidos en ejemplos anteriores El siguiente paso es emplear K-means nítido para obtener las dos categorías de valores. Empezaremos escogiendo los registros 1 y 2 como centroides de las categorías 1 y 0. Aplicaremos la distancia euclídea para determinar la distancia de cada registro a los centroides, con lo que obtenemos la siguiente tabla. Los cálculos se aproximan la tercer decimal y usamos el punto decimal para separar la parte entera de la parte fraccionaria. donde D1 y D2 son las distancias de cada registro al centroide 1 y 0 respectivamente. La matriz de pertenencia a cada categoría es la siguiente Incrustación de vecinos estocástica: reduce la dimensionalidad manteniendo las distancias similares próximas entre sí y las no-similares alejadas entre sí. El agrupamiento o clustering es un procedimiento de aprendizaje no supervisado por el cual se agrupan las muestras o registros del conjunto de datos no etiquetados en función de sus similitudes, que conforman patrones o modelos. El agrupamiento es útil en campos como el marketing, segmentando grupos de clientes caracterizados por el tipo de compras que hacen, y les sugieran contenidos adaptados a su perfil de compras. También es útil para detectar aquellos registros del conjunto de datos que no corresponden a algún grupo, valores anómalos, que permiten detectar comportamientos erróneos en los sistemas. Asimismo se puede emplear para segmentar imágenes reduciendo el número de píxeles iguales entre sí, para facilitar las tareas de seguimiento de objetos. Otros usos son la detección de tipos de usuarios en las redes sociales, o motores de búsqueda que buscan elementos similares al que se trata de localizar. Las técnicas para agrupar registros se estudiante en los siguientes apartados. Ahora volvemos a calcular la pertenencia a la categoría empleando nuevos centroides, uno será la media de los registros 2, 3, 4 y 10, y el otro la media de los seis registros restantes. Con ellos las nuevas distancias son Con lo que las nuevas categorías son Existen distintos tipos de técnicas de agrupamiento, de entre las que destacaremos: El K-Means: está basado en centroides, que son los puntos centrales de los diferentes grupos. Cada registro se asocia a un grupo en función de la distancia a cada centroide. Dicha asociación se refina en sucesivas iteraciones hasta que permanece constante tras dos iteraciones seguidas. Agrupamiento jerárquico: basado en la acumulación o aglomeración de registros. Los estudiaremos en los siguientes apartados. 75 Aplicación de técnicas de aprendizaje automático no supervisado K-Means -propuesto por Stuart Lloyd en 1957- es un algoritmo que permite asignar los registros del conjunto de datos a diferentes grupos identificados por centroides. El parámetro K indica el número de centroides con el que vamos a trabajar, es menor que el número de registros y permite por tanto la reducción de dimensionalidad. Se han modificado las categorías, con lo que volvemos a calcular los centroides, esta vez uno será la media de los registros 2,3,4, 9, y 10 y el otro será la media de 1,5, 6, 7 y 8.. Los valores resultantes de los nuevos centroides son Las etapas de un algoritmo K-Means son: Indicar la cantidad k de clusters en la que se van a agrupar los registros Elegir los centroides. Puede ser de manera aleatoria o a través de un procedimiento de pre-agrupamiento Se agrupan los registros del conjunto de datos en función de la cercanía a los diferentes centroides, la cual se calcula mediante la distancia euclidiana Con ellos las nuevas distancias son Con lo que las nuevas categorías son Ya no se modifican las categorías, por lo que los dos conjuntos quedan como se muestra en la tabla anterior. Se calculan nuevos centroides a partir de la media de los registros agrupados en cada cluster La precisión es de 10/10, o sea del 100 por ciento. Se repite el proceso de agrupamiento con los nuevos centroides, y así hasta que no haya cambios en la asignación de los registros del conjunto de datos a cada cluster. Ejemplo de resolución del modelo Kmeans del ejercicio anterior empleando Scikit-learn En los cuadros laterales de la página anterior y la página actual se pueden ver ejemplos de K-Means resueltos a mano y con Scikit-Learn. En Scikit-Learn el método empleado para obtener K-Means se muestra a continuación KMeans(n_clusters=, init=, n_init= donde n_clusters es el número k de centroides, init es el tipo de inicio -aleatorio u otros- y n_init es el número de ejecuciones del algoritmo El tipo de inicio tiene diferentes valores, que pueden ser: #partimos del dataframe estandarizado from sklearn.cluster import KMeans from sklearn.metrics import confusion_matrix categoria=df['CLASS'] # aplicamos KMeans con criterio ‘random’ kmeans = KMeans (n_clusters=2,init='random').fit(df_std) centroids=kmeans.cluster_centers_ #mostramos los centroides print (centroids) #mostramos las etiquetas print(kmeans.labels_ #mostramos la matriz de confusion matriz=confusion_matrix(categoria,kmeans.labels_) print(matriz) #claculamos KMeans con criterio k-means++ kmeans = KMeans (n_clusters=2,init='kmeans++').fit(df_std) #obtenemos los centroides centroids=kmeans.cluster_centers_ print (centroids) #obtenemos las etiquetas print(kmeans.labels_) #calculamos la matriz de confusion matriz=confusion_matrix(categoria,kmeans.labels_) print(matriz) random: centroides elegidos aleatoriamente 76 Aplicación de técnicas de aprendizaje automático no supervisado Ejemplo de determinación de los valores de K con Elbow #partimos del dataframe estandarizado from sklearn.cluster import KMeans from sklearn.metrics import confusion_matrix import matplotlib.pyplot as plt matriz_inercia=[] for i in range(1,10): kmeans = KMeans (n_clusters=i,init='kmeans++').fit(df_std) matriz_inercia.append(kmeans.inertia_) k-means++: centroides alejados entre sí. Este último valor reduce el número de iteraciones para obtener los centroides definitivos. Los centroides iniciales condicionan sobremanera el algoritmo de agrupamiento. Para comprobar cuanto afecta esto, el método KMeans tiene el parámetro inertia_, que mide la suma de los cuadrados de las normas de las distancias entre cada punto del cluster a su centroide, cuyo valor ha de ser cuanto más bajo mejor. plt.plot(range(1,10),matriz_inercia) plt.show() 𝒏 𝒊𝒏𝒆𝒓𝒄𝒊𝒂 = ∑ ‖𝒙𝒊 − 𝝁𝒊 ‖𝟐 𝒊=𝟏 Asimismo, determinar cuál es el valor de K más apropiado es esencial para conseguir los agrupamientos óptimos. Para resolverlo podemos emplear dos métodos: Se puede ver el cambio de pendiente en en k=2 El método de Elbow: consiste en representar la inercia frente al número de centroides K. El punto donde la pendiente de la curva disminuye corresponde al valor de k óptimo. El coeficiente de silueta: permite comprobar si los clústeres están suficientemente separados entre sí para lo cual se calcula la siguiente expresión Ejemplo de determinación de los valores de K con coeficiente de silueta #partimos del dataframe estandarizado from sklearn.cluster import KMeans from sklearn.metrics import confusion_matrix from sklearn import metrics import matplotlib.pyplot as plt coeficientes_silueta=[] for k in range(2,10): kmeans = KMeans (n_clusters=i,init='kmeans++').fit(df_std) silueta=metrics.silhouette_score(df_std, kmeans.labels_) print("coeficiente de silueta para k=", k, "es:{:.2f}".format(silueta)) coeficientes_silueta.append(silueta) k= coeficientes_silueta.index(max(coeficientes_ silueta))+ 2 print(k) El resultado es que k optimo es 3, porque tiene el valor de coeficiente de silueta más próximo a 1 𝑺= 𝒃−𝒂 𝒎𝒂𝒙(𝒃, 𝒂) En Scikit-learn el método silhouette_score() del módulo metrics permite calcular el valor de S, que tomará valores entre -1 – registro asignado al cluster equivocado – y 1 registro asignado correctamente a cluster y lejos de los otros clústeres- donde 0 indica que el registro está cerca del límite entre dos clústeres. K-Means tiene limitaciones relacionadas con la dificultad para agrupar en torno a centroides en conjuntos no esféricos o con densidades diferentes, o los valores atípicos que pueden alterar los centroides, lo que obliga a emplear otros métodos como los de mezcla gaussiana o k-medioids. K-Means tiene múltiples aplicaciones en segmentación de imágenes, aprendizaje semisupervisado, marketing orientado al cliente o identificación de categorías de objetos. 77 Aplicación de técnicas de aprendizaje automático no supervisado La técnica de agrupamiento de datos jerárquico permite agrupar los diferentes registros del conjunto de datos en clusters formando una estructura de tipo dendograma – un árbol -. El agrupamiento puede empleando técnicas partitivas o de arriba abajo -esto es, se parte de un único grupo y se va dividendo en grupos más pequeños hasta que se consigue la división óptima- o de abajo a arriba – en donde se considera cada registro una categoría o cluster, y se van agrupando con otros clústeres hasta llegar a un único grupo o cluster-. Este último procedimiento es el llamado aglomerativo y es el que vamos a estudiar aquí. Ejemplo de agrupamiento jerárquico mediante cálculo manual Partimos de los registros estandarizados de apartados anteriores, y tomamos como criterio el vínculo simple. La matriz de distancias inicial es: En el método aglomerativo cobra especial relevancia el modo de calcular la diferencia o semejanza entre las categorías o clústeres, el criterio de agregación y el criterio para volver a calcular la diferencia o semejanza entre la nueva categoría resultante de la agregación y el resto de categorías o clústeres. Una vez calculada la matriz D buscamos la distancia mínima que es la del elemento D67 , de valor 1.611. Las nuevas distancias a los nodos restantes desde el cluster (67) son: La semejanza o diferencia se calcula a partir de la distancia euclidea entre las categorías/clusteres, mientras que el criterio de agregación suele ser la distancia mínima entre las categorías /clústeres, y el de nuevo cálculo de las semejanzas puede ser de tres tipos: D4= min(d46, d47)= 4.419 D5= min(d56, d57)= 2.387 D8 =min(d86, d87)= 1.778 Vinculo simple: se toma la mínima distancia -maxima semejanza- entre cada categoría y la que resulta de las que hemos agregado. Vinculo completo: se toma la máxima distancia d-minima semejanza- entre cada categoría y la que resulta de las que hemos agregado Media: se toma la media entre la máxima y la mínima semejanza entre cada categoría y la que resultad de la agregación Centroide: minimiza la varianza entre los clusters o categorías que se mezclan. D1= min(d16, d17)= 1.726 D2= min(d26, d27)= 4.406 D3= min(d36, d37)= 4.448 D9= min(d96, d97)= D10=min(d106,d107)=3.414 3.518 Generamos la nueva matriz Y volvemos a buscar la distancia minima , que es D(167) -1.726-, y calculamos de nuevo nuevo las distancias generando una nueva matriz El algoritmo para resolver el agrupamiento jerárquico aglomerativo consta de los siguientes pasos: 78 Aplicación de técnicas de aprendizaje automático no supervisado Seguimos seleccionando el cluster de menor distancia y volvemos a calcular la semejanza entre este cluster y el resto obteniendo matrices hasta llegar a Creamos la matriz de distancias euclidianas entre los registros del conjunto de datos. Es una matriz diagonal. Buscamos el elemento mínimo de esa matriz. Calculamos, empleando el cálculo de semejanzas escogido, las nuevas distancias entre clústers o categorías, con las que creamos una nueva matriz El elemento mínimo es D167859210, 3.095- y las nuevas distancias son C34=min(d34,210, d34,167859)= 3.119 Los dos conjuntos son 1256789(10) y 34. La distancia mínima no suele funcionar bien cuando las distancias entre elementos son pequeñas. El dendrograma es el siguiente Volvemos a buscar el elemento mínimo de la matriz, y reiniciamos el bucle. El resultado final de este algoritmo es la agrupación de los registros del conjunto de datos en varios clústeres o categorías que conforman el agrupamiento buscado. En Scikit-learn para realizar este procedimiento se emplea AgglomerativeClustering, dentro del paquete cluster para obtener el dendograma, con la siguiente sintaxis cluster_agl=AgglomerativeClustering(n_clusters=, linkage= Obtención del modelo agrupamiento jerarquico del ejemplo anterior empleando Scikit-learn y vinculo completo #partimos de la matriz de registros estandarizados from sklearn.metrics import confusion_matrix from sklearn import metrics import matplotlib.pyplot as plt from scipy.spatial import distance_matrix from scipy.cluster import hierarchy from sklearn.cluster import AgglomerativeClustering metodo_aglomerativo=AgglomerativeClustering(n_clusters=2, affinity='euclidean', linkage='complete') resultado=metodo_aglomerativo.fit(df_std) print(metodo_aglomerativo.labels_) matriz_distancias=distance_matrix(df_std, df_std) auxiliar=hierarchy.linkage(matriz_distancias,'complete') dendro=hierarchy.dendrogram(auxiliar) plt.title("Dendograma") plt.show() donde n_clusters es el número de clusters y linkage el tipo de vinculo -complete, single, average o Ward-. En los cuadros laterales de las páginas anterior y actual podemos ver ejemplos de agrupamiento jerárquico aglomerativo. Es una técnica de agrupamiento que permite identificar regiones de alta densidad de registros del conjunto de datos e identifica aquellos elementos atípicos que no corresponden al comportamiento estándar de los registros. Diferencia los registros entre centrales o principales - si el número de puntos -minPuntos- en su vecindad -de radio epssupera un valor determinado o mínimo de registros -, fronterizo -si están a una distancia no mayor del radio eps de un punto central o principal -y ruido o anomalía -si no pertenece a ninguna de las categorías anteriores-. De lo anterior se deduce que los registros centrales se encuentran situados en regiones densas. 79 Aplicación de técnicas de aprendizaje automático no supervisado Una secuencia de registros centrales y sus vecinos -los puntos que están en su vecindad- forman parte del mismo grupo. Un parámetro a tener en cuenta aquí es la densidad de un determinado registro X, que es el número de registros a una distancia menor que eps. El algoritmo DBSCAN funciona de la siguiente manera. Visita cada registro y comprueba si es principal, ruidoso o fronterizo. SI es principal le asigna un grupo. Asigna a todos los puntos de la vecindad -distancia eps pasan a ser considerados ruido si están lejos de cualquier grupo y fronterizos si están a distancias semejantes a eps del registro central de uno o más grupos. DBSCAN no se emplea para predecir comportamientos o clasificar nuevos registros, sino que emplea algoritmos de clasificación ya existentes, como KMeans o KNN. En el cuadro lateral se puede ver un ejemplo del uso de DBSCAN. Ejemplo del uso de DBSCAN para clasificar conjuntos de círculos entrelazados from sklearn.cluster import DBSCAN from sklearn.neighbors import KNeighborsClassifier #make_moons genera circulos entrelazados from sklearn.datasets import make_moons #generamos los círculos y la clase a que pertenecen X,y=make_moons(n_samples=5000, noise=0.05) #generamos el modelo dbscan=DBSCAN(eps=0.005,min_samples=5) #lo entrenamos para generar las clases asociadas dbscan.fit(X) #mostramos las clusters obtenidas print(dbscan.labels_) #mostramos los nucleos de los clusers print(dbscan.components_) #indice de los nucleos y numero de ellos print(len(dbscan.core_sample_indices_)) print(dbscan.core_sample_indices_) knn=KNeighborsClassifier(n_neighbors=10) knn.fit(dbscan.components_,dbscan.labels_ [dbscan.core_sample_indices_]) Cálculo de la distancia de Mahanalobis Supuesto un conjunto de datos, con la forma 𝑋𝑖1 𝑋𝑖2 𝑋1 = … … [𝑋𝑖𝑁 ] la media se calcula como 𝜇 = Existen otros algoritmos de agrupamiento, pero todos ellos se basan en encontrar instancias similares o próximas a una en concreto y a partir de ahí generar grupos con ellas. Entre esos algoritmos podemos destacar BIRCH, Mean Shift o Propagación de Afinidad. 1 𝑀 ∑𝑀 𝑗=1 𝑋𝑗 y la matriz de covarianza se obtiene como se muestra en la siguiente expresión 𝐶= 𝑀 1 ∑ ሾ𝑋𝑖 − 𝜇ሿ ∙ ሾ𝑋𝑖 − 𝜇ሿ𝑇 𝑀 𝑖=1 La distancia de Mahanalobis se obtiene a partir de la siguiente ecuación 𝐷(𝑋, 𝑌) = ሾ(𝑋 − 𝑌)𝑇 ∙ 𝐶 −1 ∙ (𝑋 − 𝑌)ሿ1/2 Se entiende anomalía como todo aquel elemento que se sale del patrón estándar. Las anomalías pueden ser valores atípicos en una gráfica de puntos, o comportamientos anómalos en un patrón climático, o bien en el comportamiento de una persona a la hora de realizar tareas rutinarias. El estudio de las anomalías es esencial para identificar fallos en el funcionamiento de una fábrica, intentos de ataque en un sistema informático, para localizar productos defectuosos o eliminar usuarios para un estudio que no corresponden con los valores estándar, o de actividad fraudulenta en términos generales. import numpy as np import matplotlib import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.covariance import EllipticEnvelope from sklearn.neighbors import LocalOutlierFactor n=200 f_out=0.15 n_out=int(f_out*n) n_normales=n-n_out np.random.seed(111) X,y=make_blobs(n_samples=n_normales,centers=[[2,2],[-2,2]]) Ejemplo de uso del método de la distancia de Mahanalobis 80 Aplicación de técnicas de aprendizaje automático no supervisado rng=np.random.RandomState(111) X=np.concatenate([X,rng.uniform(low=5,high=5,size=(n_out,2))],axis=0) modelo_DB=EllipticEnvelope(contamination=f_out) estima=modelo_DB.fit(X) y_pred=estima.predict(X) plt.scatter(X[y_pred==1,0],X[y_pred==1,1],s=30,marker="o") plt.scatter(X[y_pred==-1,0],X[y_pred==-1,1],s=30, marker="*") plt.title("Aplicacion de Mahanalobis") plt.show Ejemplo de uso del metodo de la distancia de Mahanalobis Densidad de probabilidad: es una probabilidad, pero en vez de estar definida entre 0 y 1, lo está entre 0 e infinito. Representa lo probable que es que un registro este en una distribucion. Grafica con el número de componentes óptimo -el codo de las curvasEjemplo del uso de mezcla gaussiana from sklearn.metrics import confusion_matrix from sklearn import metrics import matplotlib.pyplot as plt from sklearn import mixture import seaborn as sns mezcla_gaussiana= mixture.GaussianMixture(n_components=2, covariance_type='full',random_state=123) mezcla_gaussiana.fit(df_std) conjuntos = mezcla_gaussiana.predict(df_std) fig, ax = plt.subplots(figsize=(6, 3.84)) #determinamos el número óptimo de componentes n_components = range(1, 40) covariance_types = ['spherical', 'tied', 'diag', 'full'] for covariance_type in covariance_types: valores_bic = [] for i in n_components: mezcla_gaussiana = mixture.GaussianMixture (n_components=i, covariance_type= covariance_type) mezcla_gaussiana = mezcla_gaussiana.fit (df_std) valores_bic.append(mezcla_gaussiana.bic (df_std)) ax.plot(n_components, valores_bic, label= covariance_type)ax.set_title("Valores BIC") ax.set_xlabel("Número componentes") ax.legend(); 81 Para identificarlas se usan diferentes métodos entre los cuales podemos identificar los siguientes. La distancia de Mahanalobis es una forma de determinar la existencia de patrones atípicos que tiene en cuenta la distribución de los datos. Para determinarla tenemos que determinar la media y la matriz de covarianzas del conjunto de registros de datos. En el cuadro de la derecha podemos ver el procedimiento de obtención de la distancia de Mahanalobis. Una vez calculadas todas las distancias se estima un punto de corte -una distancia máxima a partir de la cual podemos hablar de anomalía-. El principal problema de este método es el cálculo de la matriz inversa de covarianza, el cual da valores muy próximos a infinito, Los métodos generadores permiten modelar distribuciones paramétricas que generen los registros del conjunto de datos. Una vez creados los parámetros que minimicen la distancia entre la distribución candidata y el generador de datos se puede determinar la probabilidad de que registro haya sido generado por una distribución determinada y pertenezca a un determinado cluster. La mezcla gaussiana es una técnica de aprendizaje no supervisado que se basa en el concepto de que cada registro del conjunto de datos tiene una cierta probabilidad, llamada densidad de probabilidad, de pertenecer a una u otra distribución gaussiana que engloban el total de los datos. Cada distribución está definida por parámetros -la media y la varianza, y con ellas se calcula la matriz de covarianza. Las matrices de covarianza de una mezcla gaussiana determinan la forma de los componentes principales -las hemos calculado en el método PCA-. En función de eso las componentes pueden tener la misma matriz de covarianza tied- las dimensiones de las componentes pueden ser distintas pero alineadas con los ejes -diagonal -, pueden ser todas iguales -esferical- y pueden tener cada componente Aplicación de técnicas de aprendizaje automático no supervisado distinta matriz de covarianza -full- distinta matriz de covarianza pero alineadas con los ejes -diagonal -. Como hemos comentado lass anomalías o valores atípicos son registros que se desvían de la normalidad. En un modelo de mezcla gaussiana la detección de anomalías implica detectar registros situados en una zona de baja densidad. En los cuadros laterales de esta página y la anterior se puede ver un ejemplo de mezcla gaussiana para la detección de anomalías empleando Scikit-learn, que dispone de la biblioteca mixture, y dentro de ella de la función GaussianMixture, que tiene la siguiente sintaxis mezcla_gaussiana=mixture.GaussianMixture(n_co mponente, covariance_type, random_state) Donde n_components permite visualizar el número de componentes, covariance_type corresponde al tipo de covarianza que genera distribuciones esféricas, diagonales, etc.., y random_state permite inicializar de manera aleatoria el método con diferentes registros. Ejemplo del uso de mezcla gaussiana contmezcla_gaussiana = mixture.GaussianMixture( n_components = 6, covariance_type = 'full', random_state = 123, ) #ejecutamos el modelo con 6 componentes mezcla_gaussiana.fit(df_std) #graficamos los clusters predichos log_probabilidad_predicha = mezcla_gaussiana. score_samples(df_std) print(log_probabilidad_predicha) fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(7, 3.5)) sns.distplot( log_probabilidad_predicha, hist = False, rug = True, color = 'blue', kde_kws = {'shade': True, 'linewidth': 1}, ax = ax ) ax.set_title('Distribución predicciones') ax.set_xlabel('Logaritmo densidad de probabilidad'); #buscamos las anomalias datos_y=df["CLASS"] df_resultados = pd.DataFrame({ 'log_probabilidad' : log_probabilidad_ predicha, 'anomalia' : datos_y }) fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(5.5, 3.5)) sns.boxplot( x = 'anomalia', y = 'log_probabilidad', data = df_resultados, #color = "white", palette = 'tab10', ax = ax ) ax.set_title('Distribución predicciones GMM') ax.set_ylabel('Logaritmo densidad de probabilidad') ax.set_xlabel('clasificación (0 = normal, 1 = anomalía)'); df_resultados = df_resultados \.sort_values('log_probabilidad', ascending=True) \.reset_index(drop=True) df_resultados['clasificacion'] = np.where (df_resultados.index