Introducción
En el
anterior artículo ofrecimos una primera aproximación de cómo son aplicadas las técnicas de machine learning al campo de la seguridad informática y buscamos familiarizar de manera amigable al lector con los conceptos fundamentales.
El artículo que nos ocupa en esta ocasión pretende mostrar de manera igualmente amigable como aplicar la práctica de lo expuesto en el artículo anterior. Para ello vamos a abordar la definición, entrenamiento y consulta a un modelo inteligente, de manera que se exija al lector el mínimo esfuerzo y conocimientos técnicos previos.
Experimento
En este artículo vamos a construir y evaluar nuestro primer modelo, el cual será el núcleo en un sistema de Ciberinteligencia. Dicho sistema estaría dando soporte a nuestra pequeña agencia de inteligencia, clasificando a usuarios de Twitter por su afinidad política, para el posterior registro y procesamiento de sus perfiles.
Material de trabajo
- Weka[1]: Es un conjunto de librerías escritas en JAVA para el desarrollo de aprendizaje automático y minería de datos. Además incorpora una interface gráfica (Weka Explorer), que permite trabajar con las librerías de manera muy sencilla.
- Tinfoleak[2]: Es una herramienta de extracción y análisis de información relevante en Twitter mediante técnicas OSINT (Open-Source Intelligence), desarrollada y mantenida por Vicente Aguilera Díaz[3].
- Conjuntos de datos: Vamos a utilizar dos conjuntos, uno para entrenamiento y otro de evaluación del modelo.
NOTA: Es intencionada la elección de Weka, pues el nivel de sencillez con que pretendemos abordar el tema es tal, que vamos definir, entrenar y trabajar con modelos inteligentes “a golpe de clic”. Esto es posible gracias a la interface gráfica que incorpora Weka.
Recolección de la información
El primer paso será obtener la información para el entrenamiento de nuestro modelo. Para ello vamos a apoyarnos en la herramienta
Tinfoleak y nuestro objetivo será extraer los hashtags que compondrán el conjunto de entrenamiento.
Para nuestro experimento se han recopilado los hashtags publicados por cada una de las 4 principales, en número de votos, fuerzas políticas: PP, PSOE, Podemos y Ciudadanos. Esta información la convertiremos al formato nativo de Weka .arff, aunque admite otros formatos como .cvs o .data.
Podemos observar como hay dos partes diferenciadas: primero las declaraciones que definen el nombre de la relación/conjunto de datos a clasificar (@relation) y el formato (@attribute) de cada una de las dimensiones/campos del vector de entrada (metadatos), y por último los datos propiamente dichos a partir de @data.
%comentario - Conjunto de datos en formato nativo Weka @relation hashtags @attribute hashtag string %comentario - PP = 1,PSOE = 2, Podemos = 3, Ciudadanos=4 @attribute partido {1,2,3,4} @data 'entrevista Afavor aFavor España AFavor Afavor España …’, 1 'Hashtags 26J Periscope L6elecciones L6elecciones ElDíaDelSí …’,2 ‘eleccionesA3 L6elecciones L6elecciones UnidosPodemos26J RdPGarzón …,3 ‘26JOndaCero CambioaMejor Ciudadanos CambioaMejor CambioaMejor L6elecciones’…,4 |
Carga del conjunto de entrenamiento
Comenzamos iniciando el entorno de trabajo y cargando el conjunto de datos del entrenamiento.
- Llamamos a la interface gráfica de Weka pinchando el archivo RunWeka.bat en la carpeta donde instalamos Weka.
- En la ventana “Weka GUI Chooser”, pulsamos el botón Explorer. Explorer es la única herramienta que vamos a necesitar a lo largo de todo ejemplo.
- En Weka Explorer, pestaña Preprocess, pulsamos “Open file”, navegamos hasta donde tengamos nuestro archivo .arff y lo abrimos.
- Si no hay errores de formato se cargará y veremos la información cuantitativa y cualitativa de las instancias (cada uno de los registros cargados del .arff) y sus atributos.
|
Pre-procesado de los datos
Antes de entrenar nuestro modelo tenemos que resolver algunas restricciones. No todos los modelos admiten todos los tipos de valores de entrada, ni clasifican etiquetando en todos los tipos datos de salida, pero sí es posible aplicar filtros para hacer conversiones entre tipos. Weka contempla dos maneras de aplicarlos:
- De manera explícita, aplicando los filtros disponibles en la pestaña de preprocesado
- De manera implícita a través del clasificador
FilteredClassifier, que no es más que un contenedor que vincula un modelo clasificador con uno varios filtros. Al entrenar el modelo primero se “dispararán” los filtros y, a continuación, se procederá con el entrenamiento.
Nosotros utilizaremos el segundo método, ya que nos será más cómodo de aplicar cuando en un futuro artículo abordemos este tema desde un enfoque más avanzado y centrado en desarrollo.
Definición del modelo
El siguiente paso será definir nuestro modelo, para ello nos vamos a:
- En la pestaña Classify, menu Classifier, pulsamos el botón Choose y se nos desplegará la lista de clasificadores que incorpora Weka.
- Seleccionamos weka->classifiers->meta->FilteredClassifiers
|
Aunque hasta ahora la herramienta parezca de “juguete”, se empieza a evidenciar la potencia de esta al ver la cantidad de tipos y versiones de clasificadores que implementa.
- En la pestaña Classify, menu Classifier, pulsamos el botón Choose y se nos desplegará la lista de clasificadores que incorpora Weka.
- Seleccionamos weka->classifiers->meta->FilteredClassifiers
|
Para este experimento vamos a probar un meta-clasificador, el modelo será uno con base probabilística, el NaiveBayesMultinomial.
Además el modelo NaiveBayesMultinomial es compatible con atributos de entrada numéricos y los hashtag son palabras. Más concretamente nuestro conjunto de datos está formado por 4 cadenas de hashtags (una por partido), por lo que debemos convertir las cadenas de caracteres a vectores “de palabras”.
'entrevista Afavor aFavor España AFavor Afavor España …’ 'Hashtags 26J Periscope L6elecciones L6elecciones ElDíaDelSí …’ ‘eleccionesA3 L6elecciones L6elecciones UnidosPodemos26J RdPGarzón …’ ‘26JOndaCero CambioaMejor Ciudadanos CambioaMejor CambioaMejor L6elecciones’…,’ |
Para ello:
- En la pestaña Classify, menu Classifier, pulsamos sobre la cadena “weka.classifiers.meta.FilteredClassifier -F
"weka.filters.supervised.attribute.Discretize -R first-last" -W weka.classifiers.trees.J48 -- -C 0.25 -M 2”.
¡OJO!, no sobre el botón Choose, EXACTAMENTE SOBRE LA CADENA.
- Nos aparecerá ahora la ventana “weka.gui.GenericObjectEditor” y tres opciones seleccionables, nos interesan: classifier y filter.
- Pulsamos el botón Open de classifier y seleccionamos en la lista weka->classifiers->bayes->NaiveBayesMultinomial.
- Pulsamos el botón Open de filter y seleccionamos en la lista filter->unsupervised->attribute->StringToWordVector
- Finalmente, dejamos el resto de opciones del menu Test options igual, y pulsamos Start.
|
NOTA: Tanto el clasificador, como el filtro, como las opciones de test, las hemos dejarlo con los valores por defecto. El filtro por defecto se pasará por todas las dimensiones (first-last en “attributeIndice” para las opciones del filtro), en nuestro ejemplo procesará la primera entrada de hashtags e ignorará la clase nominal “partido”. En cuanto a los test, dejaremos que pruebe que tal clasifica respecto al mismo conjunto con el que fue entrenado por ahora.
El resultado muestra:
- La lista de los nuevos atributos “tokens” que se extrajeron de las cadenas de palabras. Ahora son de tipo numeric, como requiere nuestro modelo.
- La probabilidad independiente de cada clase.
- Las probabilidades de que aparezca cada token en cada una de las clases. La base de nuestro modelo.
- Datos estadísticos que evalúan la calidad del modelo.
La información que más nos interesa, está justo al final, es la matriz de confusión.
Interpretarla es muy simple. La celda (1,1), marcada con 1, significa que el test clasificó como clase 1 (Partido Popular), la cadena de hashtags perteneciente a dicha clase. Por lo que el tener todos los valores concentrados en la diagonal se interpreta como que cada elemento clasificado como X por el modelo pertenece a la clase Y, siendo X=Y, dicho de otra manera, que clasificó correctamente todas las entradas.
Tampoco tiene mucho mérito, le hemos puesto las cosas fáciles al hacer el test con exactamente el conjunto de datos con el que fue entrenado. Cuando los conjunto son realmente grandes y contiene información ambigua y repetida, no será tan trivial que acierte incluso haciendo los test consigo mismo.
Consultando nuestro modelo entrenado
Ahora vamos a la parte realmente interesante, hemos extraído los hashtags de las siguientes cuentas de usuario de Twitter, ayudándonos nuevamente con Tinfoleak, y estos son los distintos conjuntos que forman:
NOTA: Solo se están mostrando en la tabla los primeros hashtags. Nótese los puntos suspensivos (…) al final del mismo.
%Comentario @marianorajoy @relation hashtags @attribute hashtag string @attribute partido {1,2,3,4} @data 'Afavor RajoyenCOPE RajoyenCOPE España 26J RajoyenCOPE RajoyEnCOPE Afavor España…' |
%Comentario @sanchezcastejon @relation hashtags @attribute hashtag string @attribute partido {1,2,3,4} @data 'Periscope ElDíaDelSí JornadaDeReflexión CaravanaPSOE VotaSíVotaPSOE VotaSíVotaPSOE…' |
%Comentario @Pablo_Iglesias_ @relation hashtags @attribute hashtag string |
%Comentario @Pablo_Iglesias_ @relation hashtags @attribute hashtag string @attribute partido {1,2,3,4} @data 'UnidosPodemos26J UnidosPodemos26J UnidosPodemos VotaUnidosPodemos26J …' |
%Comentario @agarzon @relation hashtags @attribute hashtag string @attribute partido {1,2,3,4} @data '26J AVotar UnidosPodemos26J UnidosPodemos26J UnidosPodemos26J …' |
%Comentario @InesArrimadas @relation hashtags @attribute hashtag string @attribute partido {1,2,3,4} @data 'CambioaMejor 26J L6elecciones L6elecciones CambioaMejor OrgulloNaranja …' |
Bien, pues llegó la hora de la verdad. Vamos a hacer lo siguiente:
- En el menu Test options, seleccionamos Supplied test set
- Pulsamos el botón “Set…”, justo al lado.
- Nos aparecerá la ventana Test Instances, en ella pulsamos el botón Open File
- Seleccionamos el conjunto de datos que queramos clasificar.
- Ahora, nos vamos a Result list (right-click options) y haciendo clic con el botón derecho del ratón sobre nuestro modelo “meta.FilteredClassifier”.
- Seleccionamos, “Re-evaluate model on current test set”
|
Y este es el resultado para cada una de las cuentas evaluadas.
Asoció cada conjunto de hashtags con el partido correcto, a excepción de los publicados por @sanchezcastejon. Interpretamos el valor en la celda (2,1) como que se clasifico como 1 = Partido Popular, pero el valor correcto es 2 = PSOE. Aunque bueno, según qué analista político igual podría ser un error revelador… o no. ¿Desvelará nuestro subconsciente información cuando decidimos que hashtags utilizar?, quien sabe.
Lo bueno de trabajar con la interface gráfica de Weka (Weka Explorer), es que a partir de este punto, haciendo clic, podemos probar otros tipos de modelos, o cambiar el algoritmo de “tokenización” o modificar la configuración del entrenamiento. Las opciones son numerosas y dan mucho juego. El cambio de modelo, en este punto, es algo al alcance de pocos clics y podría resultar divertido para el lector ver hacia donde oscila/falla la clasificación de la cuenta de Twitter @sanchezcastejon, o si hay otra cuenta que nos pueda sorprender.
Todo parecido con la realidad… y algunas opiniones personales del autor
Bien, lo primero que tenemos que resaltar es que debemos ser responsables con lo que aquí mostramos. El ejemplo funciona muy bien y es simple, pero esto es así porque detrás hay un trasfondo de experiencia en la aplicación de técnicas de aprendizaje automático a conjuntos de datos. Dicho de otra manera, desde antes del primer clic sabíamos que para ese tipo y volumen de datos, con lo representativos que son los datos de entrenamiento, la asociación tan fuerte entre estos y los de los test, el filtrado utilizado y eligiendo un modelo probabilístico bayesiano, iba a funcionar sin problema alguno hasta con los valores por defecto de la configuración.
En la práctica, cuando trabajamos con conjuntos de información, la experiencia pasada nos ofrece cierta intuición de qué filtrado, modelo y configuración del entrenamiento es la más indicada.
El preprocesado es una etapa fundamental cuando trabajamos con text
minning y puede complicarse. A veces el texto puede ser el perteneciente a un protocolo de red basado en texto: cambiarán los separadores y las
stopswords empleadas, la entropía, la tasa de ruido introducido por palabras ambiguas o incluso podemos enfrentarnos a problemas de “sobre ajuste” (“overfitting”) si hay demasiada información repetida. El preprocesado de los datos puede variar las tasas de acierto con márgenes superiores al 20%. Esto es, el entrenamiento de un modelo para text minning es sumamente sensible a las características del texto-conjunto con el que lo entrenamos. Además, en esta etapa también se recurre a normalización de frecuencias y asignación de pesos a los tokens entre otras técnicas, lo que influirá decisivamente en el entrenamiento.
El entrenamiento es otro apartado fundamental, no hay una solución única (modelo mejor que los demás por sí mismo) y la correcta configuración de este repercutirá de manera significativa en la calidad del modelo obtenido. La parametrización exige encontrar un equilibrio entre discriminar información repetida/ruidosa o poco descriptiva (métodos de reducción dimensional), o arriesgarnos al “sobre ajuste”, lo que se manifestará en forma de tasas considerables de error en la evaluación aislada de subconjuntos, ligeramente modificados, tomados a partir del conjunto de entrenamiento. Además, es una etapa crítica en cuanto a los recursos de que se dispongan (tiempo, potencia de computo, almacenamiento persistente, etc.).
Crear, entrenar y aplicar modelos, es fácil, sencillo y para toda la familia, que podríamos decir. Hacer que funcionen con tasas de acierto superiores al 75% requiere de mucho trabajo, la intuición también nos vale, afinar por encima del 90%-95% es todo un reto y en ocasiones resulta imposible. Aquí está la justificación del rol del “analista de datos”, que comprenda la naturaleza de los datos y el comportamiento de los modelos en distintos escenarios/problemas, ajustándose a unos recursos limitados.
Siendo honestos, es solo marketing y publicidad deshonesta cuando oímos hablar de: “inteligencia artificial aplicada a la ciberseguridad” (combo x2 del sensacionalismo y el modismo). En investigación, investigadores (que no ciber-investigadores) llevan trabajando desde hace décadas, en el análisis de la información. Lo correcto es referirse a investigadores/analistas de datos (más corporativo/empresa), que aplican técnicas de aprendizaje automático a conjuntos de datos procedentes de todos los campos, entre ellos la seguridad informática (sin necesidad de “ciber”).
Resulta curioso ver como hoy en día, fuera de círculos de investigación, se ignora que el gran reto actual, no es “el hacer que funcione”, sino como conseguir de la manera más óptima: la configuración, la selección de características, la selección de recursos, etc., que haga que nuestro entrenamiento dé como resultado el modelo más eficaz dentro de sus límites teóricos y prácticos. Por ejemplo, aplicando algoritmos genéticos como proponen compañeros de la Universidad de Granada pertenecientes al grupo de investigación Geneura [4][5].
Conclusión
En este artículo las conclusiones las tiene que extraer el lector por sí mismo. Qué experiencia saca de “jugar” con el experimento que hemos mostrado.
A título personal creo que lo que más desluce el artículo, es en sí mismo su principal aliciente, el uso de una interface gráfica. Es difícil explicar por escrito, algo que realmente a base de clics es muy simple. Por ello queda para un próximo artículo como darle un enfoque más avanzado, mostrar cómo desarrollar con Weka desde Java y de esta manera dotar a nuestros desarrollos de capacidad de aprendizaje automático.
Referencias
[1]
http://www.cs.waikato.ac.nz/~ml/weka/
[2]
http://www.isecauditors.com/sites/default/files/files/tinfoleak-1.5.tar.gz
[3]
http://www.vicenteaguileradiaz.com/
[4]
http://geneura.ugr.es/NEW/www/index.html
[5]
https://geneura.wordpress.com/members/
Autor: Juan Luis Martín
Departamento Auditoría