Trabajo realizado en las prácticas de la asignatura de Aprendizaje y Percepción de 4º Curso de Ingeniería Informática. A partir de la facilitación de diversos archivos de características, tanto de entrenamiento para la construcción del clasificador, como de test, se ha procedido a procesarlos con tres diferentes algoritmos: k-nn (k vecinos más cercanos) y Perceptrón, para los datos geométricos y hmm (modelo oculto de Márkov) para los datos estructurales con el fin de obtener resultados concluyentes.
Elaboración de la estructura del ADN y ARN en papel.pdf
Aprendizaje y percepción - memoria de prácticas
1. Memoria de prácticas de Aprendizaje y Percepción (APP)
ETSINF, Universitat Politècnica de València, Junio de 2014
David Villota Beltrán
davilbel@fiv.upv.es
Resumen
En este documento se pretende exponer el trabajo
realizado en las prácticas de la asignatura de
Aprendizaje y Percepción –APP- de 4º Curso de
Ingeniería Informática. Se ha abordado la siguiente
tarea principalmente: A partir de la facilitación de
diversos archivos de características, tanto de
entrenamiento, para la construcción del clasificador,
como de test, se ha procedido a procesarlos con tres
diferentes algoritmos: k-nn (k vecinos más cercanos)
y Perceptrón, para los datos geométricos y hmm
(modelo oculto de Márkov) para los datos
estructurales con el fin de obtener resultados
concluyentes. A continuación, se muestran los
resultados obtenidos y las conclusiones a las que se
ha llegado.
K-nn | perceptron | hmm | gauss2D | ocr20x20 |
traveller | test | training | errors | graphics
1 k-nn – gauss2D
Algoritmo: k-nn
Tarea: gauss2D
Parámetros experimentales: k = 1, 5, 10, 15, 20, 25, 30.
Para llevar a cabo esta tarea he utilizado el programa
facilitado en C knnc.
Antes de nada, es necesario obviar las 5 primeras
líneas del fichero de test gauss2D.te, ya que no son
relevantes en la obtención de los datos. Lo hago del
siguiente modo:
tail –n +6 gauss2D.te | awk '{print($NF);}'
> test
A continuación, procedo a obtener la clasificación
por k-vecinos más cercanos variando k en 1, 5, 10,
15, 20, 25, 30 y comparamos el último campo del
resultado (la clase de la característica) con el fichero
de test para obtener el error pertinente. Realizo todo
ello en un solo comando de la siguiente manera:
for k in 1 5 10 15 20 25 30 ; do echo -n
"$k " ; ./knnc -k $k gauss2D.tr gauss2D.te
| paste test - | awk '{if ($1!=$2)
e++;}END{print(e*100/NR);}' ; done > result
El fichero resultante result muestra una tabla [1] con
el número de vecinos en la primera columna y la tasa
de error obtenido en la segunda:
k error (%)
1 9.6
5 8.55
10 7.8
15 7.6
20 7.45
25 7.5
30 7.65
[1] Tasa de error resultante para k
Voy a mostrarlo gráficamente [2] para que se aprecie
mejor el resultado:
[2] Tasa de error resultante para k variable
Se observa que, al aumentar el número de vecinos
más cercanos mejora ínfimamente la clasificación. Al
principio es una mejora significativa pero conforme
aumenta k a valores mayores de 20, la mejora cesa e
incluso el error aumenta. Esto puede ser debido a que
los datos de aprendizaje son lo suficientemente
relevantes y hay una ausencia de ruido, lo que
favorece la clasificación con pocos vecinos más
cercanos, y al elegir un número tan elevado de
vecinos se confunden las fronteras de decisión y se
comete un error más significativo. En este caso, por
lo tanto, nos quedaremos con k=20, lo que nos dará
una tasa de error del 7.45%.
2. 2 perceptron – ocr20x20
Algoritmo: k-nn
Tarea: ocr20x20
Iteraciones: 20
Parámetros experimentales:
α = 1, 0.1, 0.01,
β = 1, 1e-10, 1e-30.
Para llevar a cabo esta tarea he utilizado el script
facilitado en octave percep.m, modificando las líneas
marcadas con break ( ) en la siguiente captura [3] (se
ha obviado mostrar el bucle for, ya que es demasiado
largo):
[3] Líneas modificadas del script percep.m
Antes de nada, al igual que en la primera tarea, es
necesario deshacerse de las 5 primeras líneas del
fichero de test ocr20x20.te. Lo hago del siguiente
modo:
tail –n +6 ocr20x20.te | awk
'{print($NF);}' > test
A continuación, procedo a sacar la clase resultante
ejecutando el algoritmo perceptrón modificado y
seguidamente, vemos que es necesario borrar la
cabecera y las dos últimas líneas (que contienen
líneas vacías) del fichero generado class para así
compararlo con el fichero de test y obtener la tasa de
error pertinente. Realizo todo ello en un solo
comando del siguiente modo:
tail -n +6 class | head -n -2 | awk '{m=1;
for (i=2;i<=NF;i++) if ($i>$m) m=i;
print(m-1);}' | paste test - | awk '{if
($1!=$2) e++;} END{print(e*100/NR);}'
En este caso, el comando nos devuelve una tasa de
error de 5.5. Finalmente para continuar recibiendo
resultados, vamos cambiando los valores de α y β en
el script utilizado y obtenemos todas las tasas de
error que necesitamos para llegar a una conclusión
convincente. Ahora muestro, tanto en la tabla [4],
como en la gráfica [5], los resultados obtenidos:
α Β error (%)
1 1 5.5
0.1 1 4
0.01 1 4.75
1 1,00E-10 5.5
0.1 1,00E-10 5.5
0.01 1,00E-10 5.5
1 1,00E-30 6.875
0.1 1,00E-30 6.875
0.01 1,00E-30 5.75
0.001 1 3.625
0.0001 1 3.5
[4] Tasa de error resultante para α y β variable (tabla)
*He añadido dos pruebas complementarias para
conseguir el menor error posible, aumentando las
iteraciones a 100.
[5] Tasa de error resultante para α y β variable (gráfica)
La convergencia y calidad del algoritmo perceptrón
depende estrechamente de los valores de α y β. Alfa
determina la velocidad de aprendizaje, cuanto más
pequeña sea, más suave es la convergencia pero,
como contrapartida, el número de iteraciones será
mayor (pasamos de menos de 20 iteraciones para α >
0.01 a 100, por lo menos, para α < 0.001). Con una
beta suficientemente grande obtenemos buenos
resultados, se obtienen fronteras de decisión
centradas que minimizan el error de clasificación. En
nuestro caso, el algoritmo converge con lo que se
puede deducir que los conjuntos de entrenamiento
son linealmente separables (o, al menos en gran
medida).
Obtenemos entonces el mejor resultado con un factor
de aprendizaje de 0.01 y un margen de 1.
3. 3 hmm – traveller
Algoritmo: hmm
Tarea: traveller
Iteraciones: 20
Parámetros experimentales:
l = 5, 10, 15, 20, 25, 30, 35, 40
Para llevar a cabo esta última tarea he utilizado la
herramienta strclass, que clasifica las muestras
haciendo uso del algoritmo de Viterbi sobre cadenas
ocultas del modelo de Márkov. Tras ejecutar el
siguiente script:
for n in 5 10 15 20 25 30 35 40
do
./strclass -n $n traveller.tr > $n.hmm
done
obtengo 8 ficheros correspondientes al número de
estados de cada hmm (5, 10, 15, 20, 25, 30, 35, 40).
Posteriormente, con el script que mostraré a
continuación comparo cada uno de los ficheros
anteriores con los ficheros de test y obtengo la tasa
de error:
rm -r ./result;
for n in 5 10 15 20 25 30 35 40
do
echo -n "$n " >> result;
./strclass -m $n.hmm traveller.te | awk
'{if ($1!=$2) e++;} END{print(e*100/NR);}
done' >> result
done
Seguidamente, muestro los datos obtenidos, tanto en
forma de tabla [6] como en forma de gráfica [7], para
una mejor percepción:
l error (%)
5 3.55677
10 2,94118
15 3,21477
20 3,07798
25 2,66758
30 3,41997
35 3,21477
40 3,14637
[6] Tasa de error resultante para l estados variable (tabla)
[7] Tasa de error resultante para l estados variable (gráfica)
El número de estados en el algoritmo de Viterbi
depende directamente de la longitud de los datos de
aprendizaje, por lo que cuanto más largas sean las
cadenas más estados se necesitarán para
representarlo. En mi caso, tengo cadenas que van
desde 10 hasta 131 símbolos, con lo cual, es de
esperar que el número de estados esté comprendido
entre estos dos valores. Una vez tenemos un número
de estados apropiado, ampliar el número de estados
no mejorará el número de aciertos. Esto es debido a
que modelos demasiado grandes no clasifican bien
las muestras más pequeñas. Para esta tarea me quedo
entonces con un modelo oculto de Márkov de 25
estados con una tasa de error del 2.66758%, aunque
seguramente si probásemos con un número de
estados un poco mayor encontraríamos una solución
más ajustada.
Referencias
[1] Material de PoliformaT.