Una selección de las características adecuada eliminará ruido en los datos y acelerará el aprendizaje del modelo estadístico.
Cada fichero binario está definido por un vector que representa las repeticiones de cada palabra en el reporte generado en su análisis estático. Todos los vectores completos apilados forman la matriz completa de características.
Como ejemplo tomaremos en dataset formado por los binarios amd64 + malware, de manera que el tamaño de esta matriz se puede calcular de la siguiente manera:
Tamaño total de la matriz de características sin filtrado = nº de muestras * nº de características * tamaño de cada componente del vector de características.
Siendo:
nº de muestras: 9896 ficheros binarios teniendo en cuenta goodware y malware,
nº de características: 12.384.366 palabras distintas generadas por todos los reportes estáticos de los binarios,
tamaño de cada componente del vector de características: dado que cada componente es almacenado en un Dataframe Pandas el cual esta coompuesto por variables de tipo float64, las cuales están compuestas por: 52 bits de mantisa + 11 bits de exponente + 1 bit de signo = 64 bits = 8 bytes. De esta manera, el tamaño resultante es: 9896 * 12.384.366 * 8 bytes = 980.445.487.488 bytes = 486815038,475 Kbytes = 475.405,31101 Mbytes = 464,262999034 Gbytes
Esta matriz, debido a su tamaño, es inmanejable por el equipamiento informático con el que contamos para hacer este trabajo.
CAPÍTULO 5. METODOLOGÍA Y DISEÑO Para solventar esta situación se ha procedido a dividir la matriz en submatrices, y a cada una de estas submatrices se le ha aplicado un filtrado por varianza, con idea de eliminar aquellas caracteristicas que, o aparecen en practicamente todos los reportes de análisis estático o en casi ninguno.
Partición del dataset: datos de entrenamiento y test
Antes de proceder a tomar decisiones de filtrado de características sobre cada submatriz, se ha procedido a dividir el dataset completo en subconjuntos de entrenamiento y test. El motivo se hacer esta separación antes de tomar ninguna decisión sobre el conjunto de los datos es evitar el efecto de fuga de datos o, como se conoce en inglés,data leakage.
Para seleccionar las mismas muestras en cada submatriz, el procedimiento de particionado del dataset se hace por medio de la función split, pero utilizando siempre el mismo valor para la semilla aleatoria random_state. El código aplicado para esta operación se encuentra en la funcióndatasets2finalDataset:
X_train , X_test , y_train , y_test = train_test_split (
X_unfiltered , y, test_size = test_size , random_state =42)
El tamaño del conjunto de test se ha fijado en un 33 % de las muestras, de manera que para entrenamiento se utiliza un 67 %. Más adelante se hará validación cruzada sobre el conjunto total de muestras, pero las características utilizadas serán las seleccionadas en función del subconjunto de entrenamiento. Toda transformación o selección de características se hace sobre el conjunto de entrenamiento y después se traslada sobre el subconjunto de test.
Límites impuestos a las submatrices
El equipo utilizado cuenta con 12Gb de RAM y una partición de 16 Gb de Memoria SWAP. Por este motivo se ha aplicado un filtrado de características secuencial a cada submatriz que compone la matriz total.
Se han impuesto las siguientes restricciones:
Cada submatriz utilizada del conjunto de datos a tratar debe contar como máximo con 5000 características.
La matriz resultante del filtrado tendrá como máximo 15.000 características.
Eliminación de características con baja varianza
Se ha procedido a filtrar las características con menor varianza a cada submatriz hasta conseguir una matriz formada por un máximo de 15.000 características .
Para ello se ha segmentado el dataset completo y se ha creado una lista de listas de palabras, de manera que en la primera posición se almacena la lista de palabras que se repiten 1 vez, en la 2ª posición se encuentra la lista de palabras que se repiten 2 veces, y así sucesivamente.
Una vez hemos obtenido esta lista de listas, seleccionamos aquellos intervalos que acumulen menos de 5000 palabras formando subconjuntos de palabras que, cuando se traduzcan las submatrices, estas se ajusten a los límites definidos en el apartado anterior. Seguidamente extraemos la información del conjunto total de ficheros binarios para obtener la submatriz de características que contenga, para todas las muestras, sólo las características seleccionadas en este subconjunto.
A cada submatriz de características le aplicamos un filtro de baja varianza, empezando en una varianze del 99 % reduciendose en un 1 % cada vez que la matriz resultante excede el tamaño máximo definido para ella fijado en 15.000. La nueva varianza se aplica a la matriz resultante hasta el momento para asegurar que se aplica el mismo filtro por varianza a todo el dataset. Este procedimiento se repite sucesivamente hasta haber conseguido que la matriz resultante se ajuste al máximo de características admitidas o hasta que la varianza aplicada llegue al 50 %. Se impone este valor de 50 % porque filtrar por varianza por 51 % es equivalente a filtrar por el 49 %. Siguiendo esa misma lógica, todos los filtros por varianza por debajo del 50 % se encontrarían ya realizados en los filtrados superiores al 50 %.
Este filtro, aunque parezca inicialmente laxo, elimina las palabras demasiado comunes y las que son extremadamente específicas, como las direcciones de memoria que utilizan unos pocos binarios.
En nuestro caso la varianza final aplicada ha sido 96 % y las 12.169 caracteristicas obtenidas tras este filtrado.