[Ejercicio 1 -- Clasificación
supervisada -- "Supervised classification -- Predicción de la variable clase para casos nuevos, "unseen
samples" -- "Class prediction"]
Como hemos comentado a menudo durante el curso, el clasificador final lo
aprendemos con todos los casos etiquetados, de los cuales no dudamos del valor
de su variable clase. En el problema de "iris", con los 150 casos etiquetados...
Y en este ejercicio lo que haremos, consistirá en utilizar el clasificador final
aprendido con todos estos casos, para predecir la clase de casos futuros de los
cuales el experto duda (o desconoce) el valor de su variable clase. En inglés se
le puede llamar a esto "categorize", o "class prediction".
Primero, entiende que, tal y como hemos hablado, esta predicción sobre casos futuros es una "apuesta", "bet": esto es, el clasificador final desconoce al realizar la predicción si está acertando o no. Aún así, previamente hemos estimado el porcentaje de bien clasificados de este clasificador, para intuir con qué probabilidad nos estamos equivocando/acertando: recuerda que ese porcentaje de bien clasificados se estima trabajando únicamente con los casos etiquetados.
Vayamos a simular con WEKA esta
situación. Escoge una base de datos (con no más de 20 variables...: ya verás
luego porqué...) supervisada en formato WEKA, de entre las que te ofrezco
("bases de datos seleccionadas") en la página del curso.
Abre primero la base de datos en formato texto (por ejemplo, en el navegador), y
en base a lo que expone su cabecera, trata de entender brevemente el problema de
clasificación que alberga: variable clase a predecir, significado de algunas
variables predictoras, número de casos y variables, presencia de valores
perdidos...
Ten esta base de datos en cargada en la primera ventana de "Preprocess" de WEKA:
con estos casos construiremos el clasificador final, que se utilizará para
predecir la clase de casos futuros de los cuales el experto desconozca el valor
de la variable clase.
Teniendo en cuenta el problema que has escogido, crea una fichero *.arff de
WEKA con 5 casos inventados por ti, donde ubiques el valor '?' en la variable
clase: esto es, clase desconocida, no podría ser de otra manera: "unlabeled,
unseen samples". Ten en cuenta que este segundo fichero que creas debe tener el
mismo formato, cabecera y definición de variables que el primero que contiene
todos los casos etiquetados. Aprovecha la cabecera del fichero original para
crearlo para este segundo fichero con los 5 casos creados por ti.
Carga este segundo fichero de casos sin etiquetar ("unseen samples") en WEKA en la pestaña "Classify", mediante la segunda opción de validación ("Test options"--> "supplied test set"). Y observa qué clase predicen para cada uno de estos 5 casos inventados por ti los siguiente clasificadores: naive Bayes (en WEKA, familia "Bayes"), 10-NN (10 nearest neighbour, el clasificador de los 10 vecinos más próximos: en WEKA, familia "Lazy") y otro clasificador de tu gusto. Ten en cuenta que el clasificador no ha sido construido-aprendido con estas 5 instancias inventadas por ti... sino con las cargadas en la ventana "Preprocess" y de las cuales es conocida su clase.
Para ver las clases predichas en estos 5 casos, activa la opción "Output Predictions" en el botón "More options". Para esto, no puedes fijarte en la "confusion matrix", donde no se diferencia lo predicho para cada caso individualmente. Acerca de estas predicciones, WEKA te muestra información interesante, que debes tratar de comprender: "actual", "predicted", "probability distribution"...
[Ejercicio 2 -- Técnicas de Preprocesamiento]
De entre las seleccionadas por mí, con alguna base de datos en formato *.arff de tu elección, aplicaremos varias técnicas de preprocesamiento. Antes de empezar con las tareas concretas, ten en cuenta los siguientes comentarios:
las técnicas de Preprocesamiento de WEKA están en su primera pestaña de “Preprocess”, dentro del botón “Filter—Choose”. Las técnicas están divididas en “supervised” o “unsupervised”, dependiendo si éstas hacen uso de la variable clase. A partir de ahí, siguen subdividiéndose en “instaces” o “attributes”, dependiendo en si éstas se aplican sobre los casos-instancias (filas del fichero *.arff en WEKA) o sobre las variables-attributes-features (columnas del fichero *.arff en WEKA);
una vez seleccionado un “filtro” o técnica de preprocesado, pinchando en su nombre en negrita, se accede al conjunto de parámetros de ésta, pudiéndose modificar (esto es general en WEKA para cualquier técnica de análisis de datos). Pinchando sobre el botón “More” se obtiene más información acerca de la función de cada parámetro;
una vez seleccionado el “filtro” o técnica y para que éste se aplique, se debe pinchar sobre el botón “Apply” para que se aplique sobre los datos que tenemos cargados;
una vez aplicado y para comprobar su efecto, tanto el “pseudohistograma” de la parte baja-derecha del interfaz de WEKA, así como la información de los estadísticos básicos de cada variable (parte derecha de la pantalla), son un buen punto de partida.
Los “filtros” o técnicas de preprocesado que os propongo, son los siguientes:
Sobre una base de datos que tenga variables numéricas, discretizar en 3 intervalos por igual anchura e igual frecuencia. Descrubre por ti mismo cómo acceder a ese “filtro” en WEKA. Entiende sus parámetros “bins” y useEqualFrequency”.
Descubre algún “filtro” por tu cuenta que te llame tu atención y no hayamos visto. Entiende y aplícalo.
[Ejercicio 3 --
Técnicas de preprocesamiento]
Abre la base de datos que está en el
siguiente enlace. Lee su cabecera, y entiéndela. Date cuenta del tamaño
de la base de datos y de los datos que recoge.
Se trata de un juego. Pero nos puede servir para hacernos cargo de la amplitud y variedad de filtros de preproceso, y la complejidad de algunos de éstos. A partir de este fichero Imaginemos que queremos hacer lo siguiente: seleccionar los casos de los partidos jugados por un equipo concreto (lo haremos para el equipo "LAGUN_ARO_GBC", o cualquier otro que tú elijas, es lo de menos) en la temporada 2012-2013:
busca dentro de los filtros que están en "unsupervised"--"instance";
es uno de estos el que debes aplicar para conseguir lo pedido: "RemoveWithValues";
hazlo en dos pasos: primero elige todos los partidos de la temporada de interés, luego los del equipo concreto
hay tres parámetros clave con los que debes jugar (no siempre con todos a la vez): "attributeIndex", "invertSelection", "nominalIndices", "splitPoint". Rrecuerda que para ver los parámetros de un método, debes pinchar sobre su nombre que aparece en negrita en el GUI;
¿con cuántos casos te has quedado finalmente? Chequea que ni hay partidos de otras temporadas (fíjate en los valores que toma la variable "codigo_temporada") ni de otros equipos (variable "equipo").
[Ejercicio 4 – Preprocesamiento de datos - Distribución desbalanceada en la clase a predecir]
Para realizar el ejercicio, de entre las bases de datos que os propongo, escoge algún problema con dos valores en la variable clase, y en el que uno de ellos esté "notablemente menos representado", esto es, una distribución de los valores desbalanceada en la variable clase. Ideas:
Diabetes.arff
(entiende los problemas y los valores de la variable clase):
originalmente con 500 casos con diagnóstico "negativo" (sin la
enfermedad) y 268 con diagnóstico "positivo" (sufren la enfermedad)
si te ves más valiente, un dataset de 40Megas con un desbalanceo extremo, predicción de "spam": originalmente con 39 mails spam y 1162 no-spam
Para un
clasificador de tipo naiveBayes, comprueba los porcentajes de acierto,
y muy especialmente el "true positive rate" (TPR) de la clase
minotoria, esto es, la proporción de casos de la clase minoritaria que
son capaces de "recuperar - bien clasificar": esto es, "hacerlo mejor"
en la clase minoritaria que cuando entreno con costes de
malaclasificación standard (FP=1, FN=1). Estima el porcentaje de
acierto de los modelos mediante el método "HoldOut - Percentage Split"
(entrenando con 66% y testando sobre el 33% restante).
Tal y como hemos comentado en las clases teóricas, puede ser de nuestro interés mejorar el TPR de la clase minoritaria, a costa posiblemente de empeorar el TPR de la clase mayoritaria: si el experto lo admite, adelante.
Para realizar lo expuesto, tienes el clasificador "CostSensitiveClassifier" dentro de la familia "meta" de clasificadores supervisados. Sus dos parámetros principales que debes controlar:
escoge el
clasificador base: naiveBayes
inserta de manera explícita la matriz de costes con la que indicas "cuánto más de grave es realizar un error en la clase minoritaria, respecto a la clase mayoritaria". Reflexiona sobre esto. Mi recomendación es fijar a "1" el coste de mal clasificar un caso de la clase mayoritaria como de la minoritaria: e ir aumentando el coste de mal clasificar un caso de la clase minoritaria como de la mayoritaria. Tal y como hemos explicado en las clases teóricas, ten en cuenta que en base a estos costes, WEKA reproduce-clona-replica los casos de la clase minoritaria en el conjunto de entrenamiento (aunque no lo muestre explícitamente): con este conjunto de entrenamiento en donde las proporciones de casos han variadó según la matriz de costes, aprenderá el clasificador; pero la validación se hará sobre la proporción original de casos de la base de datos (esto es, los casos de test no son reproducidos-clonados-replicados: fíjate que la suma de casos en la matriz de mala clasificación final es la original).
un detalle de funcionamiento de WEKA al insertar la matriz de costes: después de variar un coste, clicka en el tabulador para que se memorice.
¿Han variado los porcentajes de acierto en la clase minoritaria, esto es, el TPR en la clase minoritaria? ¿En base a hacerlo peor en la clase mayoritaria? ¿Cuánto peor? ¿Cómo influye el aumento de los costes en la clase minoritaria en el TPR de ambas clases, tanto la minoritaria como mayoritaria?
Date cuenta que el conjunto de entrenamiento-training intermedio donde se han variado las proporciones de los casos de "training", es transparente para el usuario. Y que este proceso es independiente de cómo se realice la validación del porcentaje de bien clasificados (hold-out, cross-validation, etc.).
Hemos visto también en las transparencias teóricas el popular algoritmo SMOTE,
que genera ejemplos sintéticos de la clase minoritaria en zonas
intermedias entre casos reales de la clase minoritaria. Este algoritmo
se encuentra dentro de los filtros de preproceso de WEKA:
filters-supervised-instances. Para poder aplicarlo junto con un
clasificador y ver su efecto en la matriz de confusión final, debemos
hacer uso del clasificador "FilteredClassifier": dentro de la familia
"meta" de clasificadores supervisados en la segunda pestaña de WEKA.
Para "FilteredClassifier" escoge como "Classifier" a naiveBayes, y como
"Filter" a SMOTE. Clicka en el nombre en negrita de SMOTE para ver sus
parámetros: el tercer parámetro, "percentage", hace referencia al
porcentaje de instancias artificiales-simuladas de la clase minoritaria
a crear. Así, dándole el valor "100", se duplicará el número de
instancias minoritarias, etc...
Para el dataset de Diabetes.arff. Variando el valor del parámetro "percentage" de SMOTE, fíjate en el efecto en los porcentajes de acierto estimados en cada clase, y especialmente la minoritaria. Como previamente, estima el porcentaje de bien clasificados medianteel "HoldOut - Percentage Split" (entrenando con 66% y testando sobre el 33% restante).
[Ejercicio 5 – Selección de variables, selección univariada: “filters for ranking features”]
Haremos el ejercicio
con la base de datos “Hepatitis.arff”. Entiende primero brevemente el
problema. Una breve explicación de sus predictoras y la clase a predecir la
tienes aquí.
Antes de empezar, discretiza sus variables numéricas en 3 intervalos por igual
anchura.
Dentro de la pestaña “SelectAttributes” de WEKA tenemos distintas funciones para tareas de selección de variables.
Si tienes interés en las distintas técnicas para seleccionar variables en problemas de clasificación supervisada, la segunda sección de este artículo es un buen punto de partida.
WEKA dispone de varias métricas para medir el nivel de correlación de cada predictora con la clase del problema. Entre ellas, trabajaremos con las siguientes tres:
“Information Gain Ratio”: al seleccionarla, pincha en el botón “More” para observar la forma en la que calcula la mencionada correlación. Esta medida es la que se utiliza para ubicar las variables en los nodos de muchas técnicas de árboles de clasificación;
“Symmetrical Uncertainty”: observa la fórmula que utiliza. Viene a ser una normalización de la métrica anterior;
“Chi-square”: ten en cuenta los apuntes de clase o la entrada de la Wikipedia para entenderla.
Ten en cuenta que como “Sarch Method”, WEKA te propondrá “Ranking”, esto es, rankear-ordenar las predictoras según su nivel de correlación (calculado de la manera escogida) respecto a la variable clase.
En el ranking aprendido, WEKA primeramente muestra el nivel de correlación calculado. Segundo, el índice de dicha predictora en la base de datos original. Tercero, el nombre de la variable.
¿Son los tres rankings aprendidos idénticos? ¿Deberían serlo?
Complicado, y eso que tenemos 19 predictoras: imagínate cientos o miles.
Como una forma de mitigar-aliviar este efecto de inestabilidad y reducir la variabilidad en los resultados de distintas técnicas, está de moda hoy en día en la comunidad “machine learning” el concreto de la estabilidad al realizar una selección de variables. Puedes realizar una búsqueda del estilo en Google: “stability for feature selection”; donde se han propuesta medidas especiales para medir el nivel de estabilidad de varias técnicas de selección de variables, esto es, el nivel de concordancia (“agreement”) en el ranking-ordenación propuesto. Hay varios trabajos que abordan este tema de la estabilidad de las variables seleccionadas. Uno de ellos, con un "abstract" sencillo de entender, lo tienes aquí [Kuncheva'07].
Un ejercicio sencillo para abordar lo anterior puede ser el siguiente. Calcular el ranking medio de los tres anteriores, para cada predictora: esto es, calcular qué posición tendría cada predictora en un ranking que reflejase la posición media de los tres rankings originales. Y quizás trabajar con este ranking medio, podría dar mayor estabilidad-robustez al modelado... WEKA no tiene esta funcionalidad, pero puedes empezar a hacerlo a mano (no lo acabes, es demasiado).
Escoge un clasificador. Siempre que tengas que estimar un porcentaje de bien clasificados, lo haremos con una “10-fold cross-validation” (si no conoces esta técnica de validación, la veremos en temas posteriores). Haz lo siguiente:
escoge una de las tres métricas univariadas anteriores, y en base al ranking que nos propone, aprende un clasificador con las “top-5” y “top-10” variables. Para eliminar variables, juega con la primera ventana de WEKA y sus opciones “Remove”, “Invert”, etc... Ojo: no elimines la variable clase;
si te quieres ir haciendo un pequeño experto en WEKA, para hacer de manera más ágil la selección anterior: tienes el parámetro “numToSelect” de la medida de ranking seleccionada, y la opción “Save reduced data” en las propiedades de la ejecución realizada (botón derecho en la ejecución realizada en la pestaña “SelectAttributes”);
O para realizar lo anterior de una única vez, fíjate en las opciones del clasificador "meta-AttributeSelectedClassifier": entiéndelo antes de aplicarlo;
aprende el mismo tipo de clasificador con todas las predictoras originales.
¿Cómo son los porcentajes de acierto de las distintas propuestas? ¿Se reduce el porcentaje de acierto al trabajar con los subconjuntos de variables propuestos?
¿Estos rankings
miden o tienen en cuenta los niveles de correlación, y posibles
redundancias, entre las variables del ranking? ¿Podrían por ejemplo la
primera y segunda predictora, aún con distinto nombre, ser las mismas?
[Ejercicio 6 -- Selección de variables en clasificación supervisada -- "The univariate approach" -- Una aplicación en "bioinformática"]
Para contextualizar el campo de
aplicación del ejercicio, espero que ayude la lectura del siguiente
artículo.
Utilizaremos este campo de aplicación como excusa para realizar un ejercicio
sobre técnicas univariadas de selección de variables en problemas de
clasificación supervisada.
Bajo lo amplio que es el término
bioinformatica,
de forma general viene a englobar el rol de las tecnologías de la información en
la biología y biomedicina. En recientes estudios en EE.UU., venía ocupando el
puesto número 1 del ranking con profesiones con mayor futuro.
Una de las principales ramas de la bioinformática viene a ser la aplicación de
las técnicas de "data mining" sobre datos de origen biológico y médico: donde,
con el objetivo de realizar diagnósticos-pronósticos más certeros y rápidos, las
técnicas de minería de datos juegan un rol fundamental en la búsqueda de
posibles "biomarcadores" ("biomarkers"). Por "biomarcador" se puede entener
aquella molécula de la vida (i.e. gen, proteína, microRNA, etc.) que pueda tener
relación-influencia en la aparición de la enfermedad: pudiéndonos ayudar a
realizar un diagnóstico-pronóstico más rápido y certero, y con el objetivo de
desarrollar fármacos que actúen sobre ella.
Esto es, "biomarcadores" diferencialmente expresados en los distintos estados de la enfermedad (sano versus control; brote versus remisión versus sano; etc.).
Para investigar en el origen y
posibles biomarcadores de muchas enfermedades complejas, durante los últimos
años se han utilizado de manera masiva los
chips de ADN: éstos son
campaces de medir-monitorizar los niveles de expresión de la práctica totalidad
de genes en un organismo (e.g. Homo sapiens). Las referencias a los términos "DNA
microarrays" y "gene expression datasets" en la red son incontables. Su uso en
la investigación de enfermedades de origen genético está popularizado: para la
ayuda en el diagnóstico-pronóstico, o para la búsqueda de biomarcadores. La
manera normal de proceder es la de monitorizar mediante chips de ADN sus niveles
de expresión (en sangre, en el tejido de una biopsia) a un grupo de enfermos, y
por otro lado a un grupo de personas sin la enfermedad: disease versus
control.
Aquí está nuestra base de datos supervisada para aplicar técnicas de minería de
datos: donde los casos se obtienen a partir de los microarrays de ADN
monitorizados, y las variables predictoras vienen a ser los niveles de expresión
de los distintos genes medidos. La variable clase a predecir, el fenotipo,
habitualmente dicotómico: enfermo versus sano; disease versus
control.
Así, este tipo de bases de datos y
problemas vienen a suponer un interesante "challenge" computacional para aplicar
técnicas de minería de datos: muy pocos casos (habitualmente menos de 100) y
miles de variables predictoras (genes) por caso. Y en las hipótesis médicas
habituales de médicos y biólogos, no más de 10-15 genes ("biomarcadores") están
detrás de la generación de una enfermedad. Así, el rol de las técnicas de
selección de variables en estos dominios es indispensable para detectar estos
genes-biomarcadores: esto es, aquellos que muestran unos niveles de expresión
diferenciados entre sanos y pacientes:
feature selection y
gen
selection.
Vamos a hacer un ejercicio con WEKA:
en el siguiente
enlace nos
encontramos con una colección de bases de datos de microarrays de ADN en
formato *.arff de WEKA. El siguiente también es otro popular enlace-repositorio en la misma línea. Dentro de las bases de datos que os ofrezco en el
curso, también tenéis un
enlace con varias.
uno de ellos, "Embryonal tumours
of the central nervous system". Cárgalo en WEKA: trata acerca de dos
dolencias oncológicas en el sistema nervioso, con el objetivo de encontrar
genes diferencialmente expresados entre ambas dolencias. Así podemos
plantear el problema.
debido al tamaño del dataset y las operaciones que
le pediremos, es una buena idea ejecutar WEKA con más memoria RAM que
la que usa por defecto. Encontrarás en la red ayuda al buscar sobre
"run weka with more memory". Ella viene a resumirse en lanzar WEKA
desde la línea de comandos de tu sistema operativo con una orden del
estilo "java -jar -Xmx2048m weka.jar". En este ejemplo concreto se
lanza con 2048 Megas (i.e. 2 Gigas).
primeramente, en la ventana "Preprocess", discretiza los valores de cada gen en 3 intervalos por igual anchura: ésta es una práctica habitual en biología, asumiendo que los valores de cada gen vienen diferenciados entre sus valores "underexpressed", "baseline" y "overexpressed".
segundo, en la ventana "Select Attributes" WEKA tiene sus técnicas de selección de variables. Vamos a detectar aquellos genes que tienen un nivel de expresión diferente en los distintos tipos de la enfermedad, esto es, aquellos con un mayor nivel de correlación respecto a la clase ("fenotipo") a predecir:
rankea todos los genes en base al nivel de correlación con la variable clase (fenotipo). Para ello, utiliza la métrica "Information Gain" ("Attribute Evaluator --> InfoGain"; "Sarch Method --> Ranker"): pincha sobre el botón "More" para conocer cómo se realiza el cálculo de esta métrica ("Information Gain") para medir el nivel el nivel de correlación entre cada gen y la clase. Esto es, en cuánto se reduce el nivel de incertidumbre de la clase, H(C), al conocer los valores del gen, H(clase | gen): "H(clase) - H(clase | gen)".
en la lista ordenada generada por WEKA, el primer valor representa el nivel de la métrica "Information Gain" para cada gen. El segundo valor es el índice del gen en la base de dator original cargada. (ten en cuenta que los genes están ordenados en esa lista en base a su nivel de correlación (medido por "Information Gain") con la variable clase). Tercero, un identificador del gen: puedes utilizarlo en la base de datos http://www.ncbi.nlm.nih.gov/ para conocer de qué gen concreto se trata (borra "_at" del nombre del gen para consultarlo en este enlace, y cambia "All Databases" --> "Gene" para realizar la consulta). En el website NCBI, muy popular en el campo de la medicina, biología, etc., tienes todo tipo de información acerca de este gen.
aprende distintos modelos de clasificación y estima su tasa de acierto. Los clasificadores: IB-5 (clasificador de los 5 vecinos más próximos), Naive Bayes y otro que escojas. Para cada uno de los tres clasificadores, estima las tasas de acierto mediante "leave one out". Todo esto, para los siguientes subconjuntos de genes:
con todos los genes
originales.
con los primeros 5 genes rankeados por "Information Gain": juega con la ventana "Preprocess", y sus opciones "Invert", "Remove"... cuidado con borrar la clase...
con los primeros 10 genes rankeados por "Information Gain".
[Ejercicio 7 – Selección de variables, selección multivariada: “filters multivariados” y “wrappers”]
Haremos el ejercicio con la base de datos “Hepatitis.arff”. Entiende primero brevemente el problema. Una breve explicación de sus predictoras y la clase a predecir la tienes aquí.
Antes de empezar, discretiza sus variables numéricas en 3 intervalos por igual anchura. Dentro de la pestaña “SelectAttributes” de WEKA tenemos distintas funciones para tareas de selección de variables.
Si tienes interés en las distintas técnicas para seleccionar variables en problemas de clasificación supervisada, la segunda sección de este artículo es un buen punto de partida.
Vamos a dar un salto con las técnicas de selección de variables. De técnicas univariadas que no medían ni tenían en cuenta los niveles de redundancia entre las variables seleccionadas, a dos técnicas distintas de realizar una selección multivariada de un subconjunto de variables que tenga en cuenta estas correlaciones.
Ten en cuenta que cuando hacíamos una selección univariada mediante una técnica “filter” (e.g. Information Gain Ratio), se realiza un ranking que refleja el nivel de correlación de cada predictora con la clase: para construir posteriormente un clasificador este ranking se “corta” en algún punto quedándonos con las “top-features”. Pero este ranking no tiene en cuenta los niveles de redundancia entre las predictoras, pudiendo por ejemplo la primera y segunda ser “mi sueldo en dolares, mi sueldo en euros”, y cada una de ellas tener un fuerte nivel de correlación con la clase.
Las técnicas multivariadas tratan de ir más allá, tal y como hemos visto en clase, escogiendo un subconjunto de variables que contenga variables altamente correladas con la clase, pero poco correladas entre sí.
Dos maneras de atacar estas técnicas multivariadas en WEKA, cuyos aspectos teóricos básicos hemos explicado en clase:
“Correlated Feature Selection” (CFS). Observa cómo cambiando el “Search Method” (heurístico de optimización) para moverse entre los distintos subconjuntos de variables, el subconjunto final de variables (el mejor encontrado en toda la búsqueda realizada) cambia. Ten en cuenta que supone un heurístico de búsqueda.
“WrapperSubsetEval”:
Observa cómo cambiando el clasificador base, el subconjunto final de variables cambia. ¿Tiene sentido?
Fijándote en los parámetros del método “wrapper”, ¿cómo crees que se estima el porcentaje de bien clasificados de cada subconjunto de variables que visitamos en nuestra búsqueda-”search”?
Observa cómo cambiando el “Search Method”, esto es, el heurístico de optimización para moverse entre los distintos subconjuntos de variables, el subconjunto final (el mejor encontrado en toda la búsqueda) de variables cambia.
[Ejercicio 8 – Selección de variables: selección univariada + selección multivariada]
Ya has visto y practicado con varias técnicas de selección univariada y multivariada. Distintas medidas para calcular la correlación entre clase y atributo en el caso univariado; los filters multivariados (CFS) y "wrappers" para el multivariado.
Una aproximación clásica, muy popular en las bases de datos de microarrays de ADN en bioinformática, es la de primero lanzar un filter univariado y a partir del "top-k" de variables más correladas con la clase, lanzar sobre éstas una técnica multivariada ("multivariate filter" o "wrapper"). A este tipo de propuestas se las conoce como "hybrid feature selection techniques". Si lanzasemos la técnica multivariada sobre el total de varias miles de variables, es más que posible que nos encontrásemos con limitaciones computacionales: no end, or memory crash.
Prueba a realizar lo expuesto, tanto sobre una base de datos de microarrays de ADN, o alguna otra con un número elevado de variables originales (más de 40-50).
[Ejercicio 9 – Estimación del porcentaje de bien clasificados]
Para un clasificador y base de datos que tú elijas (trata de que la base de datos tenga un número de casos "suficiente", más allá de 300-400), estima el porcentaje de bien clasificados de las siguientes formas, y muestra su porcentaje de bien clasificados estimado:
método no-honesto de estimación
método H, hold-out, entrenando con 66%
método H 5 veces
método de estimación basado en 10 rodajas: 10-fold cross-validation
método de estimación basado en 5 rodajas: 5-fold cross-validation
leave-one-out: ¿qué valor debes poner en "folds"?
(WEKA no tiene implementado el 0,632 bootstrapping)
¿devuelven todos el mismo porcentaje de error estimado? ¿por qué?
¿cuál de los métodos anteriores devuelve el mejor porcentaje de error estimado? ¿era esperable? ¿por qué?
¿cuál te parece la estimación más fiable de las 6 anteriores? Ten en cuenta que el error real únicamente se pude conocer teniendo infinitos casos.
¿cuál de los 6 métodos anteriores de estimación le ha exigido más trabajo de cómputo a WEKA? Fíjate que durante la ejecución, en la parte baja izquierda del GUI, en Status, aparece un mensaje cambiante: ¿cuál es?
cuando le pedimos a WEKA que estime el error mediante 10-fold cross-validation, ¿cuántos modelos aprende WEKA internamente? ¿Por qué no son 10? ¿Con qué porcentaje de casos del total aprende cada uno de esos modelos?
¿puede darse el caso que para una "seed-semilla" y método de validación concreto, en una ejecución el clasificadoX "sea mejor" que el "clasificadorY", y que para otra "seed-semilla" ocurra justamente lo contrario? ¿Qué es "ser mejor"? Habrá que ser más "finos", ¿no?
[Ejercicio 10 – Estimación honesta del porcentaje de bien clasificados]
Varios trabajos nos
alertan sobre la obligación de ser cuidadosos en la estimación del porcentaje de
bien clasificados. Entre ellos, resaltaría los siguientes [Reunanen'03] [Smialowski'09],
con unos abstracts y mensajes muy claros.
La clave es la siguiente:
el modelo final (e.g. nuestra bola de cristal con la que predeciremos la clase de casos futuros) lo construimos con todos nuestros casos, y sobre todos nuestros casos aplicamos nuestro "pipeline" de análisis: e.g., primero discretizar las variables continuas, luego imputar los valores perdidos, luego seleccionar las variables más relevantes, y finalmente aprender un modelo de clasificación supervisada.
¿cómo estimamos el porcentaje de bien clasificados del "pipeline" anterior?
sobre todos los casos, discretizar-imputar-featureSelection (nos quedamos con un subconjunto de variables ya discretizadas y sin valores perdidos), y luego mediante una 10-cross-validation estimamos el porcentaje de bien clasificados de un clasificador de nuestra elección;
¿es lo anterior "correcto" - "honesto"? Cuándo has aplicado la 10-fold-cross-validation y en cada una de sus iteraciones de 9-folds-for-training 1-fold-for-testing, ¿estás seguro que NO has utilizado en el modelado-training la información de las instancias de la hoja-fold de testing?
piénsalo, la respuesta es que la información de los datos de la hoja-fold de testing sí ha sido utilizada para discretizar-imputar-featureSelection.
esta forma de estimar el porcentaje de bien clasificados no es honesta, es "optimista", devolviendo posiblemente una bondad de acierto superior a la real.
¿cómo podemos por lo tanto estimar el porcentaje de bien clasificados de nuestro pipeline de manera "honesta", sin que la información de las hojas-folds de test cuando hacemos una 10-fold-cross-validation sea utilizada en ninguna decisión de modelado (sea discretizar, seleccionar variables, etc...)?
no queda más remedio que REPETIR TODO EL "PIPELINE" que proponemos (discretize-impute-FSS-classifier) en CADA iteración de 10-fold-cross-validation: 10 veces, entrenando con 9-folds el "pipeline" y testando en la fold-restante.
¿cómo se hace esta estimación honesta del porcentaje de bien clasificados en WEKA? La pista está en "Classifier"-"meta-"FilteredClassifier". Lee con atención sus clasificadores y entiende sus parámetros.
prueba de manera empírica con una base de datos de tu elección que ambas formas de estimar el porcentaje de bien clasificados ("la no honesta" y "la honesta") no devuelven el mismo porcentaje de bien clasificados.
Tras comprender todo lo anterior es el momento de estudiar la Fig1del trabajo de [Smialowski'09]. La figura asume que la validación se va a hacer mediante "hold-out" ("percentage split"): esto es, entreno con una partición de los datos y estimo su bondad en la partición restante. Observa que la manera errónea de validación sería la concatenación de los pasos B+C: en el paso B se realiza la selección de variables a partir del conjunto de datos completo, y aunque posteriormente el modelo de training se aprende únicamente sobre la partición de train, "el daño ya está hecho" al validar este modelo en la partición de test restante (paso C). Esto es, los casos de la partición de test sí se han utilizado en la fase de selección de variables (paso B), siendo falsa la necesaria premisa que los casos de la partición de test no han tomado parte en ningún procedimiento de aprendizaje del modelo.
Observa las diferencias del proceso anterior respecto a la concatenación de los pasos A+C.
[Ejercicio 11 – Comparación estadística entre los porcentajes de acierto de dos clasificadores en una base de datos]
Escoge una base de datos con un número "suficiente" de casos (i.e. al menos 300-400). Escoge dos clasificadores que te interese comparar en ese problema. Como método de estimación del porcentaje de bien clasificados, variando la semilla, escogeremos 5 ejecuciones de 10-fold cross-validation para cada clasificador. Obviamente, para que el proceso sea más completo, un número mayor de ejecuciones del 10-fold cross-validation es necesario: pero bueno, el tiempo es limitado. Compara ambos clasificadores con el test correspondiente, y extrae conclusiones del tipo:
"the significance of the differences between compared techniques is p-value=... This means that the results of both compared classifiers can be considered statistically different (or not)...". O frases similares de los cuales están plagadas los trabajos-papers de análisis de datos.
Ten en cuenta que si utilizamos la misma semilla de aleatorización de casos para el par de clasificadores en cada ejecución (y de ahí se deriva la misma partición de los datos en las hojas-"folds" de la cross-validation), las muestras con los 5 porcentajes de acierto de ambos clasificadores son apareadas: esto es, la primera del clasificador1 con la primera del clasificador2, etc. Esto condicionará que los tests estadísticos que utilicemos para comparar ambas muestras de resultados sean apareados ("2-sample paired t-test" en el caso paramétrico; "Wilcoxon test" en el caso no-paramétrico).
Si quieres utilizar un test paramétrico (e.g. t-test), "para hacerlo bien" y asegurarte que el uso de los parámetros del test está justificado, se debería hacer uso del test de "Wilks-Shapiro" si es que quieres chequear que cada una de las dos muestras comparadas sigue una distribución normal. El test lo tienes implementado en R, y también en otras webs que lo hacen online (search for "Wilks Shapiro test online" or similar).
A partir de ahí, para comparar los resultados de ambos clasificadores y obtener el p-value que nos diga el "nivel de significancia de las diferencias" entre ambos clasificadores, tienes varios recursos ("two sample t-test"; "Mann Whitney" es un test no-paramétrico para muestras no-pareadas; "Wilcoxon" es un test no-paramétrico pareado):
R-software: parametric tests, non-parametric tests.
Excel - Calc (OpenOffice): creo que en su versión standard únicamente contiene la "prueba t", y no contiene los no paramétricos.
Echa un vistazo a este test estadístico de "Kruskall Wallis": ¿a qué tipo de preguntas trata de ofrecer respuestas?
[Ejercicio 12 – comparación estadística múltiple -- varios algoritmos en varios datasets]
Tal y como hemos visto en el video asociado al tema, una práctica común en la comunidad de "machine learning" consiste en la comparativa de varios algoritmos en varios datasets: por resumir, llamémosle "comparativa múltiple". Esto es, se trata de extraer conclusiones que vayan más allá del clásico "el algoritmoA es superior al algoritmoB en el datasetC". Compararemos una batería de algoritmos en un conjunto de datasets. Tras el pionero trabajo de Demsar'2006 (ver apartado referencias) y las posteriores mejoras y acotaciones propuestas por García y Herrera'2008 (idem), esta práctica es actualmente un standard en nuestra comunidad.
Desde entonces han surgido varias tecnologías para realizar este tipo de comparativas estadísticas. A mi conocimiento han llegado estas dos:
- La plataforma online STAC, "Statistical Tests for Algorithm Comparison". Atractiva, de uso sencillo, te llevará unos pocos minutos hacerte con ella gracias a su interfaz gráfico. Como podrás comprobar sus posibilidades van más allá de la "comparativa múltiple". Ésta la podrás encontrar en "Non parametric tests --> Multiple groups, All versus All". [Enlace]
- Para los "seguidores" de R tenemos el paquete "scmamp" ("statistical comparison of multiple algorithms in multiple problems"). En la siguiente viñeta nos ofrecen sus autores una amena ayuda para conocer el flujo común de funciones para realizar la comparativa: esta ayuda es relevante hasta el apartado "graphical representations", y a partir de ahí ya te ofrece posibilidades para varias filigranas. Aunque no es un tema que hemos tratado en profundidad, la viñeta de ayuda contiene un apartado interesante ("Parametric vs. non-parametric") que nos hace reflexionar sobre el uso de tests parámetricos y sus asunciones asociadas, o bien decantarnos por los no paramétricos. El paquete está disponible en el servidor CRAN de R y en la popular web "mloss" de software libre para "machine learning".
Me dejo muchos detalles en el camino sobre el uso de ambas plataformas. Pero tu intuición, experiencia y un poco de paciencia irá descubriendo su modo de uso. No dejes de acudir a la ayuda de ambas plataformas y a los ejemplos que ofrecen para facilitar tu uso.
Recuerda que primero se trata de realizar un test de hipótesis que chequee la hipótesis nula acerca del similar comportamiento de la batería de algoritmos en el conjunto de datasets. En caso de ser rechazada se pasan a realizar tests de hipótesis entre todas las parejas de algoritmos ("pairwise differences -- posthoc tests"), donde la hipótesis nula en cada uno de ellos es que la pareja de algoritmos tiene un comportamiento similar. A partir de aquí podemos obtener los conocidos como "Critical Difference Diagrams": los algoritmos conectados por una línea horizontal indican que no se ha rechazado para ellos la hipótesis de comportamiento similar. Los números de la parte alta nos indican, para el conjunto de datasets, el ranking medio de cada algoritmo tras ordenarlos en cada dataset por su bondad predictiva: el cálculo del estadístico del primer test del proceso se basa en dichos rankings.
Para cada test de hipótesis que realicemos y el "p-value" que éste nos devuelva, es necesario fijar un umbral de significancia que nos indica la "probabilidad de rechazar la hipótesis nula cuando esta es cierta": al fin y al cabo, se trata de un umbral de riesgo en la decisión que tomemos. Una práctica habitual es fijar este umbral en la probabilidad 0.05, y a partir de ahí, en caso de que el "p-value" del test sea menor que este umbral, rechazar la hipótesis nula. Se debe informar acerca del umbral elegido.
Escoge 5 datasets supervisadas en formato WEKA con un número "suficiente" de casos (i.e. al menos 300-400). Escoge 4 algoritmos supervisados que te interese comparar en esta batería de problemas. Como método de estimación del porcentaje de bien clasificados, variando la semilla de aleatorización ("Test options --> More options --> Random seed") , ejecutaremos una 10-fold cross-validation para cada algoritmo y dataset. Obviamente, para que el proceso sea más completo, un número mayor de ejecuciones del 10-fold cross-validation es deseable: pero bueno, el tiempo es limitado.
De entra las dos herramientas para realizar la batería de tests que os he presentado, escoge una de ellas.
Documenta los resultados obtenidos: analiza los resultados y extrae conclusiones. Tus conclusiones son lo que cuentan. Muestra también los "Critical Difference Diagrams".