Sei sulla pagina 1di 12

Metaheurísticas 2017/2018

Práctica 3:
Enfriamiento Simulado, Búsqueda Local Reiteraday Evolución Diferencial para el
Problema del Aprendizaje de Pesos en Características

Luis Ramos Grosso


Grupo A1
76668859-S
luisramosgr@correo.ugr.es

1
Índice

Descripción del problema …………………………… 3

Descripción detallada de los algoritmos ……………….. 4

Breve descripción de funciones auxiliares …………. 10

Análisis de los resultados …………………………… 11

Procedimiento empleado para el desarrollo …………. 12

Utilización del código y organización de ficheros …… 13

Referencias ………………..………………..…………... 13

2
Descripción del problema

El problema del APC consiste en optimizar el rendimiento de un clasificador basado


en vecinos más cercanos a partir de la inclusión de pesos asociados a las
características del problema que modifican su valor en el momento de calcular las
distancias entre ejemplos. En nuestro caso, el clasificador considerado será el 1-NN
(k-NN, k vecinos más cercanos, con k=1 vecino). La variante del problema del APC
que afrontaremos busca optimizar tanto la precisión como la complejidad del
clasificador.

En nuestro problema, consideraremos el método de validación 5-fold cross validation


(5fcv). Para ello, el conjunto de datos se divide en 5 particiones disjuntas al 20%
manteniendo la distribución de clases. Aprenderemos un clasificador utilizando hasta
un total del 80% de los datos disponibles (4 particiones de las 5) y validaremos con el
20% restante (la partición restante), teniendo por tanto 5 particiones posibles al 80-
20%. Así, obtendremos hasta un total de cinco valores de porcentaje de clasificación
en el conjunto de prueba, uno para cada partición que ha sido parte del conjunto de
validación.

Para facilitar la comparación de algoritmos en las prácticas del APC se considerarán


cuatro estadísticos distintos denominados Tasa_clas, Tasa_red, Agregado y Tiempo:

• Tasa_clas o accuracy se calcula como la media de los porcentajes de acierto (las


tasas de clasificación) obtenidos por cada método en cada partición del conjunto de
datos (es el valor final resultante del 5fcv).

• Tasa_red o simplicidad corresponde al porcentaje de reducción obtenido en la


selección del subconjunto de características respecto al total. El cálculo se realiza con
la expresión mostrada en la sección anterior. El valor global se obtiene como la media
de los porcentajes de reducción obtenidos por cada método en cada partición del
conjunto de datos.

• Agregado o función de evaluación corresponde al valor de la función objetivo que


está optimizando el algoritmo; es decir, al valor a maximizar proveniente de la fórmula
F(W) = α · tasa_clas(W) + (1 – α)·tasa_red(W), considerando α = 0.5 en este caso.
Igualmente, se indicará el valor medio de las 5 ejecuciones 5fcv

• Tiempo se calcula como la media del tiempo de ejecución empleado por el algoritmo
para resolver cada caso del problema (cada conjunto de datos). Es decir, en nuestro
caso es la media del tiempo empleado por las 5 ejecuciones.

3
Descripción detallada de los algoritmos

Anteriores

k-NN (1-NN)

Este algoritmo de comparación sencillamente comparará los elementos de un


conjunto de training y otro de test elemento a elemento, buscando los K elementos
más cercanos a éste. En este caso y para el propósito de la práctica, k = 1.

Por motivos de eficiencia, este algoritmo ha sido modificado significativamente para la


segunda entrega y es complejo de representar (n-dimensional). Aún así, su
funcionamiento general es análogo al implementado en la primera práctica, y que se
muestra a continuación.

for elemento_test in test_set


distancia_minima = infinito

for elemento_train in training_set


distancia_temporal = distancia_euclidea(elemento_test, elemento_train)

Si distancia_minima > distancia_temporal y distancia_temporal != 0


distancia_minima = distancia_temporal

Si etiqueta_elem_test == etiqueta_elem_train
resultado_elemento = 1

En caso contrario
resultado_elemento = 0

return vector de resultado_elemento

Lo único que hace el algoritmo es usar un doble bucle for, para buscar el elemento
más cercano de training a cada uno de los de test.
Teniendo ya este resultado, el algoritmo guarda un 1 si las etiquetas de ambos
elementos coinciden, y un 0 en caso contrario.
Al final, devolvemos un vector con las soluciones de cada elemento.

Cabe destacar que este método ha sido generalizado para actuar también con pesos
y poder usarse en los otros algoritmos, y por tanto contiene un par más de parámetros
con ese fin.

4
Local Search

Este algoritmo de búsqueda busca minimizar nuestra función de evaluación mediante


la creación de soluciones vecinas a la actual (empezando por una aleatoria) y
eligiendo siempre la mejor encontrada hasta el momento.

Vector pesos ← (entrada)

aciertos = resultado de kNN con nuestros datos y pesos generados inicialmente


evaluacion_actual = función de evaluacion de nuestra solución actual
evaluacion_antigua = evaluacion_actual

nuevos_pesos = vector pesos

for iteracion in (20 veces el tamaño del vector de pesos)

Si no quedan pesos sin modificar


Todos vuelven a ser modificables

indice aleatorio = randint(tamaño del vector de modificables)


peso_actual = nuevos_pesos[indice aleatorio] + (aleatorio normal entre 0 y 1)

delete modificables[indice aleatorio]


nuevo_aciertos = resultado de kNN con nuestros datos y pesos nuevos
evaluacion_nueva = función de evaluacion de nuestra solución actual

Si evaluacion_nueva > evaluacion_antigua


evaluacion_antigua = evaluacion_nueva
pesos = nuevos_pesos
Todos vuelven a ser modificables
Si no hay cambios
break

Si se superan 1000 evaluaciones objetivo


break

return pesos

Como se puede observar, lo único que hace este algoritmo es, partiendo de una
solución inicial aleatoria, crea vecinos de esta solución mediante mutaciones
aleatorias de valores de la solución hasta encontrar una mejor.

5
Una vez que encontramos una mejor, volvemos al principio pero partiendo de dicha
solución.

Nota: Se marca en rojo una de las condiciones que se estipulan para esta práctica.

Nuevos

Simulated Annealing

sol_actual ← sol_inicial
mejor_sol ← sol_inicial

for k en numero de enfriamientos


exitos = 0

for j en maximos vecinos


vecino ← Generar vecino

if aceptamos vecino
exitos += 1
sol_actual = vecino

if sol_actual es mejor que mejor_sol


mejor_sol = sol_actual

if exitos supera a max_exitos


enfriamos
break

if no hemos enfriado en el if anterior


enfriamos

if hemos llegado a la temperatura final


break

return mejor_sol

6
Iterative Local Search

mejor_sol ← sol_inicial

for I en max_iterations
vecino ← mutation(mejor_sol)

if vecino es mejor que mejor_sol


mejor_sol = vecino

retun mejor_sol

Differential Evolution

CR = 0.5
poblacion ← poblacion inicial

for g en generaciones
for individuo_index en poblacion
padres_aleatorios = {p1, p2, p3}
k_aleatoria = {k1}

for cromosoma_index en un individuo


if random < CR or k_aleatoria == cromosoma_index
Cromosoma de hijo = Funcion_Mutacion
else
Cromosoma de hijo = Cromosoma del padre

if hijo mejor que padre


Reemplazo de padre por hijo en poblacion

if individuo es el mejor de la generacion actual


mejor_en_g = individuo

return mejor de todas las generaciones

7
Nota: Se hace referencia en el pseudo-codigo a la funcion Funcion_Mutacion, que no
existe y que pretende denotar el uso de cualquiera de las dos funciones de
mutacionion que se usan en esta practica.

Breve descripción de funciones auxiliares

Simulated Annealing

initialTemp(…)
Calcula la temperatura inicial segun la formula:

coolingScheme(…)
Determina como enfria la temperatura segun la siguiente formula:

Genera_Vecino (…)
Tal y como indica su nombre, genera -a partir de una solucion actual-, una nueva
solucion vecina mediante una mutacion normal aleatoria.

metrop (de, t)
Define el criterio de aceptacion de soluciones. Acepta cuando la nueva solucion es
mejor o si un valor aleatorio entre 0 y 1 es menor que e−de/ t , con “de” diferencia entre
evaluaciones de ambas soluciones y “t” temperatura.

Iterative Local Search

mutation(…)
Genera una solucion vecina generando aleatoriamente un numero de posiciones de
cromosomas y realizandoles mutaciones normales:

vecino = solucion_actual.copy()

pos = {x , y, z} # Posiciones aleatorias de vecino

for k en pos:

8
vecino[k] += random.normal(sigma = 0.4)

Valores de vecino < 0 → Se igualan a 0


Valores de vecino > 1 → Se igualan a 1
Differential Evolution

DE_Rand_1(…)
Genera el vector vecino segun la siguiente formula:

DE_currentToBest_1(…)
Genera el vector vecino segun la siguiente formula:

Generales

evaluateAccuracy(…)
Devuelve el valor de la tasa-clas entre 0 y 1 según los resultados obtenidos del k-NN
(teniendo en cuenta el umbral establecido para la simplicidad).

evaluateSimplicity(...)
Devuelve el valor de la tasa-red entre 0 y 1 según un valor de umbral dado para el
cual los pesos no se deberían de tener en cuenta.

evaluationFunction(...)
Devuelve el valor de la agr. (función evaluación) entre 0 y 1 según un α dado. Es
unicamente hacer la media de accuracy y simplicity.

StratifiedKFold (…)
Haciendo uso de la libreria sklearn, divide el conjunto de datos en tantas partas
iguales como queramos de forma que las proporciones se mantienen.
Una vez se hace esto, va intercambiando los conjuntos de entranamiento y test para
hacer validación cruzada, y usando dichos conjuntos en el algoritmo que se está
evaluando.

9
Análisis de los resultados

Para la obtención de los datos adjuntos se han usado los siguientes parámetros:

· Semilla aleatoria: 0
· Número de splits (cross-validation): 5
· Threshold o umbral de descarte de pesos: 0.2
· Sigma: 0.3 (0.4 para mutaciones en ILS)

Tal y como se puede ver en la tabla superior, y más detalladamente en la hoja de


cálculo adjunta a este documento, la diferencia entre los algoritmos puede llegar a ser
muy grande tanto en tiempo de ejecución como en efectividad (medida según lo
establecido).

Podemos ver cómo los algoritmos greedy de la primera práctica (fuera de la región
marcada en rojo) se van quedando muy por debajo de las soluciones de los
algoritmos mas sofisticados como los usados en esta practica. Esto se debe
principalmente a que, mientras que los greedy se centran principalmente en encontrar
la mejor solución en una región del espacio de soluciones reducido, todos estos
algoritmos intentan diversificar y explorar distintas regiones de dicho espacio.
Esta diversificación nos ayuda a salir de ciertos óptimos locales con mayor facilidad al
mismo tiempo que nos acercamos a una buena solución.

Se puede comprobar como Simulated Annealing es capaz de encontrar soluciones de


mucha calidad con una rapidez que destaca frente al resto. Un factor fundamental a
destacar es que este algoritmo es capaz de cambiar su solucion actual incluso si esta
es peor en ciertas ocasiones, lo cual ayuda a salir de optimos locales con facilidad.
El concepto de temperatura, sumado a esta diversificacion, e intensificacion cuando
nos estamos acercando a una solucion mejor, es clave para conseguir estos
resultados.

10
Aun asi, cabe destacar que pequeno cambios en la forma de determinar la
temperatura inicial o el esquema de enfriamiento pueden significar cambios
sustanciales en la calidad de este algoritmo.

Por otro lado, Iterative Local Search no deja de ser una Local Search que se repite y
“escala” las colinas hacia su pico, y por lo tanto es relativamente facil para este
algoritmo llegar a comportamientos parecidos a la Local Search simple y quedarse en
optimos locales.
Para intentar paliar algo este comportamiento, se anaden las mutaciones normales de
sigma = 0.4 en cada iteracion, pero como se puede observar en la tabla no llegan a
ser suficientes, siendo ILS el que peor resultados de agregado nos proporciona en
cualquier caso.

Por ultimo, Differential Evolution salta ya a tiempos bastante mas altos para todos los
casos, lo que no es de extranar si estamos evaluando generaciones enteras de
poblaciones repetidamente. DE es capaz de diversificar e intensificar a la vez de
forma muy efectiva. Es evidente que este comportamiento y extensivo analisis de
espacio de soluciones (con las mutaciones descritas) hacen que lleguemos las
soluciones de mayor calidad encontradas hasta ahora.

En cuanto a las dos variantes de mutaciones de DE, gana claramente “Current to


Best” si tenemos en cuenta tanto los tiempos como los resultados de agregado
finales. Esto salta a la vista como consecuencia directa de que esta mutacion es la
que utiliza el mejor vector de la generacion en el momento de mutar..

Procedimiento empleado para el desarrollo


Partiendo de la información dada en los pdf de la asignatura y lo que el profesor ha
explicar en clase, se ha intentado ir desarrollando la práctica de manera paulatina y
en orden creciente de dificultad.

Las primeras funciones desarrolladas fueron las explicadas en las transparencias


como criterios de evaluación de los resultados y mutaciones, ya que estas son
inamovibles y carecen de complejidad.

Porteriormente, se implementaron los distintos algoritmos especificados y se


analizaron los resultados obtenidos tras solventar los distintos fallos de
implementación iniciales e intentar mejorar el rendimiento.

A efectos de esto ultimo, se ha hecho uso extensivo de numpy para tratar de hacer las
cosas de forma matricial (n-dimensional) y la libreria numba, que realiza una especie
de compilacion de ciertas funciones (@jit).

11
Utilización del código y organización de ficheros

La práctica está íntegramente implementada en python, por lo que no hace falta


compilación alguna.

El código, para esta práctica, se ha dividido en tres archivos distintos (uno por cada
algoritmo).
Tan sólo se deberá abrir el código fuente del algoritmo que se quiere probar y cambiar
los parámetros que se quieran.

Referencias

Método StratifiedKFold (librería sklearn)

Uso de @jit (libreria numba)

Materiales de la asignatura (UGR)

12

Potrebbero piacerti anche