Sei sulla pagina 1di 246

ALGORITMOS GENÉTICOS APLICADOS A

LA CATEGORIZACIÓN AUTOMÁTICA DE
DOCUMENTOS

TESIS DE GRADO EN INGENIERIA


INFORMATICA

FACULTAD DE INGENIERIA
UNIVERSIDAD DE BUENOS AIRES

TESISTA: Sr. Eugenio YOLIS


DIRECTOR: Prof. Dr. Ramón GARCIA-MARTINEZ
Laboratorio de Sistemas Inteligentes
ABRIL 2003
ALGORITMOS GENÉTICOS APLICADOS A LA
CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

TESIS DE GRADO EN INGENIERIA INFORMATICA

Laboratorio de Sistemas Inteligentes

FACULTAD DE INGENIERIA
UNIVERSIDAD DE BUENOS AIRES

Sr. Eugenio Yolis Dr. Ramón García Martínez

Tesista Director

ABRIL 2003
Resumen

La categorización automática de documentos ha estado recibiendo creciente


atención debido al incremento en la cantidad de información disponible en forma
electrónica y a la necesidad cada vez mayor de encontrar la información buscada en un
tiempo mínimo. Si bien existen numerosos algoritmos para categorizar documentos,
todos ellos evaluan un subconjunto pequeño del espacio de posibles soluciones. Estea
tesis presenta un algoritmo genético adaptado al problema de categorización de
documentos. El algoritmo propuesto introduce 5 nuevos operadores, diseñados
específicamente para la resolución del problema de categorización. Los resultados
obtenidos demuestran que el algoritmo genético logra explorar el espacio de búsqueda
más amplia y eficientemente que los algoritmos previos tomados como referencia.

Palabras clave: Categorización Automática de Documentos, Algoritmos Genéticos,


Computación Evolutiva

Abstract

Automatic document clustering has been receiving increasing attention due to


the growing amount of information available in digital formats, and the importance of
finding the information required faster every day. Even though several clustering
algorithms have been developed, all of them evaluate just a small part of the solution
space. This paper presents an adaption of a genetic algorithm to the document clustering
problem. This new algoritm introduces 5 new operators, designed specifically for the
problem being solved. The obtained results show that the genetic algorithm achieves a
wider and more efficient exploration of the solution space than the previously developed
algoritms that were taken as reference.

Keywords: Automatic Document Clustering, Genetic Algorithms, Evolutionary


Computation
ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Indice

CAPÍTULO 1 ...............................................................................................................................................................7

INTRODUCCIÓN ......................................................................................................................................................7

1.1 CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS...................................................................................... 8


1.1.1 La Hipótesis del Agrupamiento.............................................................................................................8
1.1.2 Aplicaciones..............................................................................................................................................9
1.2 NATURALEZA COMBINATORIA DEL PROBLEMA DE CATEGORIZACIÓN..................................................... 10
1.3 A LGORITMOS GENÉTICOS............................................................................................................................... 11
1.4 OBJETIVO DE LA TESIS .................................................................................................................................... 11
1.5 ESTRUCTURA DE LA TESIS .............................................................................................................................. 12

CAPÍTULO 2 .............................................................................................................................................................15

ESTADO DEL ARTE..............................................................................................................................................15

2.1 CATEGORIZACIÓN DE OBJETOS...................................................................................................................... 16


2.2 REPRESENTACIÓN VECTORIAL....................................................................................................................... 16
2.2.1 Definición del “centroide” de un grupo ............................................................................................17
2.2.2 Reducción de la dimensionalidad del espacio de términos............................................................18
2.2.2.1 Reducción de palabras a su raíz ......................................................................................................... 18
2.2.2.2 Remoción de términos poco discriminantes ...................................................................................... 19
2.3 M EDIDAS DE SEMEJANZA ............................................................................................................................... 20
2.4 M ÉTODOS PARA CATEGORIZAR DOCUMENTOS............................................................................................ 23
2.5 M ÉTODOS DE CATEGORIZACIÓN INTRÍNSECOS............................................................................................ 24
2.5.1 Métodos Jerárquicos.............................................................................................................................24
2.5.1.1 Enlace simple (“single link”) ............................................................................................................. 27
2.5.1.2 Enlace completo (“complete link”).................................................................................................... 28
2.5.1.3 Enlace promedio (“average link”)...................................................................................................... 28
2.5.1.4 Método de Ward................................................................................................................................. 29
2.5.1.5 Resumen de características ................................................................................................................ 29
2.5.2 Métodos particionales...........................................................................................................................30
2.5.2.1 Selección inicial de los representantes............................................................................................... 31
2.5.2.2 Criterios de optimización................................................................................................................... 32
2.5.2.3 Algoritmos de optimización............................................................................................................... 35
2.5.2.4 Resumen de características ................................................................................................................ 37
2.6 EL ALGORITMO “BISECTING K-M EANS”...................................................................................................... 38
2.6.1 Algoritmo “Bisecting K-Means con refinamiento”..........................................................................39

Eugenio Yolis INDICE 1


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7 INTRODUCCIÓN A LOS A LGORITMOS GENÉTICOS....................................................................................... 39


2.7.1 Representación.......................................................................................................................................42
2.7.2 Generación de la población inicial.....................................................................................................44
2.7.3 Función de adaptación..........................................................................................................................44
2.7.4 Selección..................................................................................................................................................45
2.7.4.1 Selección basada en el ranking.......................................................................................................... 45
2.7.4.2 Selección por ruleta............................................................................................................................ 46
2.7.4.3 Selección por torneo........................................................................................................................... 47
2.7.5 Reproducción..........................................................................................................................................48
2.7.5.1 Cruza monopunto............................................................................................................................... 49
2.7.5.2 Cruza multipunto................................................................................................................................ 49
2.7.5.3 Cruza uniforme .................................................................................................................................. 50
2.7.6 Mutación..................................................................................................................................................51
2.7.7 Inserción de los hijos en la población................................................................................................51
2.7.7.1 Se generan tantos cromosomas como elementos en la población...................................................... 51
2.7.7.2 Se generan más cromosomas que elementos en la población ............................................................ 52
2.7.7.3 Se generan menos cromosomas que elementos en la población ........................................................ 52
2.7.8 Criterios de terminación del algoritmo genético..............................................................................53
2.7.8.1 Criterio de convergencia de identidad ............................................................................................... 53
2.7.8.2 Criterio de convergencia de aptitud................................................................................................... 53
2.7.8.3 Criterio de cantidad de generaciones ................................................................................................. 53

CAPÍTULO 3 .............................................................................................................................................................55

DESCRIPCIÓN DEL PROBLEMA ...................................................................................................................55

3.1 LA BÚSQUEDA EN EL ESP ACIO DE SOLUCIONES........................................................................................... 55


3.1.1 Problemas de los algoritmos actuales................................................................................................55
3.2 UTILIZACIÓN DE ALGORITMOS GENÉTICOS.................................................................................................. 57
3.2.1 Representación y operadores de cruza...............................................................................................58
3.2.2 Uso del conocimiento del dominio......................................................................................................58

CAPÍTULO 4 .............................................................................................................................................................61

SOLUCIÓN PROPUESTA ....................................................................................................................................61

4.1 A DAPTACIONES EXISTENTES.......................................................................................................................... 61


4.1.1 Representación.......................................................................................................................................61
4.1.1.1 Numeración de grupo......................................................................................................................... 61
4.1.1.2 Representación por matriz ................................................................................................................. 62
4.1.1.3 Permutación con separadores ............................................................................................................. 62
4.1.1.4 Permutaciónes con búsquedas locales................................................................................................ 63
4.1.2 Generación de la población inicial.....................................................................................................64
4.1.3 Función de adaptación..........................................................................................................................64

2 INDICE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.1.4 Selección..................................................................................................................................................64
4.1.5 Cruza ........................................................................................................................................................64
4.1.5.1 Cruza monopunto y multipunto......................................................................................................... 64
4.1.5.2 Cruza basada en las aristas................................................................................................................. 66
4.1.6 Mutación..................................................................................................................................................67
4.2 A LGORITMO PROPUESTO................................................................................................................................ 67
4.2.1 Representación.......................................................................................................................................67
4.2.2 Estructura del cromosoma....................................................................................................................68
4.2.3 Generacion de la población inicial.....................................................................................................68
4.2.4 Funcion de adaptación..........................................................................................................................69
4.2.5 Seleccion..................................................................................................................................................69
4.2.6 Cruza ........................................................................................................................................................70
4.2.6.1 Cruza Pasa Grupo............................................................................................................................... 70
4.2.6.2 Análisis del operador Cruza Pasa Grupo........................................................................................... 72
4.2.7 Mutación..................................................................................................................................................73
4.2.7.1 Mutación RefinarKM......................................................................................................................... 73
4.2.7.2 Mutación Refinar Selectivo ............................................................................................................... 74
4.2.7.3 Mutación Join..................................................................................................................................... 74
4.2.7.4 Mutación Split.................................................................................................................................... 75
4.2.8 Inserción de los hijos en la población................................................................................................75
4.2.9 Tamaño de la población........................................................................................................................76
4.2.10 Criterio de terminación.......................................................................................................................76
4.2.11 Algoritmo “Genético con refinamiento”.........................................................................................77

CAPÍTULO 5 .............................................................................................................................................................79

PRUEBA EXPERIMENTAL................................................................................................................................79

5.1 CONJUNTO DE DATOS UTILIZADO .................................................................................................................. 79


5.2 VARIABLES A OBSERVAR ................................................................................................................................ 81
5.2.1 Variables independientes......................................................................................................................81
5.2.2 Variables dependientes.........................................................................................................................82
5.2.2.1 Similitud promedio ............................................................................................................................ 82
5.2.2.2 Entropía.............................................................................................................................................. 83
5.2.2.3 Cantidad de operaciones .................................................................................................................... 85
5.3 REALIZACIÓN DE LOS EXPERIMENTOS.......................................................................................................... 86
5.3.1 Metodología utilizada............................................................................................................................86
5.3.1.1 Experimentos variando la cantidad de grupos ................................................................................... 86
5.3.1.2 Experimentos variando la cantidad de documentos........................................................................... 87
5.3.2 Parámetros utilizados por el algoritmo genético.............................................................................88
5.4 RESULTADOS.................................................................................................................................................... 89
5.4.1 Experimentos variando la cantidad de grupos.................................................................................89

Eugenio Yolis INDICE 3


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.4.2 Experimentos variando la cantidad de documentos........................................................................93


5.5 A NÁLISIS DE LOS RESULTADOS...................................................................................................................... 96

CAPÍTULO 6 .............................................................................................................................................................97

CONCLUSIONES ....................................................................................................................................................97

RESPUESTA A LAS CUEST IONES PLANTEADAS.................................................................................................... 97

REFERENCIAS ..................................................................................................................................................... 101

APÉNDICE 1 .......................................................................................................................................................... 109

DETERMINACIÓN DE PARÁMETROS PARA EL ALGORITMO ................................................... 109

A1.1 PARÁMETROS A DETERMINAR .................................................................................................................. 109


A1.1.1 generacionesMáximo....................................................................................................................... 109
A1.1.2 poblacionTamaño............................................................................................................................. 109
A1.1.3 torneoTamaño................................................................................................................................... 109
A1.1.4 torneoProbMejor.............................................................................................................................. 110
A1.1.5 cruzaPasaGrupoProbMejor........................................................................................................... 110
A1.1.6 mutacionRefinarKMProb................................................................................................................ 110
A1.1.7 mutacionRefinarSelectivoProb...................................................................................................... 110
A1.2 M ETODOLOGÍA UTILIZADA ....................................................................................................................... 110
A1.3 RESULTADOS............................................................................................................................................... 112
A1.3.1 generacionesMáximo....................................................................................................................... 112
A1.3.2 poblacionTamaño............................................................................................................................. 113
A1.3.3 torneoTamaño................................................................................................................................... 115
A1.3.4 torneoProbMejor.............................................................................................................................. 116
A1.3.5 cruzaPasaGrupoProbMejor........................................................................................................... 117
A1.3.6 mutacionRefinarKMProb................................................................................................................ 118
A1.3.7 mutacionRefinarSelectivoProb...................................................................................................... 119

APÉNDICE 2 .......................................................................................................................................................... 121

ANÁLISIS ESTADÍSTICO DE LOS RESULTADOS................................................................................ 121

A2.1 PRUEBA DE HIPÓTESIS ESTADÍSTICAS...................................................................................................... 121


A2.2 EL TEST DE WILCOXON PARA LA COMPARACIÓN DE MEDIAS DE MUESTRAS APAREADAS .............. 123
A2.2.1 Introducción...................................................................................................................................... 123
A2.2.2 Descripción del test.......................................................................................................................... 123
A2.3 A PLICACIÓN DEL TEST A LOS RESULTADOS............................................................................................ 125
A2.3.1 Similitud promedio........................................................................................................................... 126
A2.3.1.1 “Bisecting K-Means con refinamiento” contra “Genético” .......................................................... 126

4 INDICE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A2.3.1.2 “Bisecting K-Means con refinamiento” contra “Genético con refinamiento”.............................. 126
A2.3.2 Entropía............................................................................................................................................. 127
A2.3.2.1 “Bisecting K-Means con refinamiento” contra “Genético” .......................................................... 127
A2.3.2.2 “Bisecting K-Means con refinamiento” contra “Genético con refinamiento”.............................. 127
A2.3.3 Cantidad de operaciones................................................................................................................. 128
A2.3.3.1 “Bisecting K-Means con refinamiento” contra “Genético” .......................................................... 128
A2.3.3.2 “Bisecting K-Means con refinamiento” contra “Genético con refinamiento”.............................. 128

APÉNDICE 3 .......................................................................................................................................................... 129

MANUAL DE USO............................................................................................................................................... 129

A3.1 ESQUEMA DE PROCESAMIENTO ................................................................................................................ 130


A3.2 ESTRUCTURA DE DIRECTORIOS DEL CD.................................................................................................. 132
A3.3 CONFIGURACIÓN DEL ORI GEN DE DATOS ODBC................................................................................... 133
A3.3.1 Copiar el archivo MDB................................................................................................................... 133
A3.3.2 Agregar el origen de datos ODBC ................................................................................................ 133
A3.4 FORMATO DE LOS ARCHIVOS DE DATOS.................................................................................................. 136
A3.5 PROGRAMA “A RMAR DATASETS”............................................................................................................ 137
A3.6 PROGRAMA “AGD OC CLUS”..................................................................................................................... 139
A3.6.1 Copia del programa al disco local................................................................................................ 139
A3.6.2 Utilización del programa ................................................................................................................ 139
A3.7 PROGRAMA “EVALUAR A GRUPAMIENTOS” ........................................................................................... 141

APÉNDICE 4 .......................................................................................................................................................... 143

PROGRAMACIÓN DE LOS ALGORITMOS ............................................................................................. 143

A4.1 DESCRIPCIÓN DE LOS MÓDULOS............................................................................................................... 143


A4.1.1 Módulo “ArchivosTexto”................................................................................................................ 143
A4.1.2 Módulo “VecArchivos”................................................................................................................... 144
A4.1.3 Módulo “Agrupamiento”................................................................................................................ 144
A4.1.4 Módulo “K-Means”......................................................................................................................... 145
A4.1.5 Módulo “Genético”......................................................................................................................... 145
A4.1.6 Módulo “Principal”......................................................................................................................... 146
A4.2 CÓDIGO FUENTE.......................................................................................................................................... 147
A4.2.1 ArchivosTexto.h ................................................................................................................................ 147
A4.2.2 ArchivosTexto.cpp............................................................................................................................ 148
A4.2.3 VecArchivos.h ................................................................................................................................... 154
A4.2.4 VecArchivos.cpp............................................................................................................................... 156
A4.2.5 ClsAgrupamiento.h........................................................................................................................... 164
A4.2.6 ClsAgrupamiento.cpp...................................................................................................................... 165
A4.2.7 ClsAgrupImprime.h .......................................................................................................................... 171

Eugenio Yolis INDICE 5


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.8 ClsAgrupImprime.cpp...................................................................................................................... 172


A4.2.9 ClsKMeans.h ..................................................................................................................................... 175
A4.2.10 ClsKMeans.cpp............................................................................................................................... 177
A4.2.11 ClsGenetico.h.................................................................................................................................. 196
A4.2.12 ClsGenetico.cpp.............................................................................................................................. 199
A4.2.13 Def.h ................................................................................................................................................. 225
A4.2.14 Sis.h................................................................................................................................................... 227
A4.2.15 SisDos.h ........................................................................................................................................... 228
A4.2.16 SisDos.cpp....................................................................................................................................... 229
A4.2.17 Ppal.cpp........................................................................................................................................... 232

6 INDICE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 1
Introducción
La Categorización de Documentos (Document Clustering) puede definirse como
la tarea de separar documentos en grupos. El criterio de agrupamiento se basa en las
similitudes existentes entre ellos [Kaufmann et al., 1990]. En la bibliografía consultada,
los términos clasificación (“classification”), y categorización o agrupamiento
(“categorization” ó “clustering”), son utilizados con distinto significado [Lewis, 1991;
Yang, 1997; Maarek et. al., 2000; Clerking et. al., 2001]. El concepto de clasificación
de documentos refiere al problema de encontrar para cada documento la clase a la que
pertenece, asumiendo que las clases están predefinidas y que se tienen documentos
preclasificados para utilizar como ejemplos. En la presente tesis, se estudia la
categorización o agrupamiento de documentos, entendiéndose por ésto el proceso de
encontrar grupos dentro de una colección de documentos basándose en las similitudes
existentes entre ellos, sin un conocimiento a priori de sus características.
Un criterio de agrupamiento utilizado es dividir los documentos en una jerarquía
de temas. Un ejemplo de esto último son las categorías que presenta el buscador
Yahoo® [Rüger et. al., 2000]. Un documento en particular se podría encontrar, por
ejemplo, dentro de “Tecnología ? Informática ? Internet ? Buscadores”. El problema
que presenta esta técnica es la dificultad de encontrar la categoría que mejor describa a
un documento [Hearst et. al., 1996]. Los documentos no tratan un sólo tema, y aunque
lo hicieran, el enfoque con el que el tema es tratado puede hacer que el documento
encuadre en otra categoría. Esto hace que la categorización de documentos sea una tarea
compleja y subjetiva, ya que dos personas podrían asignar el mismo documento a
categorías diferentes, cada una aplicando un criterio válido [Macskassy et.al., 2001].
Las siguientes secciones de este capítulo dan una introducción al contenido,
objetivo y estructura de esta tesis. La sección 1.1 presenta el problema de la
categorización automática de documentos, describiendo su utilidad y las causas que han
despertado el interés por resolverlo. En la sección 1.2 se muestra la imposibilidad de
encontrar la solución al problema de categorización automática mediante una búsqueda
exhaustiva, lo que ha llevado a la creación de algoritmos que encuentran soluciones

Eugenio Yolis CAPITULO 1 - INTRODUCCION 7


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

aproximadas al problema. La sección 1.3 describe en forma breve qué son los
algoritmos genéticos, y por qué se cree que pueden aplicarse al problema en estudio. La
sección 1.4 presenta el objetivo de la tesis, y la sección 1.5, la forma en la que se
estructura su contenido en los capítulos que la componen.

1.1 Categorización automática de documentos

La tarea de encontrar grupos de documentos con características comunes no sólo


es compleja sino que además consume tiempo. Un bibliotecario que tratara de clasificar
un documento tendría que leerlo para comprender su significado para luego asignarle
una categoría utilizando su experiencia y sentido común. El costo y el tiempo asociados
a la categorización de documentos ha llevado a la investigación de técnicas que
permitan automatizar la tarea [Rüger et. al., 2000]. Debido al incremento en los
volúmenes de información disponibles en forma electrónica y a la necesidad cada vez
mayor de encontrar la información buscada en un tiempo mínimo, éstas técnicas han
estado recibiendo creciente atención [Hearst y Pedersen, 1996; Zamir y Etzioni, 1999;
Strehl et al., 2000; Maarek et al., 2000].

1.1.1 La Hipótesis del Agrupamiento

La categorización automática de documentos se comenzó a investigar dentro de


la rama de “Recuperación de Información” (en inglés , “Information Retrieval”), que es
la rama de la informática que investiga la búsqueda eficiente de información relativa a
un tema en particular en grandes volúmenes de documentación [ISO, 1993]. En su
forma más simple, las consultas están dirigidas a determinar qué documentos poseen
determinadas palabras en su contenido. Por ejemplo, la consulta “buscador internet”
podría tener por resultado todos los documentos que contengan las palabras “buscador”
e “internet” como parte de su contenido. El objetivo de las técnicas de recupero de
información es poder resolver consultas en forma eficaz y eficiente. La eficiencia viene
dada por la rapidez con la cual se resuelve la consulta. El criterio para evaluar la

8 CAPITULO 1 - INTRODUCCION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

eficacia se basa en la relevancia de los resultados encontrados [Raghavan et. al., 1989];
en el ejemplo del párrafo anterior, una búsqueda eficaz debería retornar todos los
documentos que trataran sobre la búsqueda de información en internet, aún si la palabra
“buscador” no estuviera en el contenido de los mismos.
En el contexto del recupero de información, Van Rijsbergen [Van Rijsbergen,
1979] formula la denominada “Hipótesis del Agrupamiento” (en inglés, “Cluster
Hypothesis”); básicamente, la hipótesis del agrupamiento sostiene que “los documentos
fuertemente asociados tienden a ser relevantes para la misma consulta”, lo cual ha sido
verificado experimentalmente [Cutting et. al., 1992; Schütze et. al.,1997; Zamir et. al.,
1999]; basándose en dicha hipótesis, la categorización automática tiene en cuenta el
contenido de los documentos para agruparlos, ya que documentos similares contendrán
palabras (términos) similares.

1.1.2 Aplicaciones

La categorización automática de documentos se investiga dentro del campo del


recupero de información como una herramienta capaz de mejorar la calidad de las
soluciones ofrecidas. Sus aplicaciones más importantes son:
- Mejorar el rendimiento de los motores de búsqueda de información mediante la
categorización previa de todos los documentos disponibles [Van Rijsbergen, 1979;
Dunlop y Van Rijsbergen, 1991; Faloutsos y Oard, 1995; Zamir et. al., 1999; Rüger et.
al., 2000]. Antes de comenzar a resolver las consultas, el conjunto de documentos es
separado en grupos. A cada grupo de documentos se le asigna un “representante de
grupo”; luego, al resolver una consulta, no se examinan todos los documentos, sino que
se busca el “representante de grupo” que mejor responda a la consulta. Por la hipótesis
del agrupamiento, el grupo encontrado estará compuesto de los documentos más
relevantes para esa búsqueda.
- Facilitar la revisión de resultados por parte del usuario final, agrupando los
resultados luego de realizar la búsqueda [Croft, 1978; Cutting et al., 1992; Allen et al.,
1993; Leousky y Croft, 1996; Maarek et al., 2000]. Cuando se realizan búsquedas sobre
un gran volumen de documentos, la cantidad de resultados puede ser muy grande. Si la

Eugenio Yolis CAPITULO 1 - INTRODUCCION 9


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

lista se presenta sin ningún tipo de procesamiento previo, el usuario del sistema se verá
obligado a revisar todos los documentos descartando aquellos que no son relevantes
para él. Si los resultados se agrupan, la hipótesis del agrupamiento indica que los
documentos del mismo grupo serán relevantes para una subconsulta más específica que
la original. De esta forma, los documentos quedarán separados en grupos temáticos (los
grupos son una división de los documentos originales, y cada grupo responde a una
subconsulta más específica dentro del tema buscado) [Rüger et. al., 2000]. Asi, con sólo
revisar uno o dos documentos de cada grupo, el usuario podrá determinar cuál es el
subtema al que responden todos los documentos del grupo, pudiendo descartar
rápidamente los documentos irrelevantes para su búsqueda.

1.2 Naturaleza combinatoria del problema de


categorización

Una de las características principales del problema de la categorización de


documentos es su naturaleza combinatoria [Duran y Odell, 1974; Pentakalos et al.,
1996]. La teoría combinatoria [Liu, 1968] indica que S(n,K), la cantidad de maneras de

1 K K 
agrupar n objetos en K grupos, está dada por: S ( n, K ) = ∑ (−1)i  (K − i )n .
K ! i =0 i 
Utilizando esta fórmula puede calcularse, por ejemplo: S (25,5) = 2 x 1016 , o,
dicho en otras palabras, que hay más de dos mil millones de millones de formas de
agrupar 25 objetos en 5 grupos. Los 25 objetos del ejemplo, representan un problema de
dimensiones demasiado pequeñas para ser de utilidad. En la práctica, se querría aplicar
la categorización automática, por lo menos, a varios cientos de documentos. Sin
embargo, haciendo algunos cálculos sobre este ejemplo de dimensiones pequeñas,
puede comprenderse la complejidad del problema. Supóngase un algoritmo que intente
probar todas las posibles categorizaciones para encontrar la mejor de ellas, asignandoles
puntajes de acuerdo a un criterio predefinido. Suponiendo que el algoritmo consiga
calcular el puntaje de 100 mil soluciones por segundo (el algoritmo tendría que ser muy
rápido, pero supóngase que lo es), para probar las 2 x 1016 posibilidades, el algoritmo
tomaría más de 6 mil años en dar el resultado.

10 CAPITULO 1 - INTRODUCCION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Un algoritmo que evalúe cada una de las posibles categorizaciones no es


aplicable en forma práctica a la categorización automática de documentos, por lo que se
han desarrollado algoritmos que hacen uso de heurísticas [Cutting et al., 1992; Zamir et.
al., 1999; Jain et.al., 1999; Estivill-Castro, 2000; Zhao et.al., 2001] para explorar una
parte de estas posibles categorizaciones buscando una solución de calidad aceptable.

1.3 Algoritmos genéticos

Los algoritmos genéticos son una técnica del área de Sistemas Inteligentes que
constituye una abstracción del concepto biológico de evolución natural y tiene
numerosas aplicaciones en problemas de optimización [Davis, 1991; Falkenauer, 1999].
Su funcionamiento está basado en los mecanismos de selección natural, combinando la
supervivencia del más apto con un intercambio de información entre miembros de una
población de posibles soluciones.
Se estima que el uso de algoritmos géneticos puede contribuir a acortar
significativamente los tiempos de resolución del problema [Raghavan y Birchard, 1978;
Johnson y Fotouhi, 1996; Cole, 1998; Painho y Bação, 2000], ya que se caracterizan por
su capacidad de explorar el espacio de búsqueda amplia y eficientemente [Goldberg,
1989; Koza, 1997].

1.4 Objetivo de la tesis

En este contexto, el objetivo de esta tesis es estudiar cómo pueden aplicarse los
algoritmos genéticos, que han demostrado ser útiles para ayudar a resolver problemas de
optimización, al problema de encontrar en forma automática la mejor categorización de
documentos. Se estudiará de qué forma las características de los algoritmos genéticos
pueden utilizarse para diseñar un algoritmo que supere el rendimiento de los algoritmos
que actualmente se aplican al problema, y se evaluarán los resultados de acuerdo a la
calidad de las soluciones obtenidas.

Eugenio Yolis CAPITULO 1 - INTRODUCCION 11


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

1.5 Estructura de la tesis

La tesis se divide en seis capítulos y cuatro apéndices.


El capítulo 2 describe el estado actual de los campos de estudio relacionados con
esta tesis. La sección 2.1 define formalmente el problema de la categorización
automática de documentos. La categorización automática de documentos se vincula con
las ciencias de la “Recuperación de Información” y de la “Minería de Datos”. Del
campo de la Recuperación de Información toma los conceptos y métodos utilizados para
el procesamiento de documentos. Estas técnicas son las que permiten transformar la
información no estructurada que contienen los documentos (llamados “documentos de
texto libre”, o en inglés “free text documents”), a estructuras de datos manejables
mediante algoritmos computacionales. Las secciones 2.2 y 2.3 describen estas técnicas.
Del campo de la Minería de Datos toma las técnicas que se ocupan de los problemas de
categorización de objetos. Los algoritmos utilizados para la categorización automática
de documentos son adaptaciones de los que se utilizan para el problema más general de
categorizar objetos de cualquier tipo. La sección 2.4 muestra la ubicación de la
categorización automática de documentos dentro de este área, y detalla los algoritmos
utilizados actualmente para categorizar documentos en forma automática. En la sección
2.6 se describe un algoritmo presentado recientemente, que supera a los métodos
clásicos, y contra el cual se comparará la solución propuesta en esta tesis. La sección 2.7
presenta los principios básicos de los algoritmos genéticos, en los que se basará el
algoritmo de categorización presentado en esta tesis.
El capítulo 3 plantea las cuestiones que esta tesis apunta a responder, y analiza el
trabajo previo que existe acerca de la aplicación de los Algoritmos Genéticos a este
problema. En la sección 3.1 se exponen las limitaciones que presentan los algoritmos
actuales, relacionados con la forma en la que exploran el espacio de posibles soluciones.
La sección 3.2 describe los problemas encontrados en los trabajos previos que aplicaron
los algoritmos genéticos a la categorización automática.
En el capítulo 4 se presenta la solución propuesta en esta tesis, que apunta a
responder a las cuestiones planteadas en el capítulo 3. En la sección 4.1 se describen las
técnicas utilizadas en trabajos previos que aplican los algoritmos genéticos a problemas
de categorización automática. La sección 4.2 detalla el algoritmo de categorización

12 CAPITULO 1 - INTRODUCCION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

propuesto. Este algoritmo emplea algunas de las técnicas descriptas en la sección 4.1,
pero su característica principal es la utilización de los nuevos operadores que se
presentan en esta tesis.
El capítulo 5 describe las pruebas que se realizaron para evaluar la efectividad de
la solución propuesta en el capítulo 4. La sección 5.1 describe los conjuntos de datos
utilizados. Los mismos fueron extraídos de una colección reconocida como un estándar
dentro de la comunidad de investigadores dedicados a la categorización automática de
documentos. En las secciones 5.2 y 5.3 se detalla la metodología seguida en la
experimentación. Se enumeran las variables que intervienen en los experimentos y los
distintos tipos de experimentos realizados. La sección 5.4 presenta los resultados de la
experimentación. La presentación se hace en forma de gráficos y para cada variable se
incluye además el resultado del test estadístico realizado sobre los resultados. En la
sección 5.5 se analizan brevemente los resultados, que luego se tratan con más detalle
en el capítulo 6.
El capítulo 6 presenta las conclusiones extraídas a partir de la investigación
realizada y los resultados experimentales obtenidos. En esta tesis se propone una
adaptación de un algoritmo genético al problema de la categorización automática de
documentos, que incluye el diseño de un nuevo operador de cruza y cuatro operadores
de mutación. Los resultados experimentales obtenidos confirman la tesis que los
algoritmos genéticos son una poderosa herramienta para la resolución de problemas en
los cuales el espacio de soluciones es amplio y la función de optimización es compleja.
En el apéndice 1 se describen las pruebas realizadas para obtener los parámetros
utilizados en el algoritmo propuesto.
El apéndice 2 detalla el análisis estadístico realizado sobre los resultados que se
exponen en el capítulo 5, y que soportan las afirmaciones realizadas en la sección 5.4
(“Resultados”) de ese capítulo.
El apéndice 3 contiene la documentación de los programas y conjuntos de datos
que se incluyen en el CD que acompaña la presente tesis. Estos programas hacen
posible la realización de los experimentos y la evaluación de los resultados.
El apéndice 4 detalla la forma en la que se programaron los algoritmos
comparados en la prueba experimental. Para realizar la prueba experimental, se
desarrolló una aplicación de categorización automática de documentos que permite

Eugenio Yolis CAPITULO 1 - INTRODUCCION 13


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

seleccionar qué algoritmo se quiere utilizar. El desarrollo de la aplicación se realizó en


el lenguaje C++. La sección A4.1 contiene la descripción de los distintos módulos en
los que se separó la lógica del algoritmo y la interacción que existe entre los mismos. En
la sección A4.2 se incluye el código fuente de cada módulo.

14 CAPITULO 1 - INTRODUCCION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 2

Estado del arte

Este capítulo describe el estado actual de los campos de estudio relacionados con
esta tesis. La sección 2.1 define formalmente el problema de la categorización
automática de documentos.
La categorización automática de documentos se vincula con las ciencias de la
“Recuperación de Información” y de la “Minería de Datos”. Del campo de la
Recuperación de Información toma los conceptos y métodos utilizados para el
procesamiento de documentos. Estas técnicas son las que permiten transformar la
información no estructurada que contienen los documentos (llamados “documentos de
texto libre”, o en inglés “free text documents”), a estructuras de datos manejables
mediante algoritmos computacionales. Las secciones 2.2 y 2.3 describen estas técnicas.
Del campo de la Minería de Datos toma las técnicas que se ocupan de los
problemas de categorización de objetos. Los algoritmos utilizados para la
categorización automática de documentos son adaptaciones de los que se utilizan para el
problema más general de categorizar objetos de cualquier tipo. La sección 2.4 muestra
la ubicación de la categorización automática de documentos dentro de este área, y
detalla los algoritmos utilizados actualmente para categorizar documentos en forma
automática.
En la sección 2.6 se describe un algoritmo presentado recientemente, que supera
a los métodos clásicos, y contra el cual se comparará la solución propuesta en esta tesis.
La sección 2.7 presenta los principios básicos de los algoritmos genéticos, en los que se
basará el algoritmo de categorización presentado en esta tesis.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 15


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.1 Categorización de objetos

La categorización de documentos es un tipo de problema perteneciente a la


familia de problemas asociados a encontrar agrupamientos entre objetos de cualquier
tipo. Si bien la categorización de documentos tiene características particulares que
surgen de las propiedades de los documentos como objetos a agrupar, los principios
generales coinciden con los que se aplican para categorizar cualquier otro tipo de
elementos. Los algoritmos para la categorización automática de documentos son los
mismos que se utilizan para agrupar otros tipos de objetos, o adaptaciones de éstos [Qin
He, 1996; Cole, 1998; Fasulo, 1999; Jain et.al., 1999].
Una definición del problema del agrupamiento de documentos (que es aplicable
al agrupamiento de cualquier tipo de elementos), puede enunciarse de la siguiente
manera [Zhao et.al., 2001]:

Dado un conjunto S, de N documentos, se quiere encontrar la


partición S1 , S2 , ..., Sk, tal que cada uno de los N documentos se encuentre
sólamente en un grupo Si, y que cada documento sea más similar a los
documentos de su mismo grupo que a los documentos asignados a los
otros grupos.

2.2 Representación vectorial

Para poder definir medidas de semejanza entre los objetos a agrupar, éstos se
representan mediante vectores v = (a1 , a2 , ... , am ), donde cada componente del vector
es el valor de un atributo del objeto. De esta forma, cada uno de los objetos a agrupar es
un punto en un Espacio Euclideano de m dimensiones, Rm. Los investigadores
dedicados a las ramas de la Recuperación de Información adoptaron tempranamente una
representación vectorial para el manejo de documentos [Van Rijsbergen, 1979]; en este
modelo, cada documento es considerado un vector d en el espacio de términos (el
conjunto de palabras que aparecen en por lo menos uno de los documentos de la
colección).

16 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Una forma aceptada [Van Rijsbergen, 1979; Faloutsos et.al., 1995; Jones et.al.,
1995] de representar los documentos es asignar a cada atributo del vector la presencia o
ausencia del término correspondiente. De esta manera, para m términos el vector
consistiría en m atributos binarios que pueden tomar valores de cero o uno, según los
términos que aparezcan o no en el documento. Otra manera es representar a cada
documento por su vector de frecuencia de términos [Steinbach et.al., 2000]: dtf = ( tf1 ,
tf 2 , ... , tf m ), donde tf i es la frecuencia del término número i en el documento (cantidad de
veces que aparece esa palabra en el documento). De esta forma, se considera que los
documentos quedan caracterizados por la cantidad de veces que aparece cada término
dentro del mismo.
Un refinamiento de este modelo consiste en multiplicar a la frecuencia de cada
término por su “frecuencia documental inversa” (en inglés, “inverse document
frecuency”). Ésta técnica, denominada “tf-idf”, se basa en la premisa que si un término
aparece en gran parte de los documentos, es poco discriminante, y por lo tanto, debe
restársele importancia [Faloutsos et.al., 1995; Zhao et.al., 2001]. Asi, la representación
del documento resultaría: dt f-idf = ( tf1 log(N / df1 ) , tf2 log(N / df2 ) , ... , tfm log(N / dfm) ),
donde N es la cantidad total de documentos de la colección y df i es la cantidad de
documentos que contienen al término i.
La normalización de los vectores (|| d || = 1) asegura que los documentos se
evalúen por la composición de su contenido, sin tener en cuenta su tamaño, ya que en
los documentos más extensos, las frecuencias de aparición de los términos serán
mayores.

2.2.1 Definición del “centroide” de un grupo

La definición de “centroide” de un grupo de elementos representados


vectorialmente es utilizada en el contexto de los algoritmos de agrupamiento. Dado un
grupo de elementos S, que contiene h elementos si, se define a su centroide Cs como el
h

∑s i
promedio de los vectores que componen el grupo: Cs = i =1
. Cada componente del
h
vector centroide es el promedio del valor de esa componente para los miembros del

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 17


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

grupo [Steinbach et.al., 2000; Zhao et.al., 2001]; su propiedad más importante es que la
distancia promedio desde un punto cualquiera del espacio hasta cada elemento del grupo
es igual a la distancia entre ese punto y el centroide del grupo.

2.2.2 Reducción de la dimensionalidad del espacio de términos

Es evidente que en una colección de documentos aparecerán cientos o miles de


palabras distintas. Cómo la dimensión del espacio vectorial de representación está dada
por la cantidad de palabras diferentes, cada vector contendrá cientos o miles de
componentes (gran parte de ellas con valor igual a cero) [Zervas et al., 2000]. Esto es
conocido como la “maldición de la dimensionalidad” (en inglés “the curse of
dimensionality”) [Yang et al., 1997]. Hay dos técnicas que se utilizan para reducir la
dimensionalidad del espacio de términos: la reducción de palabras a su raíz, y la
remoción de los términos poco discriminantes.

2.2.2.1 Reducción de palabras a su raíz

Para reducir el número de términos distintos con los que se trabaja, el primer
paso es reducir todas las palabras a su raíz (en inglés “steeming”). Por ejemplo, las
palabras “medicina”, “médico” y “medicinal” se reducen a la forma “medic”. Esta
técnica es llamada “remoción de sufijos” (en inglés “suffix stripping”). Si bien es
posible que de esta manera se lleven a la misma raíz palabras que en realidad tienen
significados distintos, en general las palabras que tienen la misma raíz refieren al mismo
concepto, y la pérdida de precisión es compensada por la reducción de la
dimensionalidad del espacio [Van Rijsbergen, 1979].
Las aplicaciones de agrupamiento de documentos usan técnicas de remoción de
sufijos [Krovetz, 1993; Zamir et.al., 1998; Steinbach et.al., 2000], existiendo consenso
en cuanto a la conveniencia de su aplicación. La técnica de remoción de sufijos más
utilizada es la llamada “regla de Porter” [Porter, 1980]; esta técnica se basa en un
algoritmo que aplica una serie de reglas que determinan si las últimas sílabas de una
palabra deben ser removidas.

18 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.2.2.2 Remoción de términos poco discriminantes

Otro método para reducir la dimensión del espacio de términos (que es


complementario del anterior), es el de descartar los términos que se consideran poco
discriminantes [Yang et al., 1997]. Un término es poco discriminante si el hecho de
saber que ese término se encuentra en un documento nos dice poco (o nada), acerca del
posible contenido o tema del documento. El ejemplo más simple de dichos términos son
las preposiciones, artículos y toda otra palabra auxiliar que ayude a dar forma a las
oraciones. Éstas palabras se consideran poco discriminantes en cualquier colección
documental con la cual se trabaje, por lo que se utiliza una lista de palabras irrelevantes
(en inglés, “stop list”) y se descartan todas las palabras que aparecen en esa lista [Van
Rijsbergen, 1979; Strehl et.al., 2000].
Existen términos que pueden ser discriminantes dependiendo del conjunto de
documentos con los que se trabaje. Para una colección de documentos determinada,
entre sus términos habrá algunos más útiles que otros para la tarea de categorización.
Por ejemplo, si en una serie de documentos sobre física cuántica, el término “electrón”
aparece en el 98% de los documentos, es evidente que la presencia o ausencia de ese
término no es relevante a los efectos de agrupar los mismos. De la misma forma, si
dentro de ese grupo de documentos, la palabra “arcoiris” aparece solamente en uno de
ellos, ese término tampoco será importante para agruparlos.
En [Yang et al., 1997] se exponen diversas técnicas orientadas a detectar, en una
colección de documentos, qué términos son irrelevantes para la tarea de categorización.
Algunas de ellas requieren un pequeño grupo de documentos previamente
categorizados, para ser utilizados como un conjunto de entrenamiento, por lo que a
veces su aplicación puede no ser posible. A continuación se describe brevemente cada
una de las técnicas analizadas.
a) Umbral de frecuencia documental
Es el método más sencillo. Se calculan las frecuencias con que aparece cada
término en la colección documental y los términos que no superan cierto umbral
mínimo son descartados. Se asume que las palabras muy poco frecuentes no contienen
información sobre la categoría a la que pertenece el documento, o que son términos
“ruidosos” (que pueden llegar a confundir al algoritmo de agrupamiento).

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 19


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

b) Ganancia de información, Información mutua, Estadística X2


Teniendo un conjunto de documentos ya agrupados, para cada término se calcula
(en base a fórmulas probabilísticas) qué tan bueno es para predecir la categoría a la que
pertenece el documento. El puntaje más alto es obtenido por aquellos términos presentes
en todos los documentos de una categoría y que no aparecen en ningun documento de
las demás categorías. Los términos con puntaje más bajo (que son aquellos que aparecen
por igual en documentos de todas las categorías) son descartados. Los tres métodos
difieren en la forma de calcular los puntajes y normalizar los resultados.
c) Fuerza del término
Usando un grupo de documentos de entrenamiento, se toman aquellos pares de
documentos cuya semejanza excede un determinado valor (parámetro del método). Para
cada término, se cuenta la cantidad de veces que el mismo aparece en ambos
documentos de cada par. En base a eso, se calcula la probabilidad de que el término esté
en el segundo documento del par, sabiendo que está en el primero. Se asignan puntajes
más altos cuanto mayor sea esa probabilidad, asumiendo que el término es descriptivo
de la categoría de esos documentos.

El análisis comparativo [Yang et al., 1997], usando cada uno de los métodos de
remoción de términos para diferentes algoritmos de agrupamiento, llega a la conclusión
de que las técnicas de Umbral de frecuencia, Ganancia de información y Estadística X2
obtienen resultados similares, notando que el método de Umbral de frecuencia no
requiere documentos previamente clasificados, lo que amplía el rango de situaciones en
las que puede ser aplicado.

2.3 Medidas de semejanza

En la definición del problema de agrupamiento, se dijo: “...que cada documento


sea más similar a los documentos de su mismo grupo, que a los documentos asignados a
los otros grupos...” (los términos “similar”, “semejante” y “cercano” se utilizan
indistintamente para referirse a éste concepto). Para poder evaluar esta condición, es
necesario definir una medida cuantitativa de la similitud existente entre dos
documentos.

20 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

En el modelo de representación más sencillo, en el que los atibutos del vector


son valores binarios, y definiendo | v | como la cantidad de atributos de v que toman el
valor 1, las medidas más comunes son:
- Coeficiente de Jaccard
d1 ∩ d 2
d1 ∪ d 2

- Coeficiente del coseno

d1 ∩ d 2
d1 ∗ d2

Ambas medidas definen el concepto de semejanza de los documentos por la


cantidad de términos en común que contienen en relación al tamaño de los documentos.
En el modelo de representación más utilizado [Qin He, 1996; Maarek et.al.,
2000; Steinbach et.al., 2000], en el cual se calculan los vectores de frecuencia o de
frecuencia inversa, y siendo ||v|| la longitud (norma) del vector v, las medidas más
comunes son [Cole, 1998; Strehl et.al., 2000; Zhao et.al., 2001]:
- Coeficiente del coseno extendido

d1 • d 2
cos(d1 , d 2 ) =
d1 ∗ d 2

Es una extensión del correspondiente del modelo binario para el caso de


atributos con valores reales. Esta medida tiene la propiedad de no depender del tamaño
de los documentos, ya que cos(d1 ,d2 ) = cos(a.d1 ,d2 ) para a > 0. Sin embargo, los
documentos se normalizan para que tengan longitud unitaria, ya que entonces,

cos(d1 , d 2 ) = d1 • d2

Y la semejanza entre los documentos se puede calcular como el producto


vectorial entre ellos.
La similitud queda comprendida en el intervalo [0,1]. Para un documento
cualquiera, el vector que lo representa es un punto en el espacio. Si se traza la recta que
definen ese punto y el eje de coordenadas, todo documento que se encuentre sobre la

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 21


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

recta tiene similitud 1 con el documento que la define. Si se trazan hiperconos


concéntricos cuyo eje sea esa recta, la semejanza irá decreciendo a medida que se
agranda el ángulo del hipercono, y todos los documentos situados en la pared de cada
hipercono tienen la misma similitud con el documento que define el eje. La semejanza
igual a cero se alcanza cuando el hipercono se convierte en el hiperplano perpendicular
al eje que define el documento [Strehl et.al., 2000].
- Coeficiente de Jaccard extendido

d1 • d 2
jac( d 1 , d 2 ) =
+ d 2 − ( d1 • d 2 )
2 2
d1

Es una extensión del coeficiente de Jaccard del modelo binario para el caso de
atributos con valores reales. Los valores posibles de similitud se encuentran en el rango
[0,1]. Esta medida tiene propiedades intermedias entre el coeficiente del coseno
extendido y la distancia Euclideana, que se detalla a continuación.
- Distancia Euclideana

dist _ euc( d 1 , d 2 ) = d 1 − d 2

Es la fórmula tradicional para calcular el tamaño del segmento que une dos
puntos. La semejanza de dos documentos queda definida en forma inversa, ya que los
documentos más similares serán los que estén a menor distancia. La fórmula
comunmente utilizada es:

1
euc( d 1 , d 2 ) =
1 − d1 − d 2

Los posibles valores de similitud están en el rango [0,1], pero un documento


tiene semejanza igual a 1 sólamente consigo mismo. Para un documento cualquiera, el
vector que lo representa es un punto en el espacio. Si se trazan hiperesferas concéntricas
alrededor del punto, todos los documentos ubicados en la superficie de una hiperesfera
tienen el mismo valor de similitud con el documento que define el centro. La semejanza
decrece a medida que aumenta el radio de las hiperesferas.

22 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

En el campo de la categorización automática de documentos, la medida más


utilizada es el coeficiente del coseno extendido [Cutting et.al., 1992; Qin He, 1996;
Steinbach et.al., 2000; Zhao et.al., 2001]. Se ha realizado [Strehl et.al., 2000] un
análisis completo de las medidas expuestas anteriormente, comparando el rendimiento
de distintos algoritmos de agrupamiento utilizando cada una de las medidas de
similitud, llegando a la conclusión de que los coeficientes del coseno y Jaccard
extendidos son más apropiados que la distancia euclideana para espacios de gran
dimensionalidad y con datos dispersos, como es el caso del agrupamiento de
documentos.

2.4 Métodos para categorizar documentos

Las formas de clasificación de objetos, tales como asignar clases


predeterminadas a cada elemento ó agruparlos en forma significativa, son susceptibles
de dividirse según el esquema de la figura 2.1 [Qin He, 1996]:

Clasificaciones

No exclusivas Exclusivas

Extrínsecas Intrínsecas

Fig 2.1
División de las formas de
Jerárquicas Particionales
clasificar objetos

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 23


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

- No exclusivas : Un mismo objeto puede pertenecer a varias categorías, clases o


grupos.
- Exclusivas : Cada objeto pertenece solamente a una categoría, clase o grupo.

- Extrínsecas (supervisadas) : Las clases a las que pertenecen los objetos están
predefinidas, y se conocen ejemplos de cada una, ó algunos de los objetos ya
están clasificados y son utilizados por el algoritmo para aprender a clasificar a
los demás.
- Intrínsecas (no supe rvisadas) : La clasificación se realiza en base a las
características propias de los objetos, sin conocimiento previo sobre las clases a
las que pertenecen.

- Jerárquicas : Los métodos jerárquicos consiguen la categorización final


mediante la separación (métodos divisivos) o la unión (métodos aglomerativos)
de grupos de documentos. Así, estos métodos generan una estructura en forma
de árbol en la que cada nivel representa una posible categorización de los
documentos [Willet, 1998]
- Particionales (no jerárquicas) : Los métodos no jerárquicos, tambien
llamados particionales, o de optimización llegan a una única categorización que
optimiza un criterio predefinido o función objetivo, sin producir una serie de
grupos anidados [Everitt, 1993].

La categorización automática de documentos se encuentra en la categoría


“intrínseca”, ya que los criterios de agrupamiento se basan en la información contenida
en los mismos para determinar sus similitudes

2.5 Métodos de categorización intrínsecos


2.5.1 Métodos Jerárquicos

Los algoritmos jerárquicos se caracterizan por generar una estructura de árbol


(llamada “dendograma”), en la que cada nivel es un agrupamiento posible de los objetos

24 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

de la colección [Jain et.al., 1999]. Cada vértice (nodo) del árbol es un grupo de
elementos. La raíz del árbol (primer nivel) se compone de un sólo grupo que contiene
todos los elementos. Cada hoja del último nivel del árbol es un grupo compuesto por un
sólo elemento (hay tantas hojas como objetos tenga la colección). En los niveles
intermedios, cada nodo del nivel n es dividido para formar sus hijos del nivel n + 1.
Las figuras 2.2 y 2.3 ilustran estos conceptos mediante un ejemplo simple.

F
C
A
D
E

Fig 2.2
B
Posible colección de objetos en
un espacio de 2 dimensiones

ABCDEF

A C E F B D

A C E F B D

A E F C B D

A E F C B D

A E F C B D

A E F C B D

Fig 2.3. Posible dendograma para la colección de la figura 2.2 y agrupamientos que representa
cada nivel.

Los algoritmos de agrupamiento jerárquicos fueron uno de los primeros


enfoques para los problemas de categorización de documentos, y todavía se siguen
utilizando debido a la forma simple e intuitiva en la que trabajan [Dash et.al., 2001]. De
acuerdo a la metodología que aplican para obtener el dendograma, los algoritmos
jerárquicos pueden dividirse en aglomerativos y divisivos [Han, 2001].

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 25


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Los métodos aglomerativos parten de las hojas del árbol, ubicando a cada
elemento en su propio grupo, y en cada paso buscan los dos grupos más cercanos para
juntarlos. Los divisivos, por su parte, hacen el camino inverso. Comenzando en la raíz,
en cada paso seleccionan un grupo para dividirlo en dos, buscando que el agrupamiento
resultante sea el mejor de acuerdo a un criterio predeterminado. El análisis necesario
para pasar de un nivel a otro (decidir qué grupo dividir o cuales juntar) es más sencillo
para los métodos aglomerativos [Dash et.al., 2001], y esto hace que éstos sean más
utilizados que los divisivos [Fasulo, 1999; Steinbach et.al., 2000]. En adelante, cuando
se hable de métodos jerárquicos, se hará referencia únicamente a los algoritmos de
Agrupamiento Jerárquico Aglomerativo (HAC, su sigla en inglés).
Las distintas variantes de algoritmos jerárquicos aglomerativos difieren
únicamente en la manera de determinar la semejanza entre los grupos al seleccionar los
dos grupos más cercanos [Qin He, 1996; Willet, 1998; Cole, 1998; Jain et.al., 1999;
Fasulo 1999]. Debe notarse la diferencia entre medidas de semejanza entre documentos
y medidas de semejanza entre grupos. La similitud de dos grupos se calcula en base a
los valores de semejanza existentes entre sus documentos, pero la forma de hacer este
cálculo no es única. Dada una medida de semejanza entre documentos, que puede
considerarse la misma para todos, los distintos algoritmos jerárquicos aglomerativos se
distinguen por la medida de semejanza entre grupos que utiliza cada uno.
La figura 2.4 presenta un espacio bidimensional en el cual se han colocado 4
grupos de objetos. Los objetos de un mismo grupo se han representado mediante el
mismo símbolo (x, *, # ó +).

x
*
+ x *
+ *
+ x ** *
*
** *
x *
*
#

#
Fig 2.4
#
# Cuatro grupos de objetos en un
#
espacio de 2 dimensiones

26 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Las figuras 2.5, 2.6 y 2.7 muestran cómo los métodos pueden diferir entre ellos
al seleccionar cuáles son los grupos más semejantes. En las figuras se utiliza la distancia
Euclideana como medida de semejanza entre los documentos. La disposición presentada
de los grupos se ha elegido especialmente para provocar las diferencias, si los grupos
están suficientemente separados y son compactos todos los métodos coinciden en la
selección de los grupos más cercanos.

2.5.1.1 Enlace simple (“single link”)


El método de enlace simple, también llamado “del vecino cercano” (en inglés
“nearest neighbour”), calcula la semejanza entre dos grupos como la semejanza entre
los dos elementos más cercanos de ambos (ver figura 2.5). Este método es eficaz cuando
los grupos tienen formas irregulares, pero es muy sensible a la existencia de elementos
dispersos que no forman parte de ningún grupo definido, llevando a la creación de
grupos alargados, compuestos de objetos disímiles [Cole, 1998; Karypis et.al., 1999].
Éste efecto recibe el nombre de “encadenamiento”.

x
*
+ x *
+ *
+ x ** *
*
** *
x * Fig 2.5
*
# Distancias al grupo de las “ x “

# según el método de enlace simple.

# La distancia entre los grupos más


#
# cercanos está remarcada.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 27


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.5.1.2 Enlace completo (“complete link”)


En el extremo opuesto del método de enlace simple se encuentra el método de
enlace completo, que calcula la semejanza entre dos grupos usando la semejanza de los
dos elementos más lejanos (ver figura 2.6). De esta manera, el método no sufre del
efecto de “encadenamiento”, y encuentra con eficacia grupos pequeños y compactos.
Sin embargo, cuando los grupos no están bien definidos, puede llevar a la creación de
grupos sin significado.

x
*
+ x *
+ *
+ x ** *
*
** * Fig 2.6
x *
* Distancias al grupo de las “ x “
#
según el método de enlace
#
completo. La distancia entre los
#
# grupos más cercanos está
#
remarcada.

2.5.1.3 Enlace promedio (“average link”)


A mitad de camino entre los dós métodos anteriores, el algoritmo de enlace
promedio define a la semejanza entre dos grupos como el promedio de las semejanzas
de cada miembro de uno con cada miembro del otro (ver figura 2.7). Al tomar
propiedades de los métodos de enlace simple y completo, éste algoritmo obtiene
resultados aceptables en un rango de situaciones más amplio [Cole, 1998].

x
*
+ x *
+ *
+ x ** *
*
** * Fig 2.7
x *
* Distancias al grupo de las “ x “
#
según el método de enlace
#
promedio. La distancia entre los
#
# grupos más cercanos está
#
remarcada.

28 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.5.1.4 Método de Ward


Este método define la “suma de errores cuadrados” como la suma del cuadrado
de la distancia de cada objeto al centroide de su grupo. Así, para un grupo de elementos
S, compuesto por h elementos si y cuyo centroide es Cs:

h
Ws = ∑ || si − C s || 2
i =1

Y, para un agrupamiento de k grupos:

k
W = ∑ Wi
i =1

Al comenzar el algoritmo, la suma de errores cuadrados vale cero, ya que cada


elemento forma su propio grupo y coincide con el centroide. En cada paso, el método
evalúa cada una de las posibles uniones y elige aquella que produce el menor
incremento del error. Este método tiende a producir grupos de tamaños iguales, y su
rendimiento es comparable al del método de enlace promedio [Cole, 1998].

2.5.1.5 Resumen de características

Entre las características de éstos métodos pueden destacarse las siguientes:

a) Su forma de trabajo es simple e intuitiva


El enfoque utilizado por estos métodos es semejante al que utilizaría una persona
para realizar la tarea del agrupamiento, especialmente los aglomerativos (comenzar
juntando los documentos más similares entre si, y luego buscar similitudes entre los
grupos).

b) Su resultado es una serie de agrupamientos anidados


Esto facilita la revisión de los resultados por parte del usuario, que puede
recorrer la estructura de árbol para ver agrupamientos con diferentes niveles de
detalle [Maarek et.al., 2000].

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 29


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

c) Son deterministas
Al aplicar dos veces un algoritmo jerárquico a una colección de documentos, las
dos veces seguirá el mismo camino hacia la solución. Hay algunos agrupamientos
que el algoritmo nunca considerará, sin importar la cantidad de veces que se lo
ejecute [Steinbach et.al.,2000].

d) No revisan las decisiones que toman en los pasos anteriores


Una vez que dos documentos se han asignado al mismo grupo (o se han
colocado en distintos grupos, en los divisivos), ningún paso posterior los volverá a
separar (o juntar), por lo que una mala asignación en los primeros pasos no puede
corregirse [Cole, 1998].

e) Requieren grandes tiempos de cómputo


La forma de buscar en cada paso los grupos a unir (o dividir, en los divisivos),
hacen que las implementaciones conocidas de estos algoritmos tengan tiempos de
ejecución del orden de n2 (enlace simple) ó n3 (enlace completo) [Zamir et.al.,
1998].

2.5.2 Métodos particionales

Los métodos de optimización o particionales, a diferencia de los jerárquicos, no


van generando distintos niveles de agrupamiento de los objetos, sino que trabajan en un
sólo nivel, en el que se refina (optimiza), un agrupamiento [Everitt, 1993]. Si bien los
distintos niveles de agrupamiento generados por los algoritmos jerárquicos son más
apropiados para la presentación de los resultados al usuario, las técnicas de
optimización se están comenzando a utilizar con más frecuencia en aplicaciones de
categorización automática de documentos debido a requieren considerablemente menos
recursos [Zhao et.al., 2001]. Estos métodos asumen que el valor de k (la cantidad de
grupos), está definida de antemano [Qin He, 1996].

30 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

La estructura general de éstos métodos se compone de los siguientes pasos [Han


et.al., 2001]:
1) Seleccionar k puntos representantes (cada punto representa un grupo de la
solución).
2) Asignar cada elemento al grupo del representante más cercano, de forma de
optimizar un determinado criterio.
3) Actualizar los k puntos representantes de acuerdo a la composición de cada
grupo.
4) Volver al punto 2)

Este ciclo se repite hasta que no sea posible mejorar el criterio de optimización.

2.5.2.1 Selección inicial de los representantes

El método más frecuentemente utilizado para obtener los k puntos representantes


iniciales es eligiéndolos al azar [Bradley, 1998]. Esta técnica es la más rápida y simple,
pero también la más riesgosa, ya que los puntos elegidos pueden ser una mala
representación de la colección de objetos. Cuando se utiliza esta técnica, se ejecuta
varias veces el algoritmo de agrupamiento para distintas selecciones aleatorias, tomando
el mejor resultado y descartando el resto [Steinbach et.al., 2000].
El resto de las técnicas para la selección inicial utilizan algún algoritmo de
agrupamiento (generalmente jerárquico) para obtener la selección inicial [Bradley,
1998]. Lógicamente, no se realiza un agrupamiento de todos los objetos de la colección
ya que el objetivo no es llegar a la solución mediante un algoritmo jerárquico, sino
solamente obtener los puntos iniciales para luego usar un algoritmo de optimización
(más rápido); las técnicas “Buckshot” y “Fractionation” [Cutting et.al., 1992] son un
ejemplo de esto último.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 31


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.5.2.2 Criterios de optimización

Los algoritmos particionales buscan optimizar el valor de un criterio de


optimización. Estos criterios deben ser funciones que den una medida cuantitativa de la
calidad de un agrupamiento. En [Zhao et.al., 2001] se analizan los criterios de
optimización más frecuentemente utilizados en la categorización automática de
documentos, que se detallan a continuación.

Criterios internos

Los criterios internos dan una medida de la cohesión interna de los grupos. Para
cada grupo se calcula un valor en base a los objetos que lo componen (sin tener en
cuenta elementos de otros grupos), y luego se suman los valores de cohesión de cada
uno.

a) Maximización de la suma de similitudes promedio


Para cada grupo se calcula el promedio de las similitudes que existen
entre cada par de documentos que lo componen. Por ejemplo, para el grupo S, que tiene
ns elementos:

 
1  
sim _ prom s = 2  ∑ sim ( d , d ' ) 
n s  d ∈s 
 d '∈s 

El valor total para el criterio se obtiene sumando las similitudes promedio


de cada grupo multiplicadas por su cantidad de elementos.

k
sim _ prom = ∑ n k .sim _ prom k
i=1

Este criterio toma valores más altos cuando los elementos de cada grupo
son más similares entre sí.

32 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

b) Maximización de la suma de las similitudes con el centroide


Para cada grupo se calcula la suma de las similitudes que existen entre
cada elemento y el centroide. Por ejemplo, para el grupo S:

sim _ cents = ∑ sim(d ,C s )


d ∈s

El valor total para el criterio se obtiene sumando las similitudes promedio


de cada grupo.

k
sim _ cent = ∑ sim _ centk
i =1

Los valores más altos se alcanzan cuando cada objeto se encuentra cerca
del centro de su grupo.

c) Minimización de la suma de errores cuadrados


Este criterio es el mismo que utiliza el método de Ward, que se analiza en
la sección 2.5.1, dedicada a los métodos jerárquicos.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 33


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Criterios externos

Los criterios externos tienen en cuenta la separación que existe entre los
distintos grupos. Se considera que un agrupamiento es mejor que otro cuando sus
grupos están más separados del centro de la colección.

a) Minimización de la similitud de los centroides con centroide de la


colección
Este criterio calcula la similitud existente entre el centroide de cada
grupo y el centro de la colección, y luego suma los valores multiplicados por el tamaño
de cada grupo.

k
ext _ sim = ∑ sim (Ci , C )
i=1

b) Maximización de la distancia de los centroides al centroide de la


colección
En lugar de minimizar las similitudes, este criterio intenta maximizar las
distancias.
k
ext _ dist = ∑ || C i − C ||
i= 1

Evaluación de los criterios

En [Zhao et.al., 2001] se evalúa cada uno de los criterios detallados, aplicados al
agrupamiento de colecciones de documentos. El criterio interno de maximización de la
suma de similitudes con el centroide (que es el que se utiliza más comunmente en la
bibliografía), obtiene los mejores resultados al aplicar cada uno de los criterios en forma
individual. El trabajo propone una combinación de éste criterio con el criterio externo
de minimización de la similitud de los centroides con el centro de la colección, que
mejora el rendimiento del algoritmo de agrupamiento, produciendo grupos de tamaños
más balanceados.

34 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.5.2.3 Algoritmos de optimización

Existen variantes de algoritmos de optimización en la literatura [Rasmussen,


1992; Qin He, 1996; Jain et.al., 1999; Han et.al., 2001] que implementan la estructura
básica de cuatro pasos descripta anteriormente. Estos algoritmos son similares entre sí,
por lo que se describirá únicamente el algoritmo “k-means”, que, además de ser el
referente más típico en la bibliografía, es el que más frecuentemente se encuentra
aplicado al campo de categorización automática de documentos [Steinbach et.al., 2000].

Algoritmo “K-means”

Este algoritmo, presentado originalmente por [McQueen, 1967], utiliza a los


centroides de cada grupo como sus puntos representantes. Partiendo de una selección
inicial de k centroides (que pueden ser k elementos de la colección seleccionados al
azar, o los que se obtengan mediante la aplicación de alguna técnica de inicialización),
cada uno de los elementos de la colección se asigna al grupo con el centroide más
cercano.
A continuación, se calcula el centroide de cada uno de los grupos resultantes. En
los primeros pasos se obtienen las mayores diferencias entre los centroides originales y
los calculados luego de las reasignaciones. Los puntos de la colección vuelven a
asignarse al grupo del centroide más cercano, y estos pasos se repiten hasta que los k
centroides no cambian luego de una iteración (ésto es equivalente a decir que el valor de
la función utilizada como criterio de optimización no varía). El algoritmo “k-means”
encuentra una categorización que representa un óptimo local del criterio elegido
[Bradley et.al., 1998].
Las figuras 2.8, 2.9, 2.10 y 2.11 ilustran la forma de trabajo del algoritmo. En
ellas puede verse cómo una iteración del algoritmo refina el agrupamiento. Los objetos
de la colección están representados mediante signos “+”, y los centroides de cada grupo
con los signos “X”. En la figura 2.8 se muestran los objetos de la colección y los
centroides que el algoritmo ha encontrado hasta el paso N. En la figura 2.9, cada objeto
de la colección se ha asignado al grupo con el centroide más cercano. Los nuevos
centroides, calculados a partir de la composición de los grupos, se grafican en la figura

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 35


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.10. En la figura 2.11 puede verse la situación inicial para el paso N+1. En éste paso, el
algoritmo encontrará los 3 grupos claramente definidos que existen en la colección. La
disposición de los objetos se ha elegido especialmente para que la mejora en el
agrupamiento sea evidente.

+ X
+
+
+
+ +

+
X
+ X
+ Fig 2.8
+
Objetos en una colección y los 3
centroides del paso N

+ X
+
+
+
+ +

+
X
+ X
Fig 2.9
+
+ Los objetos de la colección se
asignan al grupo del centroide
más cercano

+
X +
+
+
+ +

X +

+ X
+ Fig 2.10
+
Se calculan los centroides para
el paso N + 1

36 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

+
X +
+
+
+ +

X +

+ X
+ Fig 2.11
+
Situación inicial para el paso
N+1

2.5.2.4 Resumen de características

Entre las características de éstos métodos pueden destacarse las siguientes:

a) Pueden ser no deterministas.


Partiendo del mismo agrupamiento inicial, los métodos llegarán siempre
a la misma solución. Sin embargo, los métodos para la selección inicial son no
deterministas. El algoritmo evaluará diferentes agrupamientos cada vez que se lo
ejecute, y (si los grupos no están claramente separados) podrá llegar a soluciones
distintas [Steinbach et.al., 2000].

b) Pueden corregir errores cometidos en pasos anteriores


En cada paso del algoritmo los objetos de la colección se asignan al
grupo más apropiado según el criterio de optimización. De esta manera, el algoritmo va
refinando el agrupamiento en cada iteración [Qin He, 1996].

c) Pueden implementarse en forma eficiente


Las restricciones de recursos son la causa principal por la que se utilizan
este tipo de métodos. Estos algoritmos pueden implementarse de forma que sus tiempos
de ejecución sean del orden de n [Han et.al., 2001].

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 37


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.6 El algoritmo “Bisecting K-Means”

Se han presentado alternativas a los algoritmos tradicionales de categorización


automática de documentos [Cutting et.al., 1992; Bradley et.al., 1998; Steinbach et.al.,
2000]. El algoritmo “Bisecting K-Means” es una de ellas [Steinbach et.al., 2000]. En
esta tesis se decidió tomar esta variante como referencia para compararla con la
solución propuesta, por varios motivos:
- El trabajo que la presenta es uno de los más recientes, (año 2000), y esta
variante se analiza tambien en un trabajo del año 2001 [Zhao et.al., 2001].
- Uno de los autores (que participa en ambos trabajos) es una personalidad
reconocida dentro del dominio del recupero de información y de la
categorización automática, con más de 70 trabajos publicados, y diversos
desarrollos de software relativos al tema.
- Los trabajos demuestran que la calidad de los resultados supera tanto a los
algoritmos jerárquicos aglomerativos como al “K-Means”, con tiempos de
cómputo lineales con la cantidad de elementos a agrupar.

El algoritmo “Bisecting K-Means” sigue los siguientes pasos:


1) Colocar todos los documentos en un sólo grupo
2) Elegir el grupo más grande para dividirlo.
3) Dividir el grupo en 2 subgrupos usando el algoritmo “K-Means” (paso de
bisección).
4) Repetir el paso de bisección 5 veces, y tomar la división que lleve a una
mayor similitud promedio.
5) Repetir los pasos 2, 3 y 4 hasta alcanzar el número de grupo deseado.

Al utilizar el algoritmo “K-Means” para formar sólamente 2 grupos cada vez, y


repetir 5 veces cada división, se intenta atenuar la dependencia de este algoritmo con la
selección inicial de los representantes.

38 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.6.1 Algoritmo “Bisecting K-Means con refinamiento”

Esta variante consiste en refinar la solución obtenida con el algoritmo “Bisecting


K-Means” utilizando el algoritmo “K-Means” estándar. El agrupamiento generado por
el algoritmo “Bisecting K-Means” se toma como el punto de partida para el algoritmo
“K-Means”. Este refinamiento apunta a corregir posibles asignaciones incorrectas de
documentos a los grupos que se podrían haber realizado durante las fases de división del
algoritmo. Los resultados muestran que el paso de refinamiento mejora la calidad de las
soluciones obtenidas [Steinbach et.al., 2000].

2.7 Introducción a los Algoritmos Genéticos

Los algoritmos genéticos fueron desarrollados por John Holland, junto a su


equipo de investigación, en la universidad de Michigan en la década de 1970 [Holland,
1975]. Éstos combinan las nociones de supervivencia del más apto con un intercambio
estructurado y aleatorio de características entre individuos de una población de posibles
soluciones, conformando un algoritmo de búsqueda que puede aplicarse para resolver
problemas de optimización en diversos campos [Goldberg, 1989]. Imitando la mecánica
de la evolución biológica en la naturaleza, los algoritmos genéticos operan sobre una
población compuesta de posibles soluciones al problema. Cada elemento de la
población se denomina “cromosoma”. Un cromosoma es el representante, dentro del
algoritmo genético, de una posible solución al problema. La forma en que los
cromosomas codifican a la solución se denomina “Representación” (ver figura 2.12).

Codificación
Espacio de cromosomas Espacio de soluciones

C1
S2
C4 C2
C3 S1
S3
SN
CM

Fig 2.12 - Cada cromosoma codifica una posible


solución al problema

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 39


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

El algoritmo genético va creando nuevas “generaciones” de esta población,


cuyos individuos son cada vez mejores soluciones al problema. La creación de una
nueva generación de individuos se produce aplicando a la generación anterior
operadores genéticos, adaptados de la genética natural. La figura 2.13 representa el
esquema de funcionamiento del algoritmo genético. El proceso comienza seleccionando
un número de cromosomas para que conformen la población inicial. A continuación se
evalúa la función de adaptación para estos individuos. La función de adaptación da una
medida de la aptitud del cromosoma para sobrevivir en su entorno. Debe estar definida
de tal forma que los cromosomas que representen mejores soluciones tengan valores
más altos de adaptación.
Los individuos más aptos se seleccionan en parejas para reproducirse. La
reproducción genera nuevos cromosomas que combinan características de ambos
padres. Estos nuevos cromosomas reemplazan a los individuos con menores valores de
adaptación. A continuación, algunos cromosomas son seleccionados al azar para ser
mutados. La mutación consiste en aplicar un cambio aleatorio en su estructura. Luego,
los nuevos cromosomas deben incorporarse a la población; estos cromosomas deben
reemplazar a cromosomas ya existentes. Existen diferentes criterios que pueden
utilizarse para elegir a los cromosomas que serán reemplazados. El ciclo de selección,
reproducción y mutación se repite hasta que se cumple el criterio de terminación del
algoritmo, momento en el cual el cromosoma mejor adaptado se devuelve como
solución (ver figura 2.13).

40 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Generación de la
población inicial

Evaluación de la
función de adaptación

Selección de los
individuos a reproducir

Repetir hasta que se


Reproducción
cumpla el criterio de
terminación

Mutación

Inserción de los hijos


en la población

Decodificación
Mejor cromosoma Solución

Fig. 2.13 - Esquema de funcionamiento


del algoritmo genético

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 41


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.1 Representación

El esquema de representación es el que define de qué forma se corresponden los


cromosomas con las soluciones al problema. Para diseñar el esquema de representación,
se buscan los parámetros que identifican a las soluciones, y luego se codifican estos
parámetros dentro del cromosoma.

0 1 1 0 0 0 1 1 0 1

3 lados 13 mm

1 0 1 0 0 1 0 0 1 1

5 lados 19 mm
Fig 2.14 - Ejemplo de un esquema de
representación para polígonos regulares

La figura 2.14 muestra un posible esquema de representación para un problema


que tiene como soluciones a los polígonos regulares. Los parámetros que identifican a
cada solución son 2 (cantidad de lados y longitud del lado), y estos se codifican en el
cromosoma en forma binaria. El cromosoma se compone de una cadena de 10 bits, en
los que los primeros 3 son la cantidad de lados, y los siguientes 7 bits representan la
longitud de los lados en milímetros.
El esquema de representación debería ser tal que exista al menos una posible
codificación para cada una de las soluciones posibles. Las soluciones que no estén
dentro del espacio de cromosomas no serán exploradas por el algoritmo genético. En el
ejemplo de la figura 2.14, el algoritmo genético no explorará soluciones que se
compongan por polígonos de más de 7 lados ni longitudes mayores a 127 milímetros, ya
que con 3 y 7 bits pueden codificarse solamente números del 0 al 7, y del 0 al 127,
respectivamente. Por el mismo motivo (porque la búsqueda se hace sobre el espacio de
cromosomas), es deseable que no haya redundancia en la representación; que cada
solución sea representada por solamente un cromosoma. Si existen k cromosomas por

42 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

cada solución, el espacio de búsqueda sobre el que opera el algoritmo genético es k


veces más grande que el espacio de soluciones, haciendo más lento el proceso de
evolución. La representación ejemplificada en la figura 2.14 no tiene redundancia, cada
polígono es representado sólo por un cromosoma. Otro problema que puede presentarse
es que haya cromosomas que no representan ninguna solución. En el ejemplo de la
figura 2.14, un cromosoma que tenga todos 0 en los primeros 3 ó en los últimos 7 bits
no representa un polígono válido. En caso de que la representación lo permita, los
operadores del algoritmo genético deben adaptarse para tratar con este tipo de
cromosomas.
La codificación ejemplificada en la figura 2.14 se denomina “binaria”, ya que
cada posición del cromosoma contiene un bit. Esta es la representación clásica
propuesta por los primeros autores y que todavía es utilizada ampliamente [Goldberg,
1989; Cole, 1998; Falkenauer, 1999]. Sin embargo, hay problemas para los cuales esta
representación no es la más conveniente. El funcionamiento de los algoritmos genéticos
está basado en lo que se denomina la “hipótesis de los bloques constructores”
[Goldberg, 1989]. Esta hipótesis requiere que los cromosomas se compongan por
bloques significativos que codifiquen las características de la solución lo más
independientemente posible.
El ejemplo de la figura 2.14 es un claro ejemplo de una representación que no
cumple con esta premisa. Sería más apropiado un esquema en el cual el cromosoma se
componga por 2 números enteros, uno de los cuales codifique el número de lados y el
otro la longitud. La figura 2.15 muestra esta representación.

3 13

3 13 mm

5 19

5 19 mm

Fig 2.15 - Ejemplo de un esquema de


representación no binario para polígonos regulares

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 43


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.2 Generación de la población inicial

La población inicial es la principal fuente (luego se verá que el operador de


mutación tambien trabaja sobre este punto) de material genético para el algoritmo
genético. La población inicial debe contener cromosomas que estén bien dispersos por
el espacio de soluciones. La manera más simple de cumplir con este objetivo es elegir
cromosomas al azar. El uso de una heurística [Bezdek et.al., 1994] puede ayudar a
generar una población inicial compuesta de soluciones de mediana calidad, ahorrando
tiempo al proceso de evolución, siempre y cuando se garantice una dispersión suficiente
para la búsqueda.

2.7.3 Función de adaptación

La función de adaptación cuantifica la aptitud de cada cromosoma como


solución al problema, y determina su probabilidad de ser seleccionado para la fase de
reproducción y poder pasar parte de su material genético a la siguiente generación. La
función de adaptación proveé la presión que hace evolucionar la población hacia
cromosomas más aptos, por lo que una buena definición de esta función es fundamental
para un correcto funcionamiento del algoritmo. La función debe asignar el valor más
alto al cromosoma que representa la solución óptima al problema. Soluciones cercanas a
la óptima deben obtener valores altos, y la función debe ir decreciendo a medida que los
cromosomas representan soluciones cada vez más alejadas de la óptima. Como el
proceso de evolución tiende a retener el material genético de los cromosomas con
valores altos de aptitud, una elección apropiada de la función de adaptación resultará
mayor probabilidad de retener características de soluciones cercanas a la óptima.
Otro punto a tener en cuenta en el diseño de la función de adaptación es la escala
[Goldberg, 1989]. Cuando la aptitud de los elementos de la población es variada (por
ejemplo, al inicio del proceso de evolución), es común que la población contenga unos
pocos cromosomas cercanos al óptimo, rodeados de cromosomas que representan
soluciones mediocres. Los cromosomas más aptos obtendrán valores exageradamente
superiores al promedio para la función de adaptación, y el algoritmo genético elegirá
solamente a estos cromosomas para la reproducción. Esto puede ocasionar lo que se

44 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

denomina “convergencia prematura”: el algoritmo genético encontrará una solución sin


haber explorado suficientemente el espacio de búsqueda.
Sin embargo, a medida que la aptitud promedio va subiendo, el problema será
diferente. La diferencia irá decreciendo, y los cromosomas más aptos obtendrán valores
de adaptación similares a los de los demás cromosomas, reduciendo la probabilidad de
que el algoritmo genético seleccione a los mejores individuos para la reproducción.
Los dos problemas pueden corregirse aplicando una función de escala a la
función de adaptación. La función de escala lineal calcula la nueva función de
adaptación f’ a partir de la función de adaptación f usando la transformación lineal f’ =
a.f + b. Las constantes “a” y “b” se eligen de forma tal que el promedio de las dos
funciones sea el mismo, y que el máximo para la función f’ asegure la diferencia de
probabilidades deseada entre los elementos más aptos y el promedio.

2.7.4 Selección

La selección de los individuos que van a reproducirse se realiza mediante un


operador de selección. El operador de selección hace la elección basándose en los
valores de adaptación de los individuos. Existen distintos operadores de selección que
pueden utilizarse [Miller et.al., 1995], de los cuales se describen los más comunes.

2.7.4.1 Selección basada en el ranking


En el operador de selección basado en el ranking, los cromosomas se ordenan de
acuerdo a sus valores para la función de adaptación. Luego, se seleccionan para la
reproducción a los primeros m (la cantidad que sea necesaria) cromosomas. Como las
probabilidades de ser elegido de cada individuo dependen solamente de su posición
relativa respecto a los demás y no del valor absoluto de aptitud, este operador no
requiere que se apliquen las técnicas de escala de la función de adaptación.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 45


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.4.2 Selección por ruleta


El operador de selección por ruleta es uno de los más simples [Goldberg, 1989].
Los cromosomas se colocan en segmentos contínuos sobre una línea, de forma tal que el
segmento para cada individuo sea de tamaño proporcional a su valor de aptitud, y que la
suma de las longitudes de los segmentos sea igual a 1. Se genera un número al azar
entre 0 y 1, y el individuo cuyo segmento comprende el número generado es
seleccionado para la reproducción; el procedimiento se repite hasta que se obtiene el
número deseado de individuos. Esta técnica es análoga a una rueda de ruleta en la que a
cada cromosoma le es asignada una parte de tamaño proporcional a su valor de aptitud.
La figura 2.16 ejemplifica el funcionamiento de este operador. El tamaño del
segmento asignado a cada cromosoma (y por lo tanto su probabilidad de ser
seleccionado para reproducirse) es proporcional a su aptitud.

Cromosoma C1 C2 C3 C4 C5 Totales
Aptitud 2,8 10 22,5 3,1 6 44,4
Porcentaje 0,07 0,23 0,5 0,07 0,13 1

Nro Azar 1 Nro Azar 2

C1 C2 C3 C4 C5

0 0,07 0,3 0,8 0,87 1

Fig 2.16 - Selección de dos cromosomas


mediante el método de ruleta

El operador de selección por ruleta puede requerir la aplicación de una función


de escala sobre la función de adaptación, ya que los segmentos son dimensionados en
función del valor absoluto de aptitud de cada individuo.

46 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.4.3 Selección por torneo


Los dos operadores de selección descriptos anteriormente no permiten regular la
presión selectiva. El operador de selección basado en el ranking siempre seleccionará a
los mejores individuos de la población. La selección por ruleta, si no se aplica ninguna
función de escala, aplica una presión selectiva muy alta cuando las aptitudes de los
individuos son variadas, y muy baja cuando las aptitudes son similares [Goldberg,
1989]. El operador de selección por torneo permite controlar en forma efectiva la
presión selectiva del algoritmo genético, siendo a la vez de facil implementación. En
este esquema, se toman T individuos al azar de la población (donde T es el tamaño del
torneo, habitualmente 2 o 3 individuos), de los cuales se selecciona para la fase de
reproducción, con probabilidad p (generalmente entre 0,7 y 0,8), aquel que tenga el
mayor valor de la función de adaptación.
Los parámetros T y p permiten regular la presión selectiva. Cuanto más grandes
son los valores de T y p, mayor es la presión selectiva. En el caso extremo de que p sea
igual a 1 y T igual al tamaño de la población, el algoritmo genético solamente
seleccionará al mejor individuo de la población. En el otro extremo, si T es igual a 1, se
logra la presión selectiva más baja (los cromosomas se seleccionan al azar).
Manteniendo estos parámetros constantes, se logra una presión selectiva que es
independiente de los valores absolutos de aptitud de la población, y sin requerir la
aplicación de funciones de escala sobre la función de adaptación.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 47


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.5 Reproducción

La fase de reproducción se implementa por medio de un operador de


reproducción. El operador de reproducción es el encargado de transferir el material
genético de una generación a la siguiente. Es este operador el que confiere a la búsqueda
de soluciones mediante algoritmos genéticos su característica más distintiva
[Falkenauer, 1999]. A diferencia de otros métodos de optimización, los algoritmos
genéticos no solamente exploran el vecindario de las buenas soluciones, sino que
recombinan sus partes para formar nuevas soluciones. Se ha hecho notar que el
descubrimiento de nuevas teorías combinando nociones ya conocidas es un mecanismo
que el hombre ha utilizado constantemente a lo largo de la evolución de la ciencia
[Goldberg, 1989].
El objetivo de los operadores de reproducción es, partiendo de dos cromosomas
padres, generar uno o más cromosomas hijos que hereden características de ambos
padres, como se muestra en la figura 2.17. Se dice que en el hijo se “recombinan” las
características de los padres. Si las características se traspasan en bloques significativos,
se espera que un hijo que recombina características de buenas soluciones sea una buena
solución, tal vez mejor que cualquiera de sus padres [Falkenauer, 1999].

Padre 1 A1 A2 A3 A4 A5 A6 A7 A8

Padre 2 B1 B2 B3 B4 B5 B6 B7 B8

Recombinación

Hijo A1 A2 B3 A4 B5 A6 A7 B8

Fig 2.17 - En la recombinación, el hijo


hereda características de ambos padres

Los operadores de reproducción más típicos generan dos hijos a partir de dos
padres. A continuación se describen los más utilizados.

48 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.5.1 Cruza monopunto


Este operador consiste en separar a los padres en dos partes para formar dos
hijos intercambiando las partes de cada padre. Si los cromosomas se componen de N
bloques, se elige un número al azar c, tal que 1 <= c < N, y luego se asigna al primer
hijo los primeros c bloques del primer padre y los últimos N - c bloques del segundo
padre. Se procede en forma inversa para formar al segundo hijo. La figura 2.18 muestra
un ejemplo de la aplicación de éste operador.

C=3

Padre 1 A1 A2 A3 A4 A5 A6 A7 A8

Padre 2 B1 B2 B3 B4 B5 B6 B7 B8

Cruza monopunto

Hijo 1 A1 A2 A3 B4 B5 B6 B7 B8

Hijo 2 B1 B2 B3 A4 A5 A6 A7 A8

Fig 2.18 - Ejemplo del método de cruza


monopunto.

2.7.5.2 Cruza multipunto


Es evidente que en el operador de cruza monopunto, el primer y último bloque
de uno de los padres no pueden pasar juntos al hijo en ningun caso. El operador de cruza
multipunto avanza un paso más, quitando esta restricción. En la cruza multipunto, se
eligen M puntos de corte al azar, y las secciones de cada padre se pasan a los hijos en
forma alternada. La figura 2.19 ejemplifica este procedimiento, para el caso en que M es
igual a 2.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 49


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

C 1= 2 C 2= 5

Padre 1 A1 A2 A3 A4 A5 A6 A7 A8

Padre 2 B1 B2 B3 B4 B5 B6 B7 B8

Cruza multipunto

Hijo 1 A1 A2 B3 B4 B5 A6 A7 A8

Hijo 2 B1 B2 A3 A4 A5 B6 B7 B8

Fig 2.19 - Ejemplo del método de cruza


multipunto.

2.7.5.3 Cruza uniforme


Si bien la cruza multipunto es más flexible que la monopunto, tiene algunos
inconvenientes. En primer lugar, para valores impares de M impide que el primer y
último bloque de los padres pasen juntos a los hijos, y para valores impares obliga a que
sea asi. En segundo lugar, los bloques consecutivos tienen más posibilidades de pasar
juntos que los que se encuentran más distanciados. Esto no es deseable (a menos que la
codificación elegida haga que los bloques consecutivos representen características
relacionadas).
El operador de cruza uniforme permite el intercambio de los bloques en una
manera que es independiente del orden que la codificación impuso a cada uno dentro del
cromosoma. Para cada posición de los cromosomas hijos, se elige al azar cuál de los dos
bloques de los cromosomas padres se copia en cada uno. Esta es una generalización del
esquema de cruza multipunto donde la cantidad de puntos de corte M se elige al azar
para cada reproducción.

50 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.6 Mutación

La mutación de cromosomas (junto con la generación de la población inicial) es


la encargada de proveer al sistema de material genético. La mutación se implementa
mediante un operador de mutación. El operador de cruza genera nuevas soluciones
intercambiando bloques de las soluciones existentes, pero sin el operador de mutación,
el algoritmo genético no tendría forma de crear nuevos bloques. Este operador es el que
permite que la exploración del espacio de búsqueda sea amplia.
El operador de mutación trabaja a nivel de bloque dentro de los cromosomas,
haciendo cambios aleatorios de acuerdo a una probabilidad PM (probabilidad de
mutación). La naturaleza del cambio depende de la composición de los bloques de los
cromosomas. Si cada bloque es un bit (en la codificación binaria), el único cambio
posible es invertir su valor. Si los bloques son números reales, la modificación podría
ser la suma o sustracción de un pequeño valor aleatorio.

2.7.7 Inserción de los hijos en la población

La reinserción de hijos consiste en incorporar los nuevos cromosomas en la


población. Los métodos de reinserción son diferentes según la cantidad de cromosomas
generados sea menor, igual o mayor que la cantidad de elementos existentes en la
población.

2.7.7.1 Se generan tantos cromosomas como elementos en la población


El esquema más simple, denominado “reinserción pura”, consiste en generar
mediante la reproducción tantos hijos como elementos existen en la población, y
reemplazar todos los cromosomas de la generación anterior por los nuevos [Goldberg,
1989]. Cada cromosoma vive exactamente una generación. Un inconveniente que
presenta este método es que suele reemplazar buenas soluciones por soluciones de
menor calidad.

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 51


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.7.2 Se generan más cromosomas que elementos en la población


Este esquema es similar al de reinserción pura. Se eligen los mejores
cromosomas entre los que se generaron, y se eliminan los cromosomas sobrantes.
Luego, se reemplaza la población completa por la nueva generación.

2.7.7.3 Se generan menos cromosomas que elementos en la población


Este esquema exige seleccionar entre los cromosomas de la población aquellos
que se eliminarán. A continuación se describen los métodos más utilizados para hacerlo.

Inserción uniforme
Los cromosomas a ser reemplazados se eligen al azar entre los miembros de la
población. Se corre el riesgo de eliminar buenas soluciones, ya que no se tiene en cuenta
la aptitud de los cromosomas.

Inserción elitista
Se eligen los cromosomas menos aptos para ser reemplazados. Este método
asegura que los mejores cromosomas pasarán siempre a la siguiente generación, pero
puede restringir la amplitud de la búsqueda que realiza el algoritmo genético.

Inserción por torneo invertido


Se utiliza en combinación con el método de selección por torneo. Funciona
exactamente igual que el método de selección por torneo pero seleccionando con
probabilidad p al peor cromosoma del torneo para ser reemplazado, y tiene las mismas
propiedades que éste, permitiendo regular la presión selectiva sin el uso de funciones de
escala.

52 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

2.7.8 Criterios de terminación del algoritmo genético

El criterio de terminación del algoritmo genético es el encargado de definir el


momento en el cual debe deternerse el ciclo de evolución y adoptar el cromosoma más
apto como la solución encontrada por el algoritmo genético. A continuación se
describen los criterios más comunmente utilizados.

2.7.8.1 Criterio de convergencia de identidad


Este criterio consiste en detener al algoritmo genético cuando un determinado
porcentaje de los cromosomas de la población representan a la misma solución. Los
operadores del algoritmo genético tienden a preservar y difundir el material genético de
los cromosomas más aptos, por lo que es de esperar que luego de un gran número de
generaciones, alguna solución con gran valor de aptitud se imponga y domine la
población.

2.7.8.2 Criterio de convergencia de aptitud


Puede suceder que existan soluciones equivalentes o cuasi equivalentes a un
problema, que obtengan valores de aptitud similares. En ese caso, es probable que no
haya una solución que se imponga en la población (y el criterio de terminación por
convergencia de identidad nunca se cumpla). Este criterio no espera a que la población
se componga mayoritariamente de una sola solución, sino que finaliza la ejecución del
algoritmo cuando los valores de aptitud de un determinado porcentaje de las soluciones
son iguales, o difieren en un pequeño porcentaje. Por ejemplo, cuando el 90% de al s
soluciones tenga valores de aptitud que no difieran en más de un 1%.

2.7.8.3 Criterio de cantidad de generaciones


Los métodos anteriores apuntan a esperar a que la evolución de la población
llegue a su fin. Cuando alguno de ellos se cumple, es probable que las soluciones no
sigan mejorando mucho más, no importa cuantas generaciones más se ejecuten. Sin
embargo, los algoritmos genéticos pueden necesitar un número de generaciones muy

Eugenio Yolis CAPITULO 2 - ESTADO DEL ARTE 53


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

grande para llegar a la convergencia, dependiendo de las tasas de reproducción y


mutación. Utilizando cualquiera de los dos criterios anteriores no puede estimarse un
número máximo de generaciones, ya que esto dependerá no solamente de los
parámetros del algoritmo genético sino tambien del azar.
Esto puede ser un problema, sobre todo si se quieren comparar los tiempos de
resolución de un problema mediante algoritmos genéticos con otros métodos [Estivill-
Castro, 2000]. El criterio de terminación por cantidad de generaciones consiste
simplemente en finalizar la ejecución una vez que ha transcurrido un número
determinado de generaciones. Este método permite determinar con precisión los
tiempos de ejecución del algoritmo a costa de detener la evolución sin la certeza de que
las soluciones no seguirán mejorando.

54 CAPITULO 2 – ESTADO DEL ARTE Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 3
Descripción del problema
En este capítulo se plantean las cuestiones que esta tesis apunta a responder, y se
analiza el trabajo previo que existe acerca de la aplicación de los Algoritmos Genéticos
a este problema. En la sección 3.1 se exponen las limitaciones que presentan los
algoritmos actuales, relacionados con la forma en la que exploran el espacio de posibles
soluciones. La sección 3.2 describe los problemas encontrados en los trabajos previos
que aplicaron los algoritmos genéticos a la categorización automática.

3.1 La búsqueda en el espacio de soluciones

Ante la imposibilidad de evaluar todas las posibles soluciones, los algoritmos de


categorización automática exploran sólo una parte del espacio de búsqueda (solamente
evaluan algunas de las posibles categorizaciones).
La diferencia fundamental entre los distintos algoritmos consiste en:
- La elección del punto inicial de la búsqueda.
- Las reglas para pasar de un punto del espacio de búsqueda a otro.

3.1.1 Problemas de los algoritmos actuales

Algoritmos jerárquicos aglomerativos


Si bien se acepta que los métodos jerárquicos aglomerativos obtienen resultados
de buena calidad [Cutting et.al., 1992; Cole, 1998; Dash et.al., 2001], los tiempos de
cómputo que requieren son inaceptables para las aplicaciones prácticas, ya que son del
órden de N2 , donde N es la cantidad de documentos a agrupar [Zamir et.al., 1998; Dash
et.al., 2001].

Eugenio Yolis CAPITULO 3 - DESCRIPCION DEL PROBLEMA 55


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Algoritmo K-Means
El algoritmo K-Means es mucho más eficiente (los tiempos de cómputo
requeridos son lineales con la cantidad documentos a agrupar [Han et.al., 2001]), pero
es dependiente de la selección inicial de centroides [Bradley, 1998]. Sus resultados
pueden ser bastante pobres y suelen variar mucho si se aplica varias veces a la misma
colección de documentos, ya que si la selección de centroides al azar es mala, la
solución encontrada también lo será.

Algoritmo Bisecting K-Means


Aunque este algoritmo ha demostrado obtener mejores soluciones que el
algoritmo k-means y los métodos jerárquicos aglomerativos [Steinbach et.al., 2000], en
tiempos de cómputo lineales con la cantidad de documentos a agrupar, la forma en que
explora el espacio de búsqueda es claramente sub-óptima. Al momento de dividir un
grupo, el algoritmo “Bisecting K-Means” realiza 5 divisiones diferentes del grupo
(aplicando 5 veces el algoritmo K-Means con k=2 a los elementos del grupo), y luego
elige una de ellas (la que más hace crecer el criterio de optimización), descartando las
demás divisiones que creó.
El siguiente análisis muestra por qué esta forma de trabajo no es eficiente:
- Cuando el grupo es fácilmente divisible (hay 2 subgrupos claramente
definidos), las 5 corridas del algoritmo K-Means encontrarán la misma
división, o divisiones con muy pocas variaciones. En este caso, el algoritmo
estaría repitiendo 5 veces el mismo trabajo.
- Cuando no hay dos subgrupos claramente definidos, las 5 corridas del
algoritmo K-Means encontrarán divisiones diferentes. En este caso, el
problema es que el algoritmo Bisecting K-Means no tiene ningún mecanismo
para aprovechar el trabajo realizado al armar las divisiones que son
descartadas. Es muy posible que en alguna de ellas haya encontrado un
grupo excelente y uno muy malo que en promedio hagan que descarte esa
división, y no tiene ningún mecanismo que le permita quedarse con la parte
buena y descartar sólo lo malo.

56 CAPITULO 3 - DESCRIPCION DEL PROBLEMA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Estos problemas de los algoritmos actuales dan lugar a las siguientes cuestiones:

Cuestión 1: ¿Pueden ayudar los algoritmos genéticos a explorar el espacio de búsqueda


en forma más eficiente?
Cuestión 2: ¿ Pueden ayudar los algoritmos genéticos a encontrar soluciones de mejor
calidad?

3.2 Utilización de algoritmos genéticos

La aplicación de algoritmos genéticos al problema general de la categorización


automática se ha investigado con interés [Jones et.al., 1991; Bezdek et.al., 1994;
Estivill-Castro et.al., 1997; Cole, 1998; Jain et.al., 1999; Hall et.al., 1999; Falkenauer,
1999; Painho et.al., 2000]. Sin embargo, son muy pocos los autores que los han
aplicado a la categorización automática de documentos [Jones et.al., 1995]. Esto se debe
a que, pese a que los algoritmos genéticos han demostrado capacidad de explorar el
espacio de búsqueda amplia y eficientemente [Goldberg, 1989; Koza, 1997; Falkenauer,
1999], los resultados de las investigaciones no han dado buenos resultados al aplicarlos
a la categorización automática en general, ni a la categorización automática de
documentos en particular.
La causa de estos fracasos radica en la aplicación inadecuada de los algoritmos
genéticos al problema. Se ha hecho notar [Falkenauer, 1999; Estivill-Castro, 2000] que
los algoritmos genéticos no son una solución universal que pueda aplicarse en forma
pura a cualquier problema, sino un paradigma que debe adaptarse a los problemas
concretos a los que se aplica. Los fracasos no se deben a que los algoritmos genéticos no
puedan aplicarse en forma efectiva en el dominio de la categorización automática de
documentos sino a la falta de una correcta adaptación del esquema de representación y
los operadores del algoritmo genético a este problema.

Eugenio Yolis CAPITULO 3 - DESCRIPCION DEL PROBLEMA 57


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

3.2.1 Representación y operadores de cruza

La hipótesis principal en la que descansa la teoría de los algoritmos genéticos es


la hipótesis de los “bloques constructores” (en inglés “building blocks”) [Goldberg,
1989]; esto es, que el operador de cruza intercambiará características entre los
individuos de la población en bloques significativos. Al combinarse bloques de buenas
soluciones, se espera que la solución resultante también lo sea. Para que los principios
de la hipótesis se cumplan (y el algoritmo genético opere de acuerdo a la misma), la
representación y el operador de cruza deben ser definidos en forma cuidadosa e
interdependiente, para evitar lo que se conoce como “operadores de cruza insensibles al
contexto” [Cole, 1998]. La inconsistencia más importante que puede surgir al definir
incorrectamente estos operadores es que la cruza de dos individuos que representan la
misma solución puede dar como resultado una solución diferente, con poca relación con
aquella a partir de la cual se generó.
Debe remarcarse que al operar el algoritmo genético por fuera de la hipótesis de
los bloques constructores, es altamente probable que los resultados sean incorrectos, o al
menos insatisfactorios.

Esto lleva a plantear la cuestión:


Cuestión 3: ¿De qué manera puede definirse la representación de las soluciones y el
operador de cruza para que el algoritmo genético pueda ser aplicado a la categorización
automática de documentos de acuerdo a la hipótesis de los bloques constructores?

3.2.2 Uso del conocimiento del dominio

Otro punto importante es la posibilidad de incorporar en los operadores del


algoritmo genético conocimiento específico del problema al cual se está aplicando el
mismo. De esta manera, los operadores no trabajan en forma totalmente aleatoria sobre
los individuos de la población, sino que tienden a realizar cambios que apunten a buenas
soluciones para el problema a resolver. Esto ayuda a que el algoritmo genético no tenga

58 CAPITULO 3 - DESCRIPCION DEL PROBLEMA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

que explorar todo el espacio de búsqueda, ya que lo guía por aquellos sectores en los
cuales las soluciones son significativas.
Sin la aplicación de conocimiento específico del problema que se está
resolviendo en los operadores, es casi imposible que el algoritmo genético supere en
términos de eficiencia a los algoritmos diseñados ad hoc para el problema [Goldberg,
1989; Estivill-Castro, 2000]. Sin embargo, solamente un trabajo hace uso de este
conocimiento [Estivill-Castro, 2000], aunque falla en reconocer la importancia de la
sensibilidad al contexto del operador de cruza.

Lo expuesto en esta sección da lugar a la siguiente cuestión:


Cuestión 4: ¿De qué manera pueden diseñarse los operadores del algoritmo genético
para hacer uso del conocimiento específico del dominio?

Eugenio Yolis CAPITULO 3 - DESCRIPCION DEL PROBLEMA 59


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 4
Solución propuesta
En este capítulo se presenta la solución propuesta en esta tesis, que apunta a
responder a las cuestiones planteadas en el capítulo 3. En la sección 4.1 se describen las
técnicas utilizadas en trabajos previos que aplican los algoritmos genéticos a problemas
de categorización automática. La sección 4.2 detalla el algoritmo de categorización
propuesto. Este algoritmo emplea algunas de las técnicas descriptas en la sección 4.1,
pero su característica principal es la utilización de los nuevos operadores que se
presentan en esta tesis.

4.1 Adaptaciones existentes

En esta sección se describen los esquemas de representación y operadores que se


han utilizado en los trabajos previos que aplicaron los algoritmos genéticos a problemas
de categorización automática.

4.1.1 Representación

Los métodos más comunes para codificar un agrupamiento en un cromosoma


son los siguientes:

4.1.1.1 Numeración de grupo


El cromosoma representa un agrupamiento de n objetos como una cadena de n
números enteros. En cada posición i, la cadena contiene el número de grupo en que se
encuentra el objeto número i [Jones et.al., 1991]. Por ejemplo, para una colección de 5
objetos, el siguiente cromosoma representa un agrupamiento que contiene los grupos
{1,2,4} y {3,5}:

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 61


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

1 1 2 1 2

Pero en un agrupamiento no importa el número de cada grupo, sino sólamente


cuáles objetos contiene cada uno, por lo que el siguiente cromosoma representa el
mismo agrupamiento:

2 2 1 2 1

4.1.1.2 Representación por matriz


Este método utiliza una matriz de n x k posiciones para representar un
agrupamiento de n objetos y k grupos. Cada celda i,j de la matriz contiene el valor 1 si
el elemento i se encuentra en el grupo j, o 0 en caso contrario [Bezdek et.al., 1994]. El
mismo agrupamiento utilizado en el ejemplo anterior estaría representado por el
cromosoma
1 1 0 1 0
0 0 1 0 1

Y también por el cromosoma

0 0 1 0 1
1 1 0 1 0

4.1.1.3 Permutación con separadores


En este esquema, un agrupamiento de n objetos en k grupos se representa por
una cadena de enteros en la que los valores de cada posición representan el número de
objeto, y el grupo al que pertenece está dado por el orden en el que los objetos aparecen
en la cadena. Los objetos que pertenecen al mismo grupo se encuentran juntos, y se
utilizan los números (n+1) al (n+k-1), que no son válidos como números de objetos,
para indicar la separación entre los grupos. El agrupamiento del ejemplo se podría
codificar con cualquiera de los siguientes cromosomas (donde el número 6 actua como
separador):

62 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

1 2 4 6 3 5

3 5 6 1 2 4

4 1 2 6 3 5

4.1.1.4 Permutaciónes con búsquedas locales


Al igual que el método de Permutación con separadores, estos métodos utilizan
una cadena de enteros, en el que cada valor representa el número de objeto, pero en este
caso no se utiliza ningún separador. Un agrupamiento de n objetos en k grupos se
representa mediante una cadena que contiene los n números de elemento, ordenados
adecuadamente. Cuando se utilizan estas codificaciones, los cromosomas no representan
agrupamientos en forma directa, sino que debe emplearse un algoritmo de búsqueda
local para encontrar el agrupamiento representado. Estos algoritmos encuentran un
agrupamiento que es el máximo local para algún criterio determinado.
El más simple de estos algoritmos, denominado “Permutación ambiciosa”,
supone que los primeros k objetos son los centroides iniciales de los k grupos, y va
asignando cada uno de los elementos siguientes al grupo con el centroide más cercano,
en forma similar a como funciona el algoritmo k-means. El agrupamiento del ejemplo
podría ser codificado por el cromosoma:

1 3 4 5 2

Suponiendo que el agrupamiento usado como ejemplo sea el máximo local para
esa búsqueda.
Estos métodos tienen ciertas particularidades que deben tenerse en cuenta:
- Puede suceder que haya agrupamientos imposibles de codificar con estos
esquemas (que no se pueda encontrar una permutación para la cual ese
agrupamiento sea el máximo local).
- Los algoritmos de búsqueda local más comunes son del orden de (nk) o de
(n2 k) [Cole, 1998].

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 63


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.1.2 Generación de la población inicial

Los cromosomas de la generacion inicial pueden ser agrupamientos al azar


[Jones et.al., 1991], o agrupamientos generados mediante alguna heurística que aplique
conocimiento del dominio para formar grupos con algún criterio [Bezdek et.al., 1994].

4.1.3 Función de adaptación

La función de adaptación debe dar una medida de la calidad del agrupamiento


que representa el cromosoma, por lo que normalmente se usan las mismas funciones que
utilizan los algoritmos tradicionales como criterios de optimización [Cole, 1998].

4.1.4 Selección

En el capítulo 2 (“Estado del arte”), sección 2.7.4, se describen los distintos


operadores de selección que utilizan los algoritmos genéticos. No se encuentran
operadores de selección especialmente adaptados al problema, en los trabajos previos
que aplicaron los algoritmos genéticos a la categorización automática.

4.1.5 Cruza

Se detallan los operadores de cruza utilizados habitualmente para la


representación Numeración de grupo (que es la que se utilizará en el algoritmo
propuesto).

4.1.5.1 Cruza monopunto y multipunto

Estos son los operadores de cruza clásicos, que suelen aplicarse a los
cromosomas que usan representación binaria en los algoritmos genéticos más sencillos
[Goldberg, 1989]. Sin embargo, aplicados a la representación de Numeración de grupo,

64 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

estos métodos presentan un problema denominado “insensibilidad al contexto”


[Falkenauer, 1999] . Este problema surge del hecho de que la cruza opera sobre los
cromosomas sin tener en cuenta qué es lo que estos cromosomas representan. Asi, el
cromosoma hijo tiene elementos de los cromosomas padres, pero el agrupamiento
representado por el hijo tiene muy poco (o nada) en común con los agrupamientos
representados por los padres, como muestra el ejemplo siguiente:

1 1 2 1 2

2 2 1 2 1

1 1 1 2 1

Como los dos padres representan el mismo agrupamiento, con los grupos {1,2,4}
y {3,5}, se esperaría que el hijo represente el mismo agrupamiento. Sin embargo
representa un agrupamiento distinto, que contiene los grupos {1,2,3,5} y {4}.
Una forma de intentar resolver el problema es renumerar los grupos de cada
padre en forma canónica (por ejemplo, de forma ascendente, de izquierda a derecha)
antes de realizar la cruza [Jones et.al., 1991]. En ese caso, los dos cromosomas padres
del ejemplo anterior serían idénticos. Sin embargo, hay casos en los cuales esto no es
suficiente:

1 2 3 3 3 3 1

1 1 2 2 2 2 3

1 2 3 3 2 2 3

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 65


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

En este caso, los cromosomas padres ya están numerados en forma canónica. El


grupo {3,4,5,6} se repite en los dos padres, por lo que se esperaría que pase al hijo sin
cambios. Sin embargo, en el agrupamiento resultante el grupo se ha dividido.

4.1.5.2 Cruza basada en las aristas


Este operador trabaja a nivel de agrupamiento, en lugar de hacerlo a nivel de
cromosoma [Jones et.al., 1991; Cole, 1998]. Por lo tanto, no sufre el problema de la
insensibilidad al contexto.
El algoritmo de cruza basada en las aristas sigue los siguientes pasos:
- Buscar las intersecciones no vacías de los grupos de cada padre. Estas
intersecciones son los grupos del agrupamiento hijo.
- Juntar estas intersecciones al azar hasta que el hijo tenga k grupos.

Por ejemplo, si uno de los padres es


1 2 3 3 3 3 1
Que contiene los grupos : { 1, 7 } , { 2 } , { 3, 4, 5, 6 }
Y el otro es
1 1 2 2 2 2 3
Que contiene los grupos : { 1, 2 } , { 3, 4, 5, 6 } , { 7 }

Las intersecciones no vacías entre los grupos serán:


{ 1 } , { 2 } , { 3, 4, 5, 6 } , { 7 }
Como son 4 intersecciones, y el hijo debe tener 3 grupos (al igual que los
padres), deben juntarse 2 de las intersecciones. Puede verse que en ningún caso el grupo
que es común entre los dos padres puede dividirse.
Si juntamos las intersecciones { 2 } y { 7 }, el hijo será
1 2 3 3 3 3 2

Sin embargo, si bien el operador es sensible al contexto, no aplica información


específica del dominio para mejorar la calidad del hijo que está creando (por ejemplo,
no intenta juntar las intersecciones que contienen elementos más similares entre si).

66 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.1.6 Mutación

Los operadores de mutación utilizados en la literatura funcionan en forma


análoga a los operadores de mutación clásicos, cambiando elementos de grupo en forma
aleatoria en base a alguna probabilidad de mutación [Jones et.al., 1991; Bezdek et.al.,
1994].

4.2 Algoritmo propuesto

En esta sección se describe el algoritmo génetico de categorización automática


de documentos propuesto. Este algoritmo presenta un nuevo operador de cruza y cuatro
nuevos operadores de mutación diseñados específicamente para el problema de la
categorización automática de documentos.
Para el diseño de los operadores se tuvieron en cuenta los siguientes puntos,
basados en las cuestiones planteadas en el capítulo 3 (“Descripción del problema”):
- Los operadores deben ser eficientes
- Los operadores deben ayudar a explorar el espacio de búsqueda
- Los operadores deben aplicar información del dominio para ayudar al
algoritmo a obtener soluciones de buena calidad

4.2.1 Representación

La representación elegida fue la Numeración de grupo; este método es el más


frecuentemente utilizado en la literatura [Falkenauer, 1999].
Para elegir el método de representación se evaluaron los siguientes puntos:
- Que la representación fuera sencilla e intuitiva,
- Que se pudiera implementar eficientemente la función de evaluación,
- Que se pudieran implementar eficientemente los operadores.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 67


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.2 Estructura del cromosoma

La estructura del cromosoma utilizado en el algoritmo propuesto es la siguiente:

Vector de elementos (1..N) : es el vector que contiene, para cada elemento, el


número de grupo al que pertenece

CantGrupos : es la cantidad de grupos que tiene el agrupamiento

CantElementos : es la cantidad de
elementos que tiene el grupo
Vector de
grupos NroGrupo : es el número que identifica al
grupo
VecCentroide : es el centroide del grupo

La cantidad de grupos (CantGrupos) y el Vector de grupos no son estrictamente


necesarios, ya que todos los datos que contienen pueden obtenerse realizando
operaciones a partir de la información del vector de elementos. Sin embargo, como
estos datos se acceden muy frecuentemente, se incluyen en el cromosoma por razones
de eficiencia.

4.2.3 Generacion de la población inicial

Para seleccionar el método de generación de la población inicial se hicieron


diversas pruebas y se extrajeron las siguientes observaciones:
- El tamaño de la población requerido para que el algoritmo genético
encuentre buenas soluciones es más chico cuanto mejores sean los
agrupamientos de la población inicial.
- Generar la población inicial al azar es lo más rápido, pero los agrupamientos
generados son de muy baja calidad, y lleva demasiadas generaciones al
algoritmo genético llegar a buenas soluciones.
- Utilizando el algoritmo k-means (el más rápido de los algoritmos conocidos
que dan soluciones aceptables) se obtienen buenas soluciones en
relativamente pocas generaciones, pero el proceso de generación de la
población inicial exige demasiado tiempo (aún teniendo en cuenta que el

68 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

tamaño de la población inicial puede reducirse), ya que el algoritmo k-means


es del orden de (n.k).

Buscando una solución intermedia, se decidió aplicar el algoritmo k-means para


generar los agrupamientos de la población inicial, pero en lugar de formar k grupos, se
generan agrupamientos de log(k) grupos. De esta forma, la generación de la población
inicial lleva tiempos del orden de (n.log(k)). El algoritmo genético tiene operadores que
se ocupan de ir dividiendo a los grupos para llegar a soluciones que tengan k grupos,
que se detallan más adelante.

4.2.4 Funcion de adaptación

Para el algoritmo propuesto se eligió la Similitud promedio del agrupamiento


como función de adaptación. Esta función se detalla en el capítulo 5 (“Prueba
Experimental”), sección 5.2.2.1.

4.2.5 Seleccion

Para el algoritmo propuesto se utiliza el método de Torneo, por los siguientes


motivos:
- Es independiente de la escala de la función de adaptación,
- No requiere ordenar los valores de adaptación de cada cromosoma,
- Permite regular la presión de selección.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 69


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.6 Cruza

Dado que ninguno de los operadores de cruza encontrados en la literatura daba


solución a las cuestiones planteadas en el capítulo 3 (“Descripción del problema”), se
diseñó un nuevo operador de cruza que cumpliera con las características buscadas.
El operador fue diseñado con los siguientes lineamientos:
- La implementación debía ser eficiente,
- El operador debía ser sensible al contexto,
- El operador debía aplicar información específica del dominio para generar
agrupamientos de buena calidad.

4.2.6.1 Cruza Pasa Grupo

El operador diseñado se denomina “Cruza Pasa Grupos”. El operador genera 2


hijos a partir de los padres. Primero asigna un rol a cada padre para generar el primer
hijo, y luego invierte los roles para generar el otro. La figura 4.1 muestra el esquema
básico de funcionamiento del operador para generar uno de los hijos.

Padre que pasa Padre que pasa grupo


agrupamiento base

1º - Pasa agrupamiento 2º - Pasa grupo

Hijo

Fig 4.1 - Esquema básico del funcionamiento


del operador Cruza Pasa Grupo

El agrupamiento de uno de los padres es copiado al hijo sin modificaciones, y


luego uno de los grupos del segundo padre se pasa al hijo, reacomodando los elementos
que hagan falta.

70 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Los pasos que sigue el algoritmo para generar cada uno de los hijos son:
1. Crear un cromosoma con el mismo agrupamiento que el primer padre (el
padre que pasa el agrupamiento),
2. Seleccionar un grupo fuente del segundo padre (el padre que pasa el grupo),
3. Seleccionar un grupo destino en el hijo, que va a transformarse en el grupo
del padre,
4. Reacomodar los elementos del hijo según sea necesario para que el grupo
destino contenga los elementos que contiene el grupo fuente.

Paso 1 - Crear el cromosoma hijo


Este paso consiste simplemente en crear un cromosoma copiando los mismos
valores que contiene el padre que pasa el agrupamiento.

Paso 2 - Selección del grupo fuente


En este paso se selecciona un grupo del padre que pasa el grupo. Hay un
parámetro del algoritmo genético que controla la probabilidad de que se elija el mejor
grupo (aquel con mayor similitud promedio) para pasarlo al hijo. En caso contrario, se
elige un grupo al azar para pasarlo al hijo. Este parámetro varía entre los valores 0,8 y
0,9 durante la ejecución del algoritmo genético, lo que quiere decir que en más del 80%
de los casos, se elegirá el grupo con mayor similitud promedio para pasarlo al hijo.

Paso 3 - Selección del grupo destino


En este paso se selecciona un grupo del hijo, al que se le quitarán y agregarán
elementos para que contenga los mismos elementos que contiene el grupo fuente. Hay
cuatro formas de seleccionar este grupo, cada una de ellas con cierta probabilidad:
a) El grupo más similar (probabilidad 0,56): se busca en el hijo el grupo con el
centroide más cercano al centroide del grupo fuente.
b) El grupo con más elementos en común (probabilidad 0,40): se busca en el
hijo el grupo con más elementos en común con el grupo fuente.
c) Menor similitud promedio (probabilidad 0,02): se busca en el hijo el grupo
que tenga la menor similitud promedio.
d) Al azar (probabilidad 0,02): se selecciona un grupo al azar del hijo.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 71


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Paso 4 - Reacomodamiento de los elementos del hijo


En este paso, se agregan y quitan elementos del grupo destino para que resulte
igual al grupo fuente. Los elementos que están en el grupo fuente (en el padre) pero que
no están en el grupo destino (en el hijo), se sacan del grupo en el que están en el hijo, y
se agregan al grupo destino. Los elementos que están en el grupo destino (en el hijo)
pero que no están en el grupo fuente (en el padre), se quitan del grupo destino del hijo,
y se colocan en otro grupo. El grupo al que se reasigna cada uno de estos elementos se
elige de la siguiente forma:
a) Con probabilidad 0,95, se busca, dentro de los 2 grupos del hijo más
similares al grupo fuente del padre, aquel que tenga el centroide más cercano
al elemento que se está reasignando.
b) Con probabilidad del 0,05, se elige al azar el grupo al cual se moverá el
elemento a reasignar.

4.2.6.2 Análisis del operador Cruza Pasa Grupo

Sensibilidad al contexto
El operador copia el agrupamiento de uno de los padres al hijo, y después le pasa
un grupo del otro padre. El hijo siempre heredará grupos de ambos padres. En el caso
de que ambos padres sean iguales, la forma de seleccionar el grupo destino asegura que
en el 96% de los casos el grupo destino será el mismo que el grupo origen, y el hijo será
igual a los padres. En las pruebas realizadas se observó que si no se dejaba ningún caso
librado al azar, el algoritmo exploraba el espacio de búsqueda en forma incompleta,
convergiendo en forma demasiado rápido a soluciones subóptimas.

Utilización de información específica del dominio


El operador no elige al azar qué grupo del padre pasar al hijo, sino que elige en
más del 80% de los casos el grupo con mayor similitud promedio. Así, durante la cruza
no sólo se heredan características de los padres, sino que se intenta que estas
características sean deseables. En forma similar, cuando hay que reasignar un elemento
a otro grupo, en un 95% de los casos se busca una alternativa mejor que la elección al
azar del grupo destino, tratando de que el agrupamiento resultante sea de buena calidad.

72 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.7 Mutación

Durante las pruebas realizadas se observó que los operadores de mutación


clásicos retrasaban considerablemente la convergencia del algoritmo genético, ya que lo
obligaban a explorar regiones del espacio de búsqueda al azar, donde la mayor parte de
las veces no se encontraban mejores soluciones. Al diseñar un algoritmo genético que
pueda competir en términos de eficiencia con los algoritmos específicos del dominio,
debe sacrificarse en parte la amplitud de la exploración, restringiéndola a aquellas
regiones donde es más probable que haya buenas soluciones.
Esto puede lograrse diseñando operadores de mutación que no hagan cambios
totalmente aleatorios, sino que, de la misma forma que el operador de cruza, tiendan a
hacer cambios que aumenten la calidad de las soluciones, dejando algunas pocas
decisiones libradas al azar. Estos operadores se aplicarán luego con probabilidades
bastante altas comparadas con las de los operadores de mutación estándar, ya que son
necesarios no sólo para la exploración del espacio de búsqueda, sino tambien para el
aumento de la calidad de la población. A continuación se describen los 4 nuevos
operadores de mutación diseñados para el algoritmo propuesto.

4.2.7.1 Mutación RefinarKM


Este operador de mutación se aplica con una probabilidad que varía durante la
ejecución del algoritmo genético entre los valores 0,1 y 0,25. Cuando se muta un
cromosoma mediante este operador, se aplica al agrupamiento lo que se denomina
“Refinamiento ligero”, que es una modificación del algoritmo k-means. El refinamiento
ligero consiste en una sóla iteración del algoritmo k-means. Pero para cada elemento, en
lugar de buscar entre los k grupos del agrupamiento aquel cuyo centroide sea más
cercano al del elemento, la búsqueda se realiza entre 2*log(k) grupos seleccionados al
azar. De esta forma, en lugar de ser del orden de (n.k), la aplicación del operador tiene
una complejidad del orden de (n.2.log(k)). El operador cumple con el doble propósito de
mejorar la calidad de la solución, pero al mismo tiempo incluir el azar en las decisiones
para ampliar la exploración del espacio de búsqueda.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 73


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.7.2 Mutación Refinar Selectivo


Este operador de mutación se aplica con una probabilidad que varía durante la
ejecución del algoritmo genético entre los valores 0 y 0,3. Al aplicar este operador a un
cromosoma, se intenta mejorar la calidad de los mejores grupos del agrupamiento. Lo
que se busca es que el agrupamiento mutado tenga algunos grupos de muy buena
calidad que luego, si el cromosoma es seleccionado como padre, pasen al hijo. El
operador identifica los grupos con mayor y menor similitud promedio y luego recorre
los mejores grupos en busca de los elementos que están más alejados del centroide del
grupo. Esos elementos son removidos del grupo (lo que aumenta su similitud
promedio), y son reasignados a alguno de los grupos con menor similitud promedio (lo
que disminuye aún más su similitud promedio). El cromosoma resultante luego de la
mutación puede no ser una buena solución, pero va a tener algunos grupos de muy
buena calidad que podrán pasar a sus hijos en caso de ser seleccionado para la cruza.

4.2.7.3 Mutación Join


Este operador de mutación se aplica con probabilidad 1 a todos los cromosomas
que tengan más de k grupos, y con una probabilidad que varía durante la ejecución del
algoritmo genético entre los valores 0,05 y 0,15 a los cromosomas que tengan k grupos.
La aplicación de este operador a un cromosoma que tenga k grupos hará que en la
iteración siguiente se aplique el operador de mutación Split, que se describe en la
sección 4.2.7.4 (ya que el agrupamiento tendrá k-1 grupos). El operador apunta a juntar
en un solo grupo dos grupos de mediana o mala calidad, con la esperanza de que el
operador de mutación Split pueda armar grupos de mejor calidad, mejorando la
solución. El operador elige dos grupos del agrupamiento, y junta en un sólo grupo los
elementos de ambos.
El primero de los grupos puede ser seleccionado con alguno de estos criterios:
- Menor tamaño (probabilidad 0,7): se selecciona el grupo con menor cantidad
de elementos.
- Menor similitud promedio (probabilidad 0,3): se selecciona el grupo con
menor similitud promedio.

74 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

El otro grupo se puede seleccionar con alguno de estos criterios:


- Más similar (probabilidad 0,95): se selecciona el grupo con el centroide más
cercano al del primer grupo elegido.
- Al azar (probabilidad 0,05): el segundo grupo se selecciona al azar.

4.2.7.4 Mutación Split


Este operador de mutación se aplica con probabilidad 1 a todos los cromosomas
que tengan menos de k grupos, y con una probabilidad que varía durante la ejecución
del algoritmo genético entre los valores 0,05 y 0,15 a los cromosomas que tengan k
grupos. Como en la generación de la población inicial los agrupamientos se generan con
log(k) grupos, este operador es necesario para que los agrupamientos lleguen a tener k
grupos. El operador selecciona un grupo y lo divide en 2. Si al cromosoma se le aplicó
anteriormente el operador de mutación Join, el grupo formado por este operador es el
que se divide. En caso contrario, el grupo a dividir puede ser seleccionado con alguno
de los siguientes criterios:
- Mayor tamaño (probabilidad 0,90): se selecciona el grupo con la mayor
cantidad de elementos.
- Menor similitud promedio (probabilidad 0,05): se selecciona el grupo con la
menor similitud promedio.
- Al azar (probabilidad 0,05): el grupo a dividir es seleccionado al azar.
Una vez que se tiene el grupo a dividir, se lo divide en 2 aplicando a los
elementos del grupo la primera iteración (fase inicial) del algoritmo k-means, con k = 2.

4.2.8 Inserción de los hijos en la población

Se utiliza el método de torneo invertido. Cada vez que se realiza la reproducción,


se busca mediante éste método dos cromosomas de la población que son reemplazados
por los hijos recién generados.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 75


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.9 Tamaño de la población

Los tamaños de población utilizados en trabajos previos varían entre valores de


40 a 1000 individuos [Cole, 1998]. Se ha hecho notar [Estivill-Castro, 2000] que
tamaños de población excesivamente grandes retrasan la convergencia del algoritmo
genético, impidiéndole competir con otro tipo de métodos. En las pruebas realizadas se
observó que partiendo de una población de individuos de calidad medianamente
aceptable, y utilizando los operadores ya descriptos, al agrandar el tamaño de la
población se aumentaba la cantidad de generaciones requeridas para obtener buenas
soluciones, sin obtener mejoras apreciables en la calidad de las mismas. En el algoritmo
propuesto, se comienza con una población inicial de 12 individuos, que luego
disminuye a 10 cuando se han completado el 40% de las generaciones previstas.

4.2.10 Criterio de terminación

En las pruebas realizadas se observó que la calidad de la mejor solución


aumentaba con cierto ritmo hasta un punto, para luego crecer muy lentamente hasta
alcanzar la convergencia. Esto es, una vez que se llegaba a una buena solución, el
algoritmo requería una cantidad importante de generaciones hasta que todos los
cromosomas alcanzaban niveles cercanos de la función de adaptación. Para evitar esa
espera, se decidió terminar la ejecución del algoritmo genético luego de una cantidad
fija de iteraciones. Experimentalmente se encontró el valor GEN_MAX = (N / 20) + 25.
Esto es, dada la cantidad de documentos a categorizar, se calcula la cantidad de
iteraciones que debe ejecutar el algoritmo genético. Luego de llegar al número de
generaciones máximo, se selecciona como solución al cromosoma con el mayor valor
de la función de adaptación.

76 CAPITULO 4 – SOLUCION PROPUESTA Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4.2.11 Algoritmo “Genético con refinamiento”

Al igual que en el caso del algoritmo “Bisecting K-Means con refinamiento”,


esta variante consiste en refinar la solución obtenida con el algoritmo genético
propuesto utilizando el algoritmo “K-Means” estándar. El algoritmo propuesto no
garantiza que la solución obtenida sea un máximo local para la función de optimización,
por lo que probablemente el refinamiento mejore la calidad de la solución, ya que
encontrará el máximo local más próximo al agrupamiento obtenido por el algoritmo
genético.

Eugenio Yolis CAPITULO 4 - SOLUCION PROPUESTA 77


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 5

Prueba experimental

Este capítulo describe las pruebas que se realizaron para evaluar la efectividad
de la solución propuesta en el capítulo 4. La sección 5.1 describe los conjuntos de datos
utilizados. Los mismos fueron extraídos de una colección reconocida como un estándar
dentro de la comunidad de investigadores dedicados a la categorización automática de
documentos. En las secciones 5.2 y 5.3 se detalla la metodología seguida en la
experimentación. Se enumeran las variables que intervienen en los experimentos y los
distintos tipos de experimentos realizados. La sección 5.4 presenta los resultados de la
experimentación. La presentación se hace en forma de gráficos y para cada variable se
incluye además el resultado del test estadístico realizado sobre los resultados. En la
sección 5.5 se analizan brevemente los resultados, que luego se tratan con más detalle
en el capítulo 6.

5.1 Conjunto de datos utilizado

Para la realización de los experimentos, se utilizaron datos de la Colección de


Prueba para Categorización de Documentos “Reuters 21578” [Lewis, 1997]. Ésta
colección se ha convertido en un estándar “de facto” dentro del dominio de la
categorización automática de documentos y es utilizada por numerosos autores de la
materia [Joachims, 1998; Yang et.al., 2000; Steinbach et.al., 2000; Zhao et.al., 2001].
La búsqueda de “Reuters 21578” en el índice de recursos ResearchIndex/Citeseer
[Citeseer] (un sitio que se dedica a la publicación on-line de bibliografía especializada
en las ciencias de la computación), arroja alrededor de 80 documentos que la mencionan
o utilizan. Si se repite la búsqueda en el motor de búsqueda Google [Google], los
resultados traen cerca de 1.000 páginas web, entre las cuales se encuentran páginas de
productos comerciales que realizan categorización de documentos y que utilizan esta
colección para sus pruebas.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 79


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Los documentos en la colección son noticias reales que aparecieron en cables de


la agencia Reuters durante 1987. Los documentos fueron recopilados y categorizados
manualmente por personal de la agencia y de la compañía Carnegie Group, Inc., en
1987. En 1990, la agencia entregó los documentos al Laboratorio de Recupero de
Información (Information Retrieval Laboratory) de la Universidad de Massachusetts.
Desde 1991 hasta 1996, la colección se distribuyó bajo la denominación “Reuters
22173”. En 1996, durante la conferencia ACM SIGIR (una de las reuniones más
importantes en el campo de recupero de información y categorización de documentos),
un grupo de investigadores realizó un trabajo sobre esta colección con el objetivo de que
los resultados de distintos trabajos que utilizaran la colección fueran más fáciles de
comparar entre sí [ACM SIGIR, 1996]. El resultado fue la distribución 21578, que es la
que actualmente se utiliza en los trabajos sobre categorización automática de
documentos para asegurar una metodología de prueba uniforme. La colección se
compone de 21.578 documentos (cantidad que le da nombre a la misma), distribuidos en
22 archivos. Cada documento tiene 5 campos de categorización distintos: Valor
Bursatil, Organización, Persona, Lugar y Tema. En cada campo, el documento puede
tener un sólo valor, varios, o ninguno.
Los criterios utilizados en esta tesis para medir la calidad de un agrupamiento
requieren que cada documento tenga solamente una categoría asignada, por lo que para
los experimentos se decidió utilizar dos subconjuntos extraidos de esta colección
previamente utilizados por otros investigadores [Zhao et.al., 2001]. El procedimiento
seguido para extraer los subconjuntos fue tomar solamente los documentos que tenían
sólamente un valor en el campo “Tema”, luego dividir los posibles valores del campo en
dos subconjuntos y asignar a cada documento al subconjunto correspondiente. Esto dió
lugar a dos conjuntos de datos (re0 y re1), de 1504 y 1657 documentos respectivamente.
Las principales razones para usar estos documentos para las pruebas
experimentales fueron:
- La colección “Reuters 21578” es un estándar para la prueba de algoritmos de
categorización, por lo que los resultados obtenidos tendrán mucha más
validez que si los experiementos se realizaran sobre un conjunto de datos
recopilado sin seguir una metodología estándar.

80 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

- En los subconjuntos re0 y re1 extraidos de esta colección [Zhao et.al., 2001]
ya se han filtrado aquellos documentos sin clasificar, o con más de una
clasificación (que complican innecesariamente la evaluación de los
resultados) y son más fáciles de manipular que la colección completa.
- Los documentos de los subconjuntos re0 y re1 ya se han preprocesado
utilizando técnicas estándar. Primero, se han removido de cada documento
las palabras comunes que no sirven para el proceso de categorización,
utilizando una “stop list”, y el resto de las palabras fueron llevadas a su raíz
utilizando el algoritmo de Porter [Porter, 1980].

5.2 Variables a observar

Una vez que se obtienen los agrupamientos de documentos que arroja cada
algoritmo como salida, debe medirse cuantitativamente la calidad de cada uno para
poder compararlos.

5.2.1 Variables independientes

Los siguientes son los parámetros que pueden variarse con cada muestra de
datos y cada corrida de los algoritmos:
- Cantidad de documentos (N): es la cantidad de documentos que contiene la
muestra, y que se van a categorizar.
- Cantidad de grupos (K): es la cantidad de grupos que va a formar cada
algoritmo con los documentos de la muestra.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 81


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.2.2 Variables dependientes

A continuación se detallan las diversas medidas que se utilizaron para evaluar


los agrupamientos.

5.2.2.1 Similitud promedio


Esta es una medida “interna”, ya que puede evaluarse sin conocimentos externos
(no hace falta conocer la categorización “real” de los documentos). En el capítulo 2
(“Estado del arte”), sección 2.3, se describen las distintas formas de medir la similitud
entre dos documentos. Tal como se explica en esa sección, el uso del coeficiente del
coseno extendido es uno de los más difundidos, y es el que se utilizará para medir la
similitud entre dos documentos dados.
La similitud promedio (sim_prom) de un grupo es, justamente, la que surge de
promediar la similitud existente entre todos los documentos (d) del grupo tomados de a
pares. Por ejemplo, para el grupo j, que tiene nj elementos, utilizando el coeficiente del
coseno extendido como medida de similitud,

 
1  n j di • d j 
sim _ prom j = 2  ∑ 
n j  i =1 d i * d j 
 j= 1 

La similitud promedio de todo el agrupamiento se obtiene sumando la similitud


promedio de cada grupo multiplicada por la cantidad de elementos del grupo, y
dividiendo el total por la cantidad total de elementos de la muestra,

k
∑ n j * sim _ prom j
j =i
sim _ prom =
N

De esta manera se pondera la similitud promedio de cada grupo asignándole un


peso acorde con la cantidad de elementos que contiene. Esta ponderación permite que
un grupo grande con baja similitud promedio impacte negativamente en la evaluación
del agrupamiento y no sea compensado tan fácilmente por un grupo pequeño. Si no se

82 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

realizara esta ponderación, una muestra de 1.000 documentos que se dividiera en un


grupo de 900 elementos con muy baja similitud promedio y 10 grupos compactos de 10
elementos cada uno, podría sumar mejor similitud promedio que un agrupamiento
balanceado de 11 grupos con buena similitud promedio en cada uno.
Esta medida da cuenta de cuánto tienen en común los elementos de cada grupo.
Cuanto más homogeneo sea cada grupo, mayor valor tendrá este parámetro. Valores
más grandes de similitud promedio indican una mejor calidad del agrupamiento.

5.2.2.2 Entropía
La entropía es una medida “externa” (para calcularla es necesario conocer a qué
categoría “real” pertenece cada documento). El concepto de entropía tiene su origen en
el campo de la física (más especificamente, en el area de la termodinámica), y es
utilizada como medida del grado de desorden de un sistema [Carter, 2000]. En 1948,
Shannon [Shannon, 1948] incorpora el término a la teoría de la información como una
función que mide la cantidad de información generada por un proceso.
Un ejemplo simple permitirá entender qué es lo que mide la entropía y cómo
puede utilizarse para medir la calidad de un agrupamiento dado. Supóngase que se tiene
un grupo con 1000 documentos de 8 categorías distintas. Una persona debe tomar cada
documento, y escribir un código (en forma binaria) para describir la categoría a la cual
pertenece. La forma más simple de hacerlo sería escribir, para cada documento, el
número de la categoría (de 0 a 7), en base 2. Para esto, necesitaría 3 bits por cada
documento (en base 2 se requieren 3 bits para codificar los números 0 a 7).
Supóngase ahora que los documentos del grupo no pertenecen a cada categoría
en cantidades iguales, sino que el 42% de los documentos son de la primer categoría, el
40% son de la segunda categoría, y el 18% restante pertenece a las otras 6 categorías en
cantidades iguales. La persona encargada de anotar la categoría de cada documento
podría desarrollar una codificación más eficiente (la forma simple, descrita
anteriormente le insumía 3 bits por cada uno). Por ejemplo, podría adoptar el siguiente
código:

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 83


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

CATEGORÍA CÓDIGO PROBABILIDAD

0 00 42%
1 01 40%
2 1000 3%
3 1001 3%
4 1010 3%
5 1011 3%
6 1100 3%
7 1101 3%

Puede calcularse fácilmente, que, al utilizar solamente 2 bits en el 82% de los


casos, y 4 bits en el 18% de los casos restantes, estará utilizando en promedio 2,36 bits
por cada documento. Aplicada a una situación como la descrita anteriormente, la
entropía mide justamente la mínima cantidad de bits promedio para codificar la
categoría de cada documento del grupo.
Si se tienen h categorías y pi es la probabilidad de que un documento sea de la
categoría i, la formula para calcular la entropía en una situación como ésta es,
h
H = −∑ pi * log( pi ) . La máxima entropía se obtiene cuando los documentos
i =0

pertenecen en cantidades iguales a las categorías (en ese caso, H = 3, que es el caso de
la codificación en base 2 del número de categoría). En el caso que se describe en la
tabla, el valor de H es aproximadamente 1,96, lo que indica que la codificación elegida
no es la óptima. Cuanto más desparejas sean las probabilidades, el valor de la entropía
irá disminuyendo. Si todos los documentos del grupo fueran de una sóla categoría, el
sistema estará totalmente ordenado, y la entropía será igual a 0 (no hará falta escribir de
qué categoría es cada documento).
Para medir la calidad de un agrupamiento utilizando la entropía, primero se
calcula entropía de cada grupo. Para cada categoría “real” i, se calcula la probabilidad
nij
pij de que un miembro del grupo j sea de la categoría i, pij = n j , donde nij es la

cantidad de documentos de la categoría i que se encuentran en el grupo j y nj es la


cantidad de documentos del grupo j. La entropía de cada grupo se calcula usando la

84 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

fórmula: H j = −∑ pij * log( pij ) , donde i recorre todas las categorías “reales” de los
i

documentos.
La entropía total del agrupamiento se calcula luego ponderando la entropía de
cada grupo de acuerdo a su tamaño,
k
∑n j * H j
j =1
H=
N

La entropía tendrá un valor máximo cuando los documentos de cada categoría


estén distribuidos uniformemente entre los grupos, y un valor igual a 0 cuando cada
categoría tenga sus documentos en un sólo grupo. Valores más chicos de entropía
indican una mejor calidad del agrupamiento.

5.2.2.3 Cantidad de operaciones


Esta medida no se relaciona con la calidad del agrupamiento obtenido, sino con
la eficiencia del algoritmo. La cantidad de operaciones da una medida de la complejidad
computacional del algoritmo [Wilf, 1986], ya que mide el esfuerzo computacional que
llevó al algoritmo obtener el agrupamiento, en una escala que es independiente de los
recursos de hardware sobre los cuales se realizaron las pruebas (velocidad del
procesador, memoria, velocidad del disco, etc).
Las tres operaciones básicas que se repiten en los algoritmos evaluados son:
- Multiplicación de 2 vectores (para calcular la similitud entre los
documentos),
- Cálculo de la norma de un vector (para calcular la similitud promedio de un
grupo se calcula la norma del centroide),
- Sumas de vectores (cuando se cambia un elemento de un grupo a otro deben
actualizarse los centroides).
Para simplificar las mediciones, se supuso que las 3 operaciones eran
equivalentes (multiplicar dos vectores lleva el mismo esfuerzo computacional que
sumar dos vectores o calcular la norma de un vector). Por la naturaleza de las
operaciones (todas iteran sobre los elementos de un vector realizando operaciones

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 85


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

algebraicas), es una aproximación razonable. De todas maneras, alrededor del 90% de


las operaciones que realizan los algoritmos son multiplicaciones de vectores, por lo que
el error es despreciable. Lógicamente, un menor número de operaciones realizadas (para
resultados similares) indica una mayor eficiencia del algoritmo.

5.3 Realización de los experimentos

Los algoritmos que se compararon fueron:


- Bisecting K-Means con refinamiento (capítulo 2, sección 2.6).
- Algoritmo Genético (capítulo 4, sección 4.2).
- Algoritmo Genético con refinamiento (capítulo 4, sección 4.2.11)

5.3.1 Metodología utilizada

Se realizaron dos tipos de experimentos. El primero consistió en tomar muestras


de datos con una cantidad de documentos fija, y realizar corridas de los algoritmos
variando la cantidad de grupos a formar. La segunda clase de experimentos consistió en
tomar muestras de datos con diferentes cantidades de documentos, y realizar corridas de
los algoritmos formando una cantidad fija de grupos. El análisis estadístico de los
resultados (aplicando el test de Wilcoxon, que se detalla en el apéndice 2) se realizó
sobre los resultados del primer tipo de experimentos, ya que sus valores son más
facilmente comparables por provenir de corridas sobre muestras con la misma cantidad
de documentos. El segundo tipo de experimentos se utilizó para comprobar y validar las
conclusiones que se extrajeron del análisis de los resultados del primer tipo de
experimentos.

5.3.1.1 Experimentos variando la cantidad de grupos


La forma más simple de realizar los experimentos hubiera sido tomar cada
subconjunto (re0 y re1) como una muestra de datos, aplicar cada uno de los algoritmos a
evaluar, y comparar los resultados. Sin embargo, se hubieran obtenido sólamente dos

86 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

conjuntos de resultados, lo que hubiera hecho muy dificil un análisis estadístico de los
mismos. El rendimiento de los algoritmos se hubiera comparado basándose solamente
en la categorización de dos muestras, que podrían haber sido casos favorables para
alguno de ellos, quitándole validez a las conclusiones.
Con el objetivo de obtener resultados que fueran válidos desde un punto de vista
estadístico, tratando de minimizar las probabilidades de que un caso particular favorable
a uno u otro algoritmo influyera en los resultados en forma excesiva, se prepararon las
muestras de datos de la siguiente manera: de cada subconjunto de datos (re0 y re1) se
extrajeron 10 muestras de 500 documentos al azar, y se realizaron 5 corridas de cada
algoritmo sobre cada muestra. De esta manera, los resultados particulares que no
reflejan el comportamiento estadístico de los algoritmos tienen menos posibilidades de
distorsionar los resultados.
Para cada una de las muestras de datos, se obtuvieron agrupamientos de 5, 10, 15
y 20 grupos con cada algoritmo y se calcularon las medidas de evaluación para cada
uno. El procedimiento se repitió 5 veces, y se promediaron las medidas de evaluación de
las 5 iteraciones. Esto dió como resultado 20 tablas (una para cada muestra de datos),
con las medidas de evaluación de cada algoritmo para los agrupamientos de 5, 10, 15 y
20 grupos. Promediando los valores de las 20 tablas, se construyó una tabla de
promedios generales, con el valor promedio de cada medida de evaluación para cada
algoritmo, para los agrupamientos de 5, 10, 15 y 20 grupos.
Para la confección de los gráficos, se utilizó la tabla de promedios generales.
Para la realización del test de Wilcoxon, se utilizaron los valores cada una de las 20
tablas, ya que cada una de ellas se corresponde a una muestra de datos.

5.3.1.2 Experimentos variando la cantidad de documentos


Se tomaron muestras al azar de 400, 700, 1000 y 1300 documentos del primer
conjunto de datos (re0). Para cada tamaño se tomaron 3 muestras de datos, y se
realizaron 5 corridas de cada algoritmo, formando agrupamientos de 10 grupos. Para la
confección de los gráficos se promediaron los valores para las 5 corridas de cada
algoritmo sobre cada muestra de datos.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 87


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.3.2 Parámetros utilizados por el algoritmo genético

En el Apéndice 1 se detallan las experiencias realizadas para obtener todos los


valores de los parámetros utilizados por el algoritmo.
Los valores utilizados para los parámetros más importantes son:
- Generaciones: se varió la cantidad de generaciones de acuerdo con la
cantidad de documentos a categorizar según la formula descripta en el
capítulo 4 (“Solución Propuesta”). Para un tamaño de muestra de 500
documentos, esta fórmula indica que deben ejecutarse 50 generaciones.
- Tamaño de población:
- Generación 1 a 20: 12 individuos
- Generación 20 a 50: 10 individuos
- Probabilidad de aplicar el operador de mutación “Refinar KM”:
- Generación 1 a 40: 10%
- Generación 40 a 50: 25%
- Tamaño y presión selectiva del torneo:
- Generación 1 a 10: tamaño 2, presión 75%
- Generación 10 a 20: tamaño 3, presión 75%
- Generación 20 a 40: tamaño 3, presión 80%
- Generación 40 a 50: tamaño 3, presión 85%

88 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.4 Resultados
5.4.1 Experimentos variando la cantidad de grupos

En esta sección se presentan los resultados que se obtuvieron en los


experimentos realizados variando la cantidad de grupos. Para seguir el comportamiento
de cada una de las variables independientes al ir variando la cantidad de grupos, se
confeccionaron gráficos con los promedios generales para cada algoritmo. En cada
gráfico, el eje “x” representa la cantidad de grupos en que se fueron dividiendo las
muestras de datos con los algoritmos. El eje “y” representa la variable independiente
que se mide en cada gráfico. El título del gráfico lleva el nombre de la variable
independiente. Los valores que se grafican son los promedios generales para cada
algoritmo.
Además, se utilizó el test de Wilcoxon sobre cada una de las variables para
obtener un análisis estadístico de los resultados.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 89


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Similitud Promedio

0,2

0,18

0,16

0,14
Bisecting KM Ref
Genetico
0,12
Genetico Ref

0,1

0,08
5 10 15 20
Cant. Grupos

Fig 5.1
Similitud promedio de los agrupamientos encontrados en función de la cantidad de grupos.

La figura 5.1 muestra la similitud promedio de los agrupamientos encontrados


en función de la cantidad de grupos armados. La curva de resultados del algoritmo
“Genético” se encuentra ligeramente por encima de la curva del algoritmo “Bisecting K-
Means con refinamiento”, mientras que la curva para el algoritmo “Genético con
refinamiento” supera claramente a la del algoritmo “Bisecting K-Means con
refinamiento”. Esta apreciación es consistente con los resultados que arroja el test de
Wilcoxon para esta variable (que se detalla en el apéndice 2). Tomando en cuenta los
resultados de las 20 muestras, el test permite afirmar con un margen de confianza del
95% que el promedio de valores de similitud promedio para el algoritmo “Bisecting K-
Means con refinamiento” es inferior al de los otros 2 algoritmos.

90 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Entropía
Bisecting KM Ref
Genetico
1,9
Genetico Ref

1,8

1,7

1,6

1,5

1,4

1,3

1,2
5 10 15 20
Cant. Grupos

Fig 5.2
Entropía de los agrupamientos encontrados en función de la cantidad de grupos.

La figura 5.2 muestra la entropía de los agrupamientos encontrados en función


de la cantidad de grupos armados. Las curvas de resultados de los algoritmos
“Genético” y “Bisecting K-Means con refinamiento” son bastante similares, y tienen
diferencias en uno y otro sentido que no permiten afirmar que una sea mejor que la otra,
mientras que la curva para el algoritmo “Genético con refinamiento” está claramente
por debajo de ambas. Esta apreciación es consistente con los resultados que arroja el test
de Wilcoxon para esta variable. Tomando en cuenta los resultados de las 20 muestras, el
test no puede distinguir si los valores de entropía son diferentes para los algoritmos
“Genético” y “Bisecting K-Means con refinamiento”, mientras que permite afirmar con
un grado de confianza de 95% que los valores para el algoritmo “Genético con
refinamiento” son menores que para el algoritmo “Bisecting K-Means con
refinamiento”.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 91


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Cant. Operaciones
Bisecting KM Ref
Genetico
200000
Genetico Ref

180000

160000

140000

120000

100000

80000

60000
5 10 15 20
Cant. Grupos

Fig 5.3
Cantidad de operaciones realizadas por los algoritmos en función de la cantidad de grupos.

La figura 5.3 muestra la cantidad de operaciones realizada por los algoritmos en


función de la cantidad de grupos armados. Se ve claramente que los valores para el
algoritmo “Genético” están muy por debajo que los del algoritmo “Bisecting K-Means
con refinamiento”, mientras que para el algoritmo “Genético con refinamiento” se
encuentran en una posición intermedia, tambien claramente por debajo del algoritmo
“Bisecting K-Means con refinamiento”. Esta apreciación es consistente con los
resultados que arroja el test de Wilcoxon para esta variable. Tomando en cuenta los
resultados de las 20 muestras, el test permite afirmar con un margen de confianza del
95% que el promedio de operaciones realizadas por el algoritmo “Bisecting K-Means
con refinamiento” es superior en más de un 40% a las realizadas por el algoritmo
“Genético” y en más de un 15% a las realizadas por el algoritmo “Bisecting K-Means
con refinamiento”.

92 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.4.2 Experimentos variando la cantidad de documentos

Se graficó la evolución de las variables independientes para cada algoritmo al


variar la cantidad de documentos a agrupar con el fin de comprobar si su
comportamiento seguía las tendencias encontradas durante la realización del primer tipo
de experimento. En cada gráfico, el eje “x” representa la cantidad de documentos de las
muestras que se agruparon. El eje “y” representa los valores de la variable
independiente que se está graficando. Cada gráfico lleva como título el nombre de la
variable independiente que se grafica.

Similitud promedio
Bisecting KM Ref
0,172 Genetico Ref
0,17 Genetico
0,168
0,166
0,164
0,162
0,16
0,158
0,156
0,154
300 500 700 900 1100 1300

Fig 5.4
Similitud promedio de los agrupamientos encontrados en función de la cantidad de documentos.

La figura 5.4 muestra la evolución de la similitud promedio de los


agrupamientos encontrados al variar la cantidad de documentos. Puede observarse que
se confirma la tendencia encontrada. La curva de similitud promedio para el algoritmo
“Bisecting K-Means con refinamiento” se encuentra por debajo de las curvas para los
algoritmos “Genético” y “Genético con refinamiento”.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 93


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Entropía Bisecting KM Ref


Genetico Ref
1,56 Genetico
1,54
1,52
1,5
1,48
1,46
1,44
1,42
1,4
1,38
1,36
300 500 700 900 1100 1300

Fig 5.5
Entropía de los agrupamientos encontrados en función de la cantidad de documentos.

La evolución de la entropía con la cantidad de grupos (figura 5.5) muestra el


mismo comportamiento observado en el primer tipo de experimento, aunque en este
gráfico la entropía para los agrupamientos encontrados por el algoritmo “Genético” es
menor que para el algoritmo “Bisecting K-Means con refinamiento”, aunque esto puede
deberse a particularidades de las muestras utilizadas, ya que el análisis estadístico
realizado con los resultados del primer tipo de experimento no permitían afirmar esto.

94 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Cant. Operaciones

Bisecting KM Ref
550000 Genetico Ref
500000 Genetico
450000
400000
350000
300000
250000
200000
150000
100000
50000
300 500 700 900 1100 1300

Fig 5.6
Cantidad de operaciones realizadas por los algoritmos en función de la cantidad de documentos.

La cantidad de operaciones en función de los documentos a agrupar (figura 5.6)


sigue la tendencia esperada, siendo el algoritmo “Bisecting K-Means con refinamiento”
el que requiere mayor cantidad de operaciones, seguido por el algoritmo “Genético con
refinamiento” y quedando el algoritmo “Genético” en tercer lugar.

Eugenio Yolis CAPITULO 5 - PRUEBA EXPERIMENTAL 95


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

5.5 Análisis de los resultados

A partir de los gráficos y el análisis estadístico de los resultados, pueden


responderse en base a los resultados experimentales las cuestiones 1 y 2 planteadas en el
capítulo 3 (“Descripción del problema”).

Cuestión 1: ¿Pueden ayudar los algoritmos genéticos a explorar el espacio de búsqueda


en forma más eficiente?
Los resultados experimentales demuestran que si, ya que los algoritmos
“Genético” y “Genético con refinamiento” encuentran soluciones de igual o mayor
calidad que el algoritmo “Bisecting K-Means con refinamiento” tomado como
referencia, requiriendo una menor cantidad de operaciones para lograrlo.

Cuestión 2: ¿ Pueden ayudar los algoritmos genéticos a encontrar soluciones de mejor


calidad?
Los resultados muestran que las soluciones encontradas por los algoritmos
“Genético” y “Genético con refinamiento” son de mayor calidad que las halladas con el
algoritmo “Bisecting K-Means con refinamiento” tomado como referencia, para las
medidas de calidad definidas.

96 CAPITULO 5 – PRUEBA EXPERIMENTAL Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Capítulo 6
Conclusiones

En esta tesis se propone una adaptación de un algoritmo genético al problema de


la categorización automática de documentos, que incluye el diseño de un nuevo
operador de cruza y cuatro operadores de mutación. Los resultados experimentales
obtenidos confirman la tesis que los algoritmos genéticos son una poderosa herramienta
para la resolución de problemas en los cuales el espacio de soluciones es amplio y la
función de optimización es compleja.
Se ha encontrado tambien que, tal como lo han afirmado otros autores
[Falkenauer, 1999; Estivill-Castro, 2000], los algoritmos genéticos no son un método de
solución universal de problemas, sino un paradigma que debe adaptarse correctamente
al problema a resolver. El algoritmo propuesto logra resultados efectivos porque en el
diseño del mismo se han adaptado los conceptos que aplican los algoritmos genéticos y
se han creado nuevos operadores específicos para el problema a resolver.

Respuesta a las cuestiones planteadas

Cuestión 1: ¿Pueden ayudar los algoritmos genéticos a explorar el espacio de búsqueda


en forma más eficiente?
Los resultados presentados en el capítulo 5 muestran que el algoritmo genético
propuesto encuentra soluciones de mejor calidad que el algoritmo “Bisecting K-Means
con refinamiento”, requiriendo una menor cantidad de operaciones para lograrlo. La
explicación a este hecho debe buscarse en la forma que tienen de explorar el espacio de
posibles agrupamientos tanto el algoritmo “Bisecting K-Means” como el algoritmo
genético propuesto. Se ha mostrado en el capítulo 3 (“Descripción del problema”), por
qué la forma de explorar el espacio de soluciones del algoritmo “Bisecting K-Means” es
subóptima.

Eugenio Yolis CAPITULO 6 - CONCLUSIONES 97


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

El algoritmo “Genético”, al crear nuevos grupos (o modificar los existentes) con


cualquiera de sus operadores, no descarta de inmediato ninguno de ellos, aunque sean
malas soluciones. Los malos agrupamientos se van eliminando más tarde mediante el
operador de selección. Mientras tanto, esos agrupamientos pueden ser seleccionados
para su cruza con otros, momento en el cual tienen la oportunidad de pasar alguna de
sus características positivas a uno de sus hijos. Es el operador de cruza el que permite al
algoritmo “Genético” obtener su solución en forma más eficiente, ya que puede
aprovechar las buenas características de cada una de las variaciones que se fue
realizando, por lo que prácticamente ningún trabajo es desperdiciado.

Cuestión 2: ¿ Pueden ayudar los algoritmos genéticos a encontrar soluciones de mejor


calidad?
Las soluciones halladas por el algoritmo genético propuesto son de mayor
calidad (de acuerdo a las medidas definidas) que las del algoritmo “Bisecting K-Means
con refinamiento”, según lo muestran los resultados expuestos en el capítulo 5. El
algoritmo “Bisecting K-Means” no puede llegar a ninguna solución que le obligue a
pasar por un punto en el que disminuya el criterio de optimización (siempre elige la
división que más hace crecer el criterio de optimización). Esto hace que haya regiones
del espacio de búsqueda a las que le pueda resultar difícil llegar.
Por otra parte, el algoritmo “Genético” es capaz de generar soluciones de menor
calidad como parte del proceso, y extraer características positivas de ellas. De esta
manera, el algoritmo genético nunca se encuentra restringido a una región del espacio
de búsqueda. Los elementos de azar que intervienen en la cruza y la mutación pueden
llegar a generar agrupamientos en cualquier punto del espacio de búsqueda. La figura
6.1 ilustra éste concepto. La figura muestra un espacio de búsqueda unidimensional
(simplificación necesaria para que se lo pueda graficar en forma simple), en la que la
curva representa el valor del criterio de optimización para cada punto.

98 REFERENCIAS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

La figura muestra con símbolos cuadrados dos posibles agrupamientos entre los
cuales debe elegir el algoritmo “Bisecting K-Means”. Este algoritmo elegirá la solución
con mayor valor para el criterio de optimización, y esto puede tener como consecuencia
que se encuentre una solución subóptima, ya que tal vez la región con el máximo más
alto nunca se explore. Los símbolos triangulares representan los posibles miembros de
la población del algoritmo genético. Si los operadores del algoritmo genético generaran
el agrupamiento graficado con línea punteada, este agrupamiento pasaría a formar parte
de la población (aún cuando existan soluciones mejores), dándole al algoritmo genético
la posibilidad de explorar esa región.

Fig 6.1
Comparación de la exploración de los algoritmos “Bisecting K-Means con refinamiento” y “Genético”.

Cuestión 3: ¿De qué manera puede definirse la representación de las soluciones y el


operador de cruza para que el algoritmo genético pueda ser aplicado a la categorización
automática de documentos de acuerdo a la hipótesis de los bloques constructores?
Esta cuestión se responde en las secciones 4.2.1 y 4.2.6.1, que detallan la
representación utilizada en el algoritmo propuesto y el operador de cruza “Cruza Pasa
Grupo” diseñado para trabajar sobre esa representación. Este operador de cruza asegura
que se transfieran características significativas entre los miembros de la población,
llevando a que el algoritmo genético opere dentro de la hipótesis de los bloques
constructores.

Eugenio Yolis CAPITULO 6 - CONCLUSIONES 99


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Cuestión 4: ¿De qué manera pueden diseñarse los operadores del algoritmo genético
para hacer uso del conocimiento específico del dominio?
Los 5 nuevos operadores presentados como parte de la solución propuesta (el
operador de cruza y los 4 operadores de mutación, que se detallan en las secciones
4.2.6.1 y 4.7) dan respuesta a esta cuestión. Estos operadores hacen uso de esta
información para guiar la búsqueda del algoritmo genético por regiones donde haya más
posibilidades de encontrar soluciones de buena calidad.

100 REFERENCIAS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Referencias
ACM SIGIR. (1996). Proceedings of the 19th annual international ACM SIGIR
conference on Research and development in information retrieval, ACM
Press, New York, USA.

Allen, R. B., Obry, P. y Littman, M. (1993). An interface for navigating clustered


document sets returned by queries, Proceedings of the ACM Conference on
Organizational Computing Systems.

Anderberg, Michael R. (1973). Cluster analysis for Applications. Academic Press, New
York.

Bezdeck, J. C., Boggavaparu, S., Hall, L. O. y Bensaid, A. (1994). Genetic algorithm


guided clustering, in Proc. of the First IEEE Conference on Evolutionary
Computation, 3440.

Boley, D., Gini, M., Gross, R., Eui Hong, H., Hastings, K., Karypis, G., Kumar, V.,
Mobasher, B., Moore, J. (1999). Partitioning-based clustering for Web
Document Categorization. Decision Support Systems, volumen 27, número
3, páginas 329-341.

Box, G.E.P., Hunter, W.G., Hunter, J.S. (1978). Statistics for experimenters: An
introduction to design, data analysis and model building. John Wiley and
Sons, New York.

Bradley, P.S. y Fayyad, U.M. (1998). Refining initial points for k-means clustering. In
J. Shavlik, editor, Proceedings of the Fifteenth International Conference on
Machine Learning (ICML '98), pages 91--99, San Francisco, CA, 1998.
Morgan Kaufmann

Canavos, G.C. (1984). Probabilidad y estadística, Aplicaciones y Métodos. McGraw-


Hill.

Carter, T. (2000). An introduction to information theory and entropy. Complex Systems


Summer School.

Clerking, P., Cunningham, P., Hayes, C. (2001). Ontology Discovery for the Semantic
Web Using Hierarchical Clustering. Department of Computer Science,
Trinity College, Dublin.

Citeseer (Research Index). The NEC Research Institute Digital Library. Sitio dedicado a
la difusión de literatura científica. http://citeseer.nj.nec.com/.

Eugenio Yolis REFERENCIAS 101


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Cole, Rowena M. (1998). Clustering with Genetic Algorithms. Thesis for the degree of
Master of Science, Department of Computer Science, University of Western
Australia.

Croft, W. B. (1978). Organizing and searching large files of documents, Ph.D. Thesis,
University of Cambridge.

Cutting, D. R., Karger, D. R., Pedersen, J. O. y Tukey, J. W. (1992). Scatter/Gather: A


cluster-based approach to browsing large document collections,
Proceedings of the 15th International ACM SIGIR Conference on Research
and Development in Information Retrieval, Páginas 318-29.

Dash, M., y Liu, H. (2001). Efficient Hierarchical Clustering Algorithms Using


Partially Overlapping Partitions. Pacific-Asia Conference on Knowledge
Discovery and Data Mining, páginas 495-506.

Davis, L. (1991). Handbook of Genetic Algorithms. New York. Van Nostrand Reihold.

De Jong, K.A. (1975). An analysis of the behavior of a class of genetic adaptive


systems. Dissertation Abstracts International 36 (10), 514B. University of
Michigan, Microfilm No. 76-9381.

Dunlop, M.D. y Van Rijsbergen, C. J. (1991). Hypermedia and free text retrieval.
RIA091 Conference, Barcelona.

Duran, B. S. y Odell, P. L. (1974). Cluster Analysis: A survey. Berlin. Springer-Verlag.

Estivill-Castro, V. (2000). Hybrid Genetic Algorithms Are Better for Spatial Clustering.
Pacific Rim International Conference on Artificial Intelligence, pages 424-
434.

Estivill-Castro, V. y Murray, A. (1997). Spatial Clustering for Data Mining with


Genetic Algorithms. FIT, Technical Report, 97-10.

Everitt, Brian S. (1993). Cluster analysis. Halsted Press, 3ra edición.

Falkenauer, Emanuel. (1999). Evolutionary Algorithms: Applying Genetic Algorithms to


Real-World Problems. Springer, New York, Pag 65--88.

Faloutsos, Christos y Oard, Douglas W. (1995). A survey of Information Retrieval and


Filtering Methods. Technical Report CS-TR3514, Dept. of Computer
Science, Univ. of Maryland.

Fasulo, Daniel. (1999). An analysis of recent work on clustering algorithms. Technical


Report #01-03-12, Dept. of Computer Science & Engineering, University of
Washington.

102 REFERENCIAS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Goldberg, David E. (1989). Genetic Algorithms - in Search, Optimization and Machine


Learning. Addison-Wesley Publishing Company, Inc.

Google. Motor de búsqueda de páginas en internet. http://www.google.com/.

Guha, S., Rastogi, R., y Shim, K. (1998). CURE: An efficient clustering algorithm for
large databases. In Proceedings of 1998 ACM-SIGMOD International
Conference on Management of Data.

Hall, L.O., Ozyurt, B. y Bezdek, J.C. (1999). Clustering with a genetically optimized
approach. IEEE Trans. On Evolutionaty Computation, 3, 2, 103-112.

Han, J., Kamber, M. y Tung, A.K.H. (2001). Spatial clustering methods in data mining:
A survey. Geographic Data Mining and Knowledge Discovery, H. Miller
and J. Han, editors, Taylor and Francis.

Hearst, Marti A. y Pedersen, Jan O. (1996). Reexaminig the Cluster Hypothesis:


Scatter/Gather on Retrieval Results. Proceedings of ACM SIGIR ’96,
Zurich.

Hilera, J.R. y Martínez, V.J., (1995). Redes Neuronales Artificiales. Fundamentos,


Modelos y Aplicaciones. Editorial Ra-Ma, Serie Paradigma, Madrid.

Holland, J. H. (1975). Adaptation in natural and artificial systems. Ann Arbor: The
University of Michigan Press.

Honkela, T., Kaski, S., Lagus, K., y Kohonen, T. (1996). Newsgroup exploration with
WEBSOM method and browsing interface. Technical Report A32, Helsinky
University of Technology, Laboratory of Computer and Information
Science.

ISO/IEC 2382-1:1993 Information technology -- Vocabulary --. Part 1: Fundamental


terms

Jain, A. K., Murty, M.N., y Flinn, P.J. (1999). Data Clustering: A review. ACM
Computing Surveys, Vol. 31, Nro 3, Septiembre 1999.

Joachims, T. (1998). Text Categorization with Support Vector Machines: Learning with
Many Relevant Features. Proceedings of ECML-98, 10th European
Conference on Machine Learning, Springer Verlag, Heidelberg, DE.

Johnson, A., Fotouhi, F. (1996). Adaptive Clustering of Hypermedia Documents.


Information Systems, Vol. 21, No. 6, pp. 459.

Jones, D. R. y Beltramo, M. A. (1991) Solving partitioning problems with genetic


algorithms. Proceedings of the fourth International Conference on Genetic
Algorithms, pages 442-449.

Eugenio Yolis REFERENCIAS 103


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Jones, G., Robertson, A.M., Santimetvirul, C. y Willet, P. (1995). Non-hierarchical


document clustering using a genetic algorithm. Information Research, an
electronic journal, Vol 1, No 1, April, 1995.

Kaufmann, Leonard y Rousseeuw, Peter J. (1990). Finding Groups in data: An


introduction to Cluster Analysis, John Wiley & Sons, Inc., NY.

Karipys, G., Han, E.H., Kumar, V. (1999). CHAMELEON: A hierarchical clustering


algorithm using dynamic modeling, IEEE Computer: Special Issue on Data
Analysis and Mining, 32(8), 68-75.

Kohonen, T. (1982). Self-organized formation of topologically correct feature maps,


Biological Cybernetics, 43 : 59-69.

Koza, John R. (1997). Genetic Programming. Cambridge : M.I.T. Press.

Krovetz, R. (1993). Viewing morphology as an inference process. In Proceedings of


ACM-SIGIR93, pages 191--203

Leousky, A. V. y Croft, W. B. (1996). An evaluation of techniques for clustering search


results, Technical Report IR-76, Department of Computer Science,
University of Massachusetts, Amherst.

Lewis, D. (1991). Evaluating text categorization, Proceedings of the Speech and


Natural Language Workshop, Asilomar, Morgan.

Lewis, D. (1997). Reuters-21578 text categorization test collection,


http://www.daviddlewis.com/resources/testcollections/reuters21578/ ó
http://kdd.ics.uci.edu/databases/reuters21578/reuters21578.html.

Liu, G.L. (1968). Introduction to combinatorial mathematics, McGraw Hill.

Maarek, Yoelle S., Fagin, Ronald, Ben-Shaul, Israel Z. y Pelleg, Dan. (2000).
Ephemeral Document Clustering for Web Applications. IBM Research
Report RJ 10186.

Macskassy, S.A., Banerjee, A., Davison, B.D., Hirsh, H. (2001). Human performance
on clustering web pages. Technical Report DCS-TR-355, Department of
computer Science, Rutgers, State University of New Jersey.

Mahfouz, S.Y., Toropov, V.V., Westbrook, R.K. (2000). Modification, tunning and
testing of a GA for structural optimization problems. Department of Civil
and Environmental Engineering, University of Bradford, UK.

Miller, B.L., Goldberg, D.E. (1995). Genetic algorithms, Selection Schemes and the
Varying Effects of Noise, IlliGAL report No. 95009.

104 REFERENCIAS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

McQueen, J. (1967). Some methods for classification and analysis of multivariate


observations, 5-th Berkeley Symposium on mathematics, Statistics and
Probability, 1, S. 281-298.

Myers, R.H., Montgomery, D.C. (1995). Response surface methodology: process and
product optimization using designed experiments. John Wiley and Sons,
New York.

Painho, M. y Bação, F. (2000). Using Genetic Algorithms in Clustering Problems.


Proceedings of the 5th International Conference on GeoComputation,
University of Greenwich, United Kingdom.

Pentakalos, O., Menascé, D. y Yesha, Y. (1996). Automated Clustering-Based


Workload Characterization. 5th NASA Goddard Mass Storage Systems and
Technologies Conference.

Porter, M. F., (1980). An Algorithm for Suffix Stripping, Program, vol.14, no. 3, 130-
137, 1980

Qin He, (1996). A review of clustering algorithms as applied in IR, UIUCLIS-


1996/6+IGR, University of Illinois at Urbana-Champaign.

Raghavan, V. V. y Birchard, K. (1978). A clustering strategy based on a formalism of


the reproductive process in natural systems. Proceedings of the 2nd
International Conference on Research and Development in Information
Retrieval. 10-22.

Raghavan, V., Bollmann, P., y Jung, G. (1989). A critical investigation of recall and
precision as measures of retrieval system performance. ACM Transactions
on Information Systems, 7(3):205--229.

Rasmussen, E. (1992). Clustering Algorithms, W. B. Frakes and R. Baeza-Yates,


editors, Information Retrieval, Páginas 419-442. Prentice Hall, Eaglewood
Cliffs, N. J.

Rüger, S. M. R. y Gauch, S. E. (2000). Feature reduction for document clustering and


classification. Technical report, Computing Department, Imperial College,
London, UK.

Sarle, W.S., ed. (1997) Neural Network FAQ, part 1 of 7: Introduction, actualización
periódica al grupo de noticias de Usenet comp.ai.neural-nets,
ftp://ftp.sas.com/pub/neural/FAQ.html

Schütze, Hinrich y Silverstein Craig (1997) Projections for Efficient Document


Clustering, in Proceedings of ACM/SIGIR’97, pp.74-81.

Shannon, C.E. (1948) A mathematical theory of communication, Bell System Technical


Journal, vol. 27, pp. 379-423 and 623-656, July and October.

Eugenio Yolis REFERENCIAS 105


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Steinbach, M., Karypis, G., y Kumar, V. (2000). A comparison of Document Clustering


Techniques. Technical Report #00-034. University of Minnesota. In KDD
Workshop on Text Mining.

Strehl, A., Ghosh, J. y Mooney, R. (2000). Impact of Similarity Measures on Web-page


Clustering. AAAI-2000: Workshop of Artificial Inteligence for Web
Search.

Trocine, L., Malone, L.C. (2000). Finding important independent variables through
screening designs: a comparison of methods. Proceedings of the 2000
Winter Simulation Conference, University of Central Florida, Orlando,
U.S.A.

Unal, R., Dean E.B. (1991). Taguchi approach to design optimization for quality and
cost: an overview, 1991 International Conference of the International
Society of Parametric Analysts.

Van Rijsbergen, C. J. (1979). Information Retrieval, Butterworths, London, 2da edición.

Webster, P.G. (2002). Design of experiments in the Möbius Modeling Framework,


Thesis presented for the degree of Master of Science in Electrical
Engineering, University of Illinois.

Wilf, H.S. (1986). Algorithms and Complexity, Prentice Hall.

Willet, P. (1998). Recent trends in hierarchical document clustering: a critical review.


Information Processing and Management. 24:577-97.

Yang, Y. (1997). An evaluation of statistical approaches to text categorization. School


of Computer Science, Carnegie Mellon University, CMU-CS-97-127.

Yang, Y. y Liu, Xin, (1999). A re-examination of text categorization methods. 22nd


Annual International SIGIR.

Yang, Y. y Pedersen J., (1997). A comparative study on feature selection in text


categorization. Proc. of the 14th International Conference on Machine
Learning ICML97, páginas 412 - 420.

Zamir, Oren y Etzioni, Oren. (1998). Web Document Clustering: A feasibility


demonstration. Proceedings of ACM/SIGIR’98.

Zamir, Oren y Etzioni, Oren. (1999). Grouper: A Dynamic Clustering Interface to Web
Search Results. Proceedings of the Eighth International World Wide Web
Conference, Computer Networks and ISDN Systems.

106 REFERENCIAS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Zhao, Y. y Karypis, G., (2001). Criterion Functions for Document Clustering.


Technical Report #01-40, Department of Computer Science, University of
Minnesota.

Zervas, Giorgio y Rüger, Stefan. (2000).The curse of dimensionality and document


clustering. Dept. of Computing, Imperial College, England.

Eugenio Yolis REFERENCIAS 107


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Apéndice 1
Determinación de parámetros para el algoritmo
Este apéndice detalla las pruebas realizadas para determinar los valores de cada
uno de los parámetros utilizados por el algoritmo genético.

A1.1 Parámetros a determinar

En esta sección se enumeran los parámetros del algoritmo genético, con la


descripción de la función que cada uno cumple en el mismo. Para cada parámetro se
indica el rango de valores posibles que puede tomar. El rango de variación de cada
parámetro se definió tomando en cuenta la naturaleza del mismo, o en base a pruebas
preliminares realizadas durante el diseño del algoritmo genético.

A1.1.1 generacionesMáximo
Este parámetro especifica el número fijo de generaciones que se ejecutará el
algoritmo genético. El valor de este parámetro debe ser dependiente de la cantidad de
documentos que se van a agrupar. Lo que debe determinarse es la fórmula para calcular
el número de generaciones en función de la cantidad de documentos.

A1.1.2 poblacionTamaño
Este parámetro indica el número de cromosomas en la población. El posible
rango de valores es de 10 a 50 cromosomas.

A1.1.3 torneoTamaño
Este parámetro determina el tamaño del torneo para el operador de selección.
Los valores para este parámetro pueden variar entre 2 y 4.

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 109


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.1.4 torneoProbMejor
Este parámetro especifica la probabilidad con la cual se elige al mejor individuo
del torneo en el operador de selección. Su valor puede variar entre 0.6 y 1.

A1.1.5 cruzaPasaGrupoProbMejor
Este parámetro indica la probabilidad de que, en el operador de cruza, el grupo
con mayor similitud promedio del padre que pasa el grupo se incluya en el hijo. Su
valor puede variar entre 0.6 y 1.

A1.1.6 mutacionRefinarKMProb
Este parametro especifica la probabilidad de aplicar el operador de mutación
“Refinar KM” a cada hijo generado por el operador de cruza. El posible rango de
valores es de 0 a 0.15.

A1.1.7 mutacionRefinarSelectivoProb
Este parametro especifica la probabilidad de aplicar el operador de mutación
“Refinar Selectivo” a cada hijo generado por el operador de cruza. El posible rango de
valores es de 0 a 0.1.

A1.2 Metodología utilizada

Existen numerosas técnicas para la realización de experimentos tendientes a la


determinación de parámetros de un sistema [De Jong, 1975; Box et.al., 1978; Unal
et.al., 1991; Mahfouz et.al., 2000; Trocine et.al., 2000; Webster, 2002]. A continuación
se describe la metodología adoptada en esta tesis. Para poder observar la variación del
rendimiento del algoritmo genético cuando se modifica el valor de alguno de sus
parámetros, se realizaron pruebas sobre muestras de datos seleccionadas al azar. Todas
las muestras utilizadas (excepto las utilizadas para determinar la cantidad de
generaciones) fueron de 500 documentos. En todos los experimentos realizados se
formaron conjuntos de 10 grupos.

110 APÉNDICE 1 - DETERMINACIÓN DE PARÁMETROS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Los experimentos para cada parámetro consistieron en hacer que el parámetro


estudiado tomara distintos valores, dejando fijo el valor de los otros parámetros. Los
parámetros que no se estaban evaluando se fijaron en un valor igual al promedio de los
extremos de sus rangos de valores. Esta metodología se denomina “un factor a la vez”
(en inglés: “one factor at a time”) y suele usarse para observar cómo afecta a un sistema
la modificación de uno de sus parámetros [Myers et.al., 1995; Webster, 2002]. Si bien
no permite percibir los efectos de comportamiento causados por la variación combinada
de más de un parámetro, da una buena noción de la sensibilidad del sistema con
respecto a cada uno de sus parámetros.
Durante la ejecución del algoritmo genético, se tomó el promedio de la función
de adaptación para los cromosomas de la población cada 5 generaciones, y se
confeccionaron curvas con la evolución de la aptitud promedio de la población en
función del número de generación. En cada gráfico se incluyó una curva para cada valor
del parámetro evaluado.
A continuación se listan los valores utilizados para cada parámetro en los
experimentos que no lo involucraban:
- poblacionTamaño : 30
- torneoTamaño : 3
- torneoProbMejor : 0.8
- cruzaPasaGrupoProbMejor : 0.8
- mutacionRefinarKMProb : 0.1
- mutacionRefinarSelectivoProb : 0.05

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 111


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3 Resultados

A1.3.1 generacionesMáximo
Se realizaron experimentos con muestras de datos tomadas al azar conteniendo
400, 700, 1000 y 1300 documentos, y se graficó la evolución de la aptitud promedio de
la población en función del número de generación para cada tamaño de muestra.

Cantidad de documentos

400 700 1000 1300 generacionesMáximo

0,17

0,15
Aptitud promedio

0,13

0,11

0,09

0,07

0,05
0 50 100 150 200
Generación

Fig A1.1
Aptitud promedio en función del número de generación para distintas cantidades de documentos.

Puede observarse que la evolución de las curvas es similar. Todas presentan un


crecimiento relativamente rapido en las primeras generaciones. Luego, la tasa de
crecimiento decrece paulatinamente y la aptitud promedio de la población tiende a
estabilizarse (la población converge). Como se describe en el capítulo 4 (“Solución
propuesta”), sección 4.2.10, se busca detener al algoritmo genético antes de la

112 APÉNDICE 1 - DETERMINACIÓN DE PARÁMETROS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

convergencia, ya que esta toma demasiado tiempo. En el gráfico se incluye una línea
que corta a cada curva en el punto donde se observa que el crecimiento comienza a ser
lento. Se encuentra experimentalmente que la función:
generacionesMaximo = (N / 20) + 25
donde N es la cantidad de documentos a categorizar, es una buena aproximación
de esta línea.

A1.3.2 poblacionTamaño

poblacionTamaño

10 20 30 40

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200
Generación

Fig A1.2
Aptitud promedio en función del número de generación para distintos tamaños de población.

Se observa que la evolución de la aptitud promedio no presencia variaciones


significativas para los distintos tamaños de población en el primer tramo de la curva.
Cuando la velocidad de evolución decrece, la mayor diversidad de material genético
presente en las poblaciones más grandes hace que éstas continúen evolucionando

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 113


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

(aunque muy lentamente), mientras que las poblaciones de pocos individuos convergen
rapidamente.
Para elegir el tamaño de la población a utilizar, se tuvieron en cuenta los
siguientes puntos:
- El algoritmo genético se detendrá antes de la convergencia de la población, y
en esa parte de la curva la evolución es similar para todos los tamaños de
población.
- El tamaño de la población impacta significativamente en la cantidad de
operaciones que requiere el algoritmo para llegar a una solución, ya que la
generación de cada individuo de la población inicial insume una cantidad de
operaciones considerable.
En el algoritmo propuesto, se comienza con un tamaño de población de 12
individuos, que se reduce a 10 una vez que han transcurrido el 40% de las generaciones
previstas. Se encontró experimentalmente que esta reducción en el tamaño de la
población aceleraba ligeramente la convergencia del algoritmo sin afectar la calidad de
la solución obtenida.

114 APÉNDICE 1 - DETERMINACIÓN DE PARÁMETROS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3.3 torneoTamaño

torneoTamaño
2 3 4

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200
Generación

Fig A1.3
Aptitud promedio en función del número de generación para distintos tamaños de torneo.

El comportamiento observado es el que podría esperarse a través de un análisis


teórico del impacto de este parámetro. Tamaños de torneo más grandes resultan en una
presión selectiva mayor, que acelera la evolución de la población hasta cierto punto,
pero provoca una convergencia prematura de la población hacia una solución
subóptima. En el algoritmo propuesto se utiliza un tamaño de torneo igual a 2 hasta que
transcurre el 20% de las generaciones previstas, que luego se cambia al valor 3. De esta
forma, se asegura que la presión selectiva al inicio (cuando hay más peligro de que
soluciones mediocres dominen la población) sea pequeña, para luego acelerar la
velocidad de evolución en forma moderada.

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 115


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3.4 torneoProbMejor

torneoProbMejor

0.6 0.8 1

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200
Generación

Fig A1.4
Aptitud promedio en función del número de generación para distintos valores del parámetro
probTorneoMejor.

Se observa que este parámetro tiene un impacto sobre la presión selectiva, que es
aún mayor que el del parámetro anterior (tamaño del torneo). Una presión selectiva
demasiado pequeña (valor igual a 0.6) no hace evolucionar a la población, mientras que
si es demasiado alta (valor igual a 1), se produce la convergencia prematura. El valor de
0.8 produce los mejores resultados. El algoritmo propuesto utiliza para este parámetro
un valor igual a 0.75 hasta que transcurre el 40% de las generaciones previstas, luego se
aumenta el valor a 0.8 hasta llegar al 80% de las generaciones, donde se vuelve a
aumentar a 0.85 para las generaciones restantes. De esta manera, se va acelerando
progresivamente la velocidad de evolución del algoritmo.

116 APÉNDICE 1 - DETERMINACIÓN DE PARÁMETROS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3.5 cruzaPasaGrupoProbMejor

cruzaPasaGrupoProbMejor

0.6 0.8 1

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200
Generación

Fig A1.5
Aptitud promedio en función del número de generación para distintos valores del parámetro
cruzaPasaGrupoProbMejor.

Un valor de 0.6 para este parámetro resulta demasiado pequeño y provoca una
involución de la población, ya que en un 40% de los casos el grupo que pasa al hijo es
seleccionado al azar, lo que puede ocasionar que los hijos sean soluciones de peor
calidad que los padres. Los valores de 0.8 y 1 presentan curvas de evolución similares.
En el algoritmo propuesto se utiliza un valor de 0.8 hasta que transcurre el 80% de las
generaciones previstas, y luego se aumenta este valor a 0.9, para acelerar la
convergencia en la fase final.

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 117


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3.6 mutacionRefinarKMProb

mutacionRefinarKMProb

0.05 0.1 0.15

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200

Generación

Fig A1.6
Aptitud promedio en función del número de generación para distintos valores del parámetro
mutacionRefinarKMProb.

Puede observarse que el operador de mutación Refinar KM es de suma


importancia para la evolución de la población, ya que (como se detalla en el capítulo 4)
utiliza conocimiento específico del dominio para mejorar la calidad de las soluciones.
Una probabilidad de 0.05 es demasiado baja para este operador, y la población no
alcanza soluciones de buena calidad. Con probabilidades de 0.1 ó 0.15 se obtienen
buenos resultados. En el algoritmo propuesto se utiliza un valor de 0.1 para este
parámetro hasta que transcurre el 80% de las generaciones previstas, y luego se aumenta
el valor a 0.25. De esta forma, en la fase final del algoritmo, cuando la evolución es más
lenta, se apunta a mejorar la calidad de las soluciones utilizando este operador.

118 APÉNDICE 1 - DETERMINACIÓN DE PARÁMETROS Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A1.3.7 mutacionRefinarSelectivoProb

mutacionRefinarSelectivoProb

0 0.05 0.1

0,18

0,16
Aptitud promedio

0,14

0,12

0,1

0,08

0,06
0 50 100 150 200

Generación

Fig A1.7
Aptitud promedio en función del número de generación para distintos valores del parámetro
mutacionRefinarSelectivoProb.

Puede observarse que la aplicación de este operador puede ser nociva para la
evolución de la población. Para un valor de probabilidad de 0.1, el algoritmo genético
no alcanza soluciones aceptables. Tal como se describe en el capítulo 4 este operador
suele formar unos pocos grupos con gran similitud promedio, aunque reduciendo la
calidad general de la solución mutada. Si se lo utiliza desde el inicio de la evolución,
cada vez que se aplica reduce la calidad del agrupamiento que muta, impidiendo que el
algoritmo alcance soluciones de buena calidad. En el algoritmo propuesto, se lo utiliza
solamente sobre el final del algoritmo (en el último 20% de las generaciones) con
probabilidad 0.3. En esta fase, casi todas las soluciones son de la misma calidad y este
operador permite obtener material genético no presente en las soluciones.

Eugenio Yolis APÉNDICE 1 - DETERMINACIÓN DE PARÁ METROS 119


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Apéndice 2
Análisis estadístico de los resultados
Este apéndice detalla el análisis estadístico hecho sobre los resultados que se
exponen en el capítulo 5, y que soportan las afirmaciones realizadas en la sección 5.4
(“Resultados”) de ese capítulo. Las nociones teóricas de probabilidad y estadística
fueron extraídas principalmente de [Canavos, 1984], pero son las mismas que pueden
encontrarse en cualquier texto relativo al tema.

A2.1 Prueba de hipótesis estadísticas

En todas las ramas de la ciencia, cuando un investigador hace una afirmación


con respecto a un fenómeno (que puede estar basada en su intuición, o en algún
desarrollo teórico que parece demostrarla), debe luego probar la misma mediante la
realización de experimentos. La experimentación consiste en armar un ambiente de
prueba en el que ocurra el fenómeno (o buscarlo en el ambiente real), y tomar
mediciones de las variables involucradas. Luego, se realizan análisis estadísticos de los
resultados para determinar si los mismos confirman la afirmación realizada.
Una hipótesis estadística es una afirmación con respecto a una característica
desconocida de una población de interés. La esencia de probar una hipótesis estadística
es el decidir si la afirmación se encuentra apoyada por la evidencia experimental que se
obtiene a través de una muestra aleatoria. Supóngase, por ejemplo, que los fabricantes
de tubos de luz marca ACME están teniendo problemas en el mercado debido a algunos
casos de mala calidad de sus productos. Para recuperar su prestigio, hacen la siguiente
afirmación: “El promedio de vida útil de los tubos de luz marca ACME es de 500
horas”. Y encargan a una firma independiente que haga una serie de experimentos para
contrastar esta afirmación con esta otra: “El promedio de vida útil de los tubos de luz
marca ACME es menor a 500 horas”.

Eugenio Yolis APÉNDICE 2 - ANÁLISIS ESTADÍSTICO 121


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A la afirmación “promedio = 500” se la llama hipótesis nula, y se escribe como:


H0 : promedio = 500
A la afirmación “promedio < 500” se la llama hipótesis alternativa, y se escribe
como:
H1 : promedio < 500
La hipótesis nula debe considerarse verdadera a menos que exista suficiente
evidencia en su contra. Es decir, se rechazará la afirmación de que la vida útil promedio
es de 500 horas sólo si la evidencia experimental se encuentra muy en contra de ésta
afirmación. En caso contrario, no se podrá rechazar la afirmación basándose en la
evidencia experimental. Debe notarse que no poder rechazar la afirmación no es lo
mismo que aceptarla. El caso es análogo al de un juicio, donde hay un sospechoso
acusado de un crimen: si la evidencia es suficiente, se lo declarará culpable. De lo
contrario, se dirá que la evidencia no alcanza para demostrar su culpabilidad.
Existen entonces dos posibles decisiones con respecto a la hipótesis nula:
rechazarla ó no poder rechazarla. A su vez, la hipótesis nula puede ser verdadera o falsa.
Esto deja cuatro posibles escenarios:

Cuando H0 es
Cuando H0 es
verdadera
verdadera No poder
(error Tipo I) Rechazar H0
Rechazar H0
Cuando H0
Cuando H0 es falsa (error
es falsa Tipo II)

Se denomina a a la probabilidad de cometer un error de tipo I, y ß a la


probabilidad de cometer un error de tipo II. Los valores de a y ß son interdependientes.
Para cada experimento, al disminuir uno de ellos, aumenta el otro. El error de tipo I se
considera más grave que el de tipo II (volviendo a la analogía con el juicio, se prefiere
dejar ir a un culpable y no condenar a un inocente), por lo que el procedimiento seguido
habitualmente consiste en fijar un valor pequeño para a (por ejemplo, 5%), y luego
tratar de minimizar ß lo más que se pueda.

122 APÉNDICE 2 - ANÁLISIS ESTADÍSTICO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A2.2 El test de Wilcoxon para la comparación de


medias de muestras apareadas

A2.2.1 Introducción

Existen numerosos métodos para la prueba de hipótesis estadísticas. El hecho de


que cada uno de ellos pueda aplicarse a una situación en particular depende de los
siguientes factores:
- La cantidad de mediciones realizadas;
- La naturaleza de los valores a analizar (si son valores en un intervalo
numérico, si son categorías cualitativas, si son del tipo SI/NO, etc);
- El grado de dependencia existente entre las mediciones.
Los experimentos realizados para comparar los algoritmos de categorización
automática de documentos, son un caso que se denomina “de muestras apareadas”, en el
cual se miden variables numéricas. Para estos casos, el test de Wilcoxon es el más
apropiado [Canavos, 1984]. El término “muestras apareadas” se refiere a que las
mediciones realizadas no son independientes, sino que son tomadas de a pares (la
muestra de datos 1 es categorizada con los algoritmos 1 y 2). Esto hace que lo que deba
analizarse sean las diferencias que existen en cada par de valores, que es precisamente
lo que hace el test de Wilcoxon.

A2.2.2 Descripción del test

Los experimentos para comparar dos algoritmos de categorización, con respecto


a una medida de calidad, se realizan de la siguiente forma:
- Se toman N muestras de datos,
- Se categorizan las muestras de datos con ambos algoritmos,
- Se mide una variable numérica que indica la calidad del agrupamiento.

Eugenio Yolis APÉNDICE 2 - ANÁLISIS ESTADÍSTICO 123


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Luego de la realización de los experimentos, se confecciona una tabla que tiene


la siguiente forma (ejemplo para 4 muestras):

Muestra Algoritmo 1 Algoritmo 2 Diferencia Ranking Ranking con


(1 -2) signo
1 0,79 0,80 -0,01 1 -1
2 0,46 0,51 -0,05 4 -4
3 0,91 0,87 0,04 3 3
4 0,23 0,25 -0,02 2 -2

Como se ve, los valores pueden tener grandes variaciones de muestra a muestra,
pero lo que importa es la diferencia entre los valores de cada algoritmo para cada
muestra, ya que eso es lo que indicará el mejor o peor rendimiento de cada uno.
La hipótesis nula que es puesta a prueba es que el promedio de los valores es
igual para los dos algoritmos (es decir, que las calidades de los agrupamientos
producidos es equivalente). Se plantean dos hipótesis alternativas, una de ellas afirma
que el promedio de los valores es mayor para el algoritmo 1, y la otra que el promedio
de los valores es mayor para el algoritmo 2.
La metodología del test es la siguiente:
- Se calculan las diferencias de los valores para cada muestra,
- Luego, se asigna a cada diferencia un valor en un ranking (de menor a
mayor) en base a su valor absoluto,
- Por último, a cada valor del ranking se le asigna el signo de la diferencia que
le dió origen.
Se denomina T+ a la suma de los valores positivos y T- a la suma de los
negativos. Si no hubiera diferencias entre los algoritmos, es de esperar que T+ resulte
igual a T- (en valor absoluto). Para muestras lo suficientemente grandes (N > 15), la
variable T+ puede aproximarse por medio de una distribución normal con media E(T+)
y varianza Var(T+), donde

N ( N + 1) N ( N + 1)( 2 N + 1)
E (T + ) = Var(T + ) =
4 24

124 APÉNDICE 2 - ANÁLISIS ESTADÍSTICO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Luego, si se define la transformación

(T + ) − E (T +)
zT + =
Var(T + )

La variable zT+ tiene una distribución normal estándar (media igual a 0 y


varianza igual a 1). El valor del parámetro a determina los límites mínimo y máximo
para el valor observado de zT+, más allá de los cuales se rechaza la hipótesis nula. Si el
valor de zT+ es superior al límite máximo, se aceptará la hipótesis alternativa de que el
promedio de valores para el algoritmo 1 es mayor que para el algoritmo 2. Si el valor de
zT+ es inferior al límite mínimo, se aceptará la hipótesis alternativa de que el promedio
de valores para el algoritmo 2 es mayor que para el algoritmo 1.

A2.3 Aplicación del test a los resultados

Tal como se describe en el capítulo 5, sección 5.3.1 (“Metodología Utilizada”),


se utilizaron 20 muestras de datos. Cada una de ellas se procesó con cada algoritmo para
producir agrupamientos de 5, 10, 15 y 20 grupos. Esto da un total de 20 * 4 = 80
mediciones realizadas, por lo que N = 80. El valor de a utilizado es de 5%, a = 0,05.
Esto quiere decir que, en los casos en que rechazemos la hipótesis nula y aceptemos
alguna hipótesis alternativa, el test nos dará un 95% de confianza.
Teniendo N y a, quedan definidos los límites mínimo y máximo para zT+, que
son respectivamente -1,645 y 1,645. Para cada variable se comparó al algoritmo
“Bisecting K-Means con refinamiento” con los algoritmos “Genético” y “Genético con
refinamiento”.

Eugenio Yolis APÉNDICE 2 - ANÁLISIS ESTADÍSTICO 125


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A2.3.1 Similitud promedio

Debe recordarse que valores más grandes para la similitud promedio indican una
mejor calidad del agrupamiento.

A2.3.1.1 “Bisecting K-Means con refinamiento” contra “Genético”


Valor de zT+ observado: -4,812
Consecuencia: Debe rechazarse la hipótesis nula y aceptarse la hipótesis
alternativa de que los valores para el algoritmo “Genético” son mayores que para el
algoritmo “Bisecting K-Means con refinamiento”.

A2.3.1.2 “Bisecting K-Means con refinamiento” contra “Genético con


refinamiento”
Valor de zT+ observado: -8,627
Consecuencia: Debe rechazarse la hipótesis nula y aceptarse la hipótesis
alternativa de que los valores para el algoritmo “Genético con refinamiento” son
mayores que para el algoritmo “Bisecting K-Means con refinamiento”.

126 APÉNDICE 2 - ANÁLISIS ESTADÍSTICO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A2.3.2 Entropía

Debe recordarse que valores más chicos para la entropía indican una mejor
calidad del agrupamiento.

A2.3.2.1 “Bisecting K-Means con refinamiento” contra “Genético”


Valor de zT+ observado: -1,076
Consecuencia: No puede rechazarse la hipótesis nula de que los valores son
iguales para los dos algoritmos.

A2.3.2.2 “Bisecting K-Means con refinamiento” contra “Genético con


refinamiento”
Valor de zT+ observado: 4,713
Consecuencia: Debe rechazarse la hipótesis nula y aceptarse la hipótesis
alternativa de que los valores para el algoritmo “Genético con refinamiento” son
menores que para el algoritmo “Bisecting K-Means con refinamiento”.

Eugenio Yolis APÉNDICE 2 - ANÁLISIS ESTADÍSTICO 127


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A2.3.3 Cantidad de operaciones

Para la variable Cantidad de operaciones se cambió la hipótesis nula, ya que el


objetivo no es demostrar sólamente que la cantidad de operaciones es menor (esto es
evidente viendo las gráficas del capítulo 5), sino que la diferencia es considerable.

A2.3.3.1 “Bisecting K-Means con refinamiento” contra “Genético”


La hipótesis nula se reformuló de la siguiente forma: La cantidad de
operaciones para el algoritmo “Bisecting K-Means con refinamiento” es un 40% mayor
que para el algoritmo “Genético”. Las hipótesis alternativas se reformularon para
afirmar que la diferencia era todavía mayor que el 40%, ó que no llegaba a ser del 40%.
Para realizar el test en estas condiciones, sólamente se requirió multiplicar la cantidad
de operaciones del algoritmo “Genético” por 1,4 y realizar el test de la forma habitual.
Valor de zT+ observado: 1,887
Consecuencia: Debe rechazarse la hipótesis nula y aceptarse la hipótesis
alternativa de que la diferencia es todavía mayor que el 40%.

A2.3.3.2 “Bisecting K-Means con refinamiento” contra “Genético con


refinamiento”
La hipótesis nula se reformuló de la siguiente forma: La cantidad de
operaciones para el algoritmo “Bisecting K-Means con refinamiento” es un 15% mayor
que para el algoritmo “Genético con refinamiento”. Las hipótesis alternativas se
reformularon para afirmar que la diferencia era todavía mayor que el 15%, ó que no
llegaba a ser del 15%. Para realizar el test en estas condiciones, sólamente se requirió
multiplicar la cantidad de operaciones del algoritmo “Genético con refinamiento” por
1,15 y realizar el test de la forma habitual.
Valor de zT+ observado: 2,101
Consecuencia: Debe rechazarse la hipótesis nula y aceptarse la hipótesis
alternativa de que la diferencia es todavía mayor que el 15%.

128 APÉNDICE 2 - ANÁLISIS ESTADÍSTICO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Apéndice 3
Manual de Uso
Este apéndice contiene la documentación de los programas y conjuntos de datos
que se incluyen en el CD que acompaña el presente trabajo. Estos programas hacen
posible la realización de los experimentos y la evaluación de los resultados.
La sección A3.1 describe el esquema de procesamiento, explicando la función de
cada componente en el proceso de experimentación. La sección A3.2 identifica la
ubicación de cada uno de los componentes en la estructura de directorios del CD. La
sección A3.3 explica cómo debe configurarse el origen de datos ODBC para que los
programas puedan acceder a la base de datos de datasets. La sección A3.4 detalla el
formato de los archivos que contienen los conjuntos de datos utilizados. En la sección
A3.5 se explica cómo utilizar el programa que genera subconjuntos de datos a partir de
los archivos que contienen la colección completa. La sección A3.6 contiene la
documentación del programa de agrupamiento. Éste programa es el que implementa los
algoritmos de agrupamiento descriptos durante el trabajo y permite utilizarlos para
agrupar los documentos de los subconjuntos de datos. La sección A3.7 describe el
programa que, a partir de la salida generada por el programa de agrupamiento, evalúa
las soluciones generadas y proporciona los valores para las distintas medidas de calidad.

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 129


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.1 Esquema de procesamiento

La figura A3.1 muestra gráficamente la forma en la que interactúa cada uno de


los componentes del proceso. Los archivos re0 y re1 son los conjuntos de datos
extraídos de la colección Reuters 21578, que se describe en el capítulo 5. El formato de
estos archivos se detalla en la sección A3.3.

Conjuntos de Programa Subconjuntos de


datos (re0 y re1) datos (re0_1,
“Armar Datasets”
re0_2, etc)

Programa
“AGDocClus”

Base de datos de
Agrupamientos
datasets (MDB)

Programa
“Evaluar Agrupamientos”

Planilla excel con


los resultados
Fig. A3.1: Esquema de procesamiento

130 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

El primer paso consiste en generar subconjuntos de datos que contengan


elementos (elegidos al azar) de estos archivos. Estos subconjuntos de datos se generan
en la forma de archivos con el mismo formato que los conjuntos originales, y además se
guardan en la base de datos de datasets. El programa “Armar Datasets” es el que hace
este trabajo. Luego, los archivos conteniendo cada subconjunto son procesados por el
programa que realiza los agrupamientos (“AGDocClus”). Este programa genera
archivos de salida que contienen la información de los agrupamientos. A continuación,
el programa “Evaluar Agrupamientos” toma como entrada los agrupamientos generados
y los datos de cada subconjunto de la base de datos de datasets para armar una planilla
excel con los resultados (los valores de las medidas de calidad para cada agrupamiento).

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 131


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.2 Estructura de directorios del CD

A continuación se describe el contenido de cada uno de los directorios que se


encuentran en el CD.

Ø Directorio Raiz
Ø Tesis
Este directorio contiene los documentos que componen el presente
trabajo.
Ø Conjuntos de datos
Este directorio contiene los archivos de los conjuntos re0 y re1.
Ø Subconjuntos de datos
Este directorio contiene subdirectorios para cada uno de los subconjuntos
utilizados. En cada subdirectorio se encuentran los archivos del
subconjunto, y los agrupamientos encontrados por cada uno de los
algoritmos evaluados.
Ø Base de datos
Este directorio contiene la base de datos de datasets.
Ø Armar Datasets
Este directorio contiene el código fuente y el ejecutable compilado del
programa que genera los subconjuntos de datos al azar.
Ø AGDocClus
Este directorio contiene el código fuente y el ejecutable compilado del
programa que implementa los algoritmos de agrupamiento estudiados en
el trabajo.
Ø Evaluar Agrupamientos
Este directorio contiene el código fuente y el ejecutable compilado del
programa que calcula las medidas de calidad para los agrupamientos
generados.
Ø Resultados
Este directorio contiene las planillas excel con los resultados de los
experimentos realizados.

132 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.3 Configuración del origen de datos ODBC

Para que los programas “Armar Datasets” y “Evaluar Agrupamientos” puedan


acceder a la base de datos de datasets, debe configurarse un origen de datos ODBC en el
sistema. A continuación se explica cómo realizar esta configuración en Windows 98. La
configuración para otras versiones de Windows puede variar levemente.

A3.3.1 Copiar el archivo MDB

El archivo bdDataSets.mdb, ubicado en el directorio “Base de datos” del CD,


debe copiarse al disco rígido de la PC. El archivo puede copiarse en cualquier directorio
del disco. Como ejemplo, se supondrá que se copia en el directorio “C:\Tesis\BD”.

A3.3.2 Agregar el origen de datos ODBC

Para completar este paso, debe abrirse el “Panel de Control” de Windows, y


seleccionar la opción “ODBC Data Sources (32bit)”, como se muestra en la figura A3.2.

Fig. A3.2: Panel de


control de Windows

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 133


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Luego debe seleccionarse la solapa “System DNS” y presionar el botón “Add...”,


como se muestra en la figura A3.3.

Fig. A3.3: Agregar


un DNS de sistema

Debe seleccionarse el driver de conexión “Microsoft Access Driver (*.mdb)”,


como se muestra en la figura A3.4.

Fig. A3.4: Selección


del driver a utilizar

134 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Luego debe configurarse el origen de datos ODBC para utilizar el archivo MDB
que se copió al disco en el paso descripto en la sección A3.3.1, de la forma que muestra
la figura A3.5. En la figura se utiliza el nombre “bdReuters2” para el origen de datos. Se
recomienda el uso de este nombre, ya que es el que tienen configurado por defecto los
programas que acceden a la base de datos.

Fig. A3.5:
Configuración del
origen de datos

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 135


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.4 Formato de los archivos de datos

Como se describe en el capítulo 5, los archivos de datos utilizados no son


documentos de texto sino dos conjuntos de datos preprocesados extraídos de la
colección Reuters 21578. Cada uno de los conjuntos de datos (llamados re0 y re1), se
compone de 3 archivos, que llevan como nombre de archivo el nombre del conjunto de
datos, con extensiones “.mat”, “.mat.clabel” y “.mat.rclass”. Para el conjunto de datos
re0, por ejemplo, los 3 archivos son:
- re0.mat
El archivo “.mat” contiene 1 linea de encabezado, y luego 1 línea por
cada documento del conjunto de datos.
La línea de encabezado tiene 3 números. El primero de ellos es la
cantidad de documentos que tiene el conjunto de datos. El segundo es la
cantidad de términos distintos que aparecen en los documentos del
conjunto. El tercer número es la cantidad de entradas distintas de cero
que hay en la matriz que conforman las líneas siguientes del archivo.
Cada una de las siguientes líneas representa un documento del conjunto
de datos. En cada linea hay tantos pares de números como términos
distintos haya en el documento. El primer número del par es el número
del término, y el segundo número es la cantidad de veces que aparece ese
término en el documento.
- re0.mat.clabel
El archivo “.mat.clabel” enumera todos los términos que aparecen en los
documentos, uno en cada línea. El orden de los términos se corresponde
con la numeración mediante la cual se referencian en el archivo “.mat”.
- re0.mat.rclass
El archivo “.mat.rclass” contiene una línea por cada documento del
conjunto de datos. Cada línea del archivo contiene la categoría a la que
pertenece ese documento.

136 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.5 Programa “Armar Datasets”

Este programa es el que se utiliza para extraer muestras de datos al azar a partir
de los conjuntos de datos re0 y re1. En la realización de los experimentos, este
programa se utilizó para generar las 10 muestras de datos re0_1 a re0_10 con 500
documentos al azar del conjunto de datos re0, y las 10 muestras de datos re1_1 a
re1_10, con 500 documentos al azar del conjunto de datos re1.
Al ejecutar el programa, se presenta la siguiente pantalla:

Fig. A3.6:
Configuración del
programa “Armar
Datasets”

En esta pantalla deben configurarse los parámetros del programa. A


continuación se detalla el significado de cada uno de ellos:
- Nombre del origen ODBC : Este parámetro es utilizado para identificar la
base de datos MDB de datasets. Debe colocarse el mismo nombre que se
utilizó al configurar el origen de datos ODBC de la forma en que se describe
en la sección A3.3.
- Ubicación archivos datasets : Este parámetro indica la ruta a los archivos
“.mat”, “.mat.clabel” y “.mat.rclass” correspondientes a los conjuntos de

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 137


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

datos re0 y re1. En este directorio se ubicarán tambien los archivos de las
nuevas muestras de datos generadas por el programa.
- Dataset fuente : Este parámetro permite seleccionar el conjunto de datos del
cual se quiere extraer la muestra de datos al azar. Este parámetro puede
tomar los valores “re0” y “re1”.
- Cantidad elementos dataset fuente : En este parámetro debe colocarse la
cantidad de documentos que contiene el conjunto de datos ingresado en el
parámetro anterior. Los conjuntos de datos re0 y re1 contienen 1504 y 1657
documentos, respectivamente.
- Cantidad elementos nuevos datasets : Este parámetro indica la cantidad de
documentos que van a contener las muestras de datos extraídas. Debe ser
menor o igual a la cantidad de documentos del conjunto de datos origen.
- Nuevos datasets, desde : Este parámetro indica el número de la primera
muestra de datos a generar. Si el parámetro tiene el valor “1”, y el conjunto
de datos origen es “re0”, la primera muestra de datos será “re0_1”.
- Nuevos datasets, hasta : Este parámetro indica el número de la última
muestra de datos a generar. Si el conjunto de datos origen es “re0”, el
parámetro “Nuevos datasets, desde” toma el valor “1”, y el parámetro
“Nuevos datasets, hasta” toma el valor “3”, las muestras de datos generadas
serán “re0_1”, “re0_2” y “re0_3”.

Una vez configurados los valores de los parámetros, debe presionarse el botón
“Procesar”. El programa generará los archivos correspondientes a las muestras de datos,
y guardará tambien la información de los mismos en la base de datos de datasets.

138 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.6 Programa “AGDocClus”

Este programa implementa los algoritmos de agrupamiento estudiados en el


trabajo. El programa permite seleccionar la muestra de datos que se quiere categorizar,
seleccionar la cantidad de grupos y el algoritmo a utilizar, y generar el agrupamiento.

A3.6.1 Copia del programa al disco local

El programa “AGDocClus” no puede ejecutarse desde el CD, ya que intentará


escribir la salida en un subdirectorio del CD, generando un error. Debe copiarse el
contenido de la carpeta “AGDocClus” del CD en un directorio del disco rígido de la PC,
por ejemplo, en el directorio “C:\Tesis\AGDocClus”. Luego debe crearse un
subdirectorio llamado “salida” en el subdirectorio en el cual se copió el programa. En
caso del ejemplo, debe crearse el subdirectorio “C:\Tesis\AGDocClus\salida”. En este
subdirectorio se generará la salida del programa.

A3.6.2 Utilización del programa

Debe ejecutarse el archivo “AGDocClus.exe”.

El programa comenzará preguntando por el directorio en el cual se encuentran


ubicados los archivos de muestras de datos.
Directorio donde se encuentran los archivos (ej: 'd:\Tesis_Docs') :

Debe ingresarse el mismo directorio que se indicó como salida en el programa


“Armar Datasets”, ya que en ese directorio se habrán generado los archivos de muestras
de datos.

Luego, el programa preguntará el nombre de la muestra de datos a categorizar.


Nombre del .mat (ej : 're0_1') o 'txt' para leer archivos .txt :

Debe ingresarse el nombre de la muestra de datos que se quiere categorizar, por


ejemplo, “re0_1”.

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 139


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A continuación, el programa presentará un menú de opciones.


(1) Cambiar cantidad grupos (15)
(2) Cambiar cantidad corridas (5)
(3) Cambiar generaciones del genetico (50)
(a) Bisecting K-Means (con refinamiento)
(b) Algoritmo Genetico (con y sin refinamiento)
(x) Salir
?

Las opciones (1) a (3) permiten cambiar parámetros que afectarán la realización
de los experimentos.
La opción (1) permite cambiar la cantidad de grupos que se formarán.
La opción (2) permite cambiar la cantidad de corridas del algoritmo
seleccionado que se realizarán.
La opción (3) permite cambiar la cantidad de generaciones que se ejecutarán en
el algoritmo genético.
Las opciones (a) y (b) permiten realizar los agrupamientos con cada uno de los
algoritmos.
Al seleccionar la opción (a) se agruparán los elementos de la muestra de datos
utilizando el algoritmo “Bisecting K-Means con refinamiento”.
Al seleccionar la opción (b) se agruparán los elementos de la muestra de datos
utilizando los algoritmos “Genético” y “Genético con refinamiento”.

El programa generará los archivos de salida para cada corrida de los algoritmos
en el subdirectorio “salida”. Estos archivos de salida son utilizados por el programa
“Evaluar Agrupamientos”.

140 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A3.7 Programa “Evaluar Agrupamientos”

Este programa toma los agrupamientos generados como salida por el programa
“AGDocClus” y calcula las medidas de calidad utilizadas en el trabajo.

Al ejecutar el programa se presenta la siguiente pantalla:

Fig. A3.7: Configuración del programa “Evaluar Agrupamientos”

En esta pantalla deben configurarse los parámetros del programa. A


continuación se detalla el significado de cada uno de ellos:
- Nombre del origen ODBC : Este parámetro es utilizado para identificar la
base de datos MDB de datasets. Debe colocarse el mismo nombre que se
utilizó al configurar el origen de datos ODBC de la forma en que se describe
en la sección A3.3.
- Dataset a evaluar : Este parámetro indica el dataset para el cual se desea
evaluar la salida generada.
- Ubicación del programa AGDocClus : En este parámetro debe colocarse el
directorio en el cual se copió el programa “AGDocClus”. El programa
“Evaluar Agrupamiento” buscará los archivos de salida en el subdirectorio
“salida” del directorio indicado en este parámetro

Eugenio Yolis APÉNDICE 3 - MANUAL DE USO 141


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Una vez configurados los valores de los parámetros, debe presionarse el botón
“Procesar”. El programa buscará los archivos de salida generados por el programa
“AGDocClus”, obtendrá la información del dataset de la base de datos de datasets, y
generará una planilla en el programa Microsoft Excel con las medidas de calidad para
cada uno de los agrupamientos procesados.

La planilla generada tendrá un formato similar al siguiente:

CORRIDA SIMIL.PROM. ENTROPIA OPERACIONES


salida_re0_1_BisKM(ref)2_15_0.txt 0,188 1,464 145758
salida_re0_1_BisKM(ref)2_15_1.txt 0,185 1,565 144803
salida_re0_1_BisKM(ref)2_15_2.txt 0,188 1,422 155652
salida_re0_1_BisKM(ref)2_15_3.txt 0,18 1,56 169471
salida_re0_1_BisKM(ref)2_15_4.txt 0,186 1,387 165588
PROM. BisKM(ref)2_15 0,1854 1,4796 156254,4
salida_re0_1_Gen(ref)_15_0.txt 0,19 1,446 119230
salida_re0_1_Gen(ref)_15_1.txt 0,191 1,449 121671
salida_re0_1_Gen(ref)_15_2.txt 0,191 1,362 142727
salida_re0_1_Gen(ref)_15_3.txt 0,187 1,225 120171
salida_re0_1_Gen(ref)_15_4.txt 0,191 1,411 131046
PROM. Gen(ref)_15 0,19 1,3786 126969
salida_re0_1_Gen_15_0.txt 0,189 1,478 96207
salida_re0_1_Gen_15_1.txt 0,18 1,523 76086
salida_re0_1_Gen_15_2.txt 0,19 1,37 112203
salida_re0_1_Gen_15_3.txt 0,183 1,274 97150
salida_re0_1_Gen_15_4.txt 0,184 1,432 85483
PROM. Gen_15 0,1852 1,4154 93425,8

Para cada corrida de cada uno de los algoritmos se muestran sus medidas de
calidad, con los promedios agrupados para las corridas de cada algoritmo.

142 APÉNDICE 3 - MANUAL DE USO Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Apéndice 4
Programación de los algoritmos
En éste apéndice se detalla la forma en la que se programaron los algoritmos
comparados en la prueba experimental. Para realizar la prueba experimental, se
desarrolló una aplicación de categorización automática de documentos que permite
seleccionar qué algoritmo se quiere utilizar. El desarrollo de la aplicación se realizó en
el lenguaje C++. La sección A4.1 contiene la descripción de los distintos módulos en
los que se separó la lógica del algoritmo y la interacción que existe entre los mismos. En
la sección A4.2 se incluye el código fuente de los módulos más significativos.

A4.1 Descripción de los módulos

Para facilitar la codificación y el seguimiento de la lógica de la aplicación, la


misma se dividió en módulos conceptuales. Cada módulo implementa una parte de la
funcionalidad necesaria para la aplicación. A su vez, cada módulo está compuesto de
uno o más archivos de código fuente.

A4.1.1 Módulo “ArchivosTexto”

Este módulo implementa las funciones necesarias para leer los subconjuntos de
documentos que se categorizarán con la aplicación. Los subconjuntos de documentos
deben estar compuestos por archivos con el formato que se describe en el apéndice 3
(“Manual de uso”), sección A3.4. Este módulo se compone de los siguientes archivos de
código fuente:
• ArchivosTexto.h: Declaración de las funciones para leer los
subconjuntos de documentos.
• ArchivosTexto.cpp: Implementación de las funciones que leen los
subconjuntos de documentos.

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 143


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.1.2 Módulo “VecArchivos”

Este módulo implementa un tipo de objeto “VecArchivo”. La utilización de este


objeto permite al resto de los módulos abstraerse de la forma en la cual se manejan las
estructuras utilizadas para la representación vectorial de los documentos a agrupar. El
módulo incluye funciones para agregar elementos al vector, calcular su norma y
multiplicar, sumar y restar vectores. Este módulo se compone de los siguientes archivos
de código fuente:
• VecArchivos.h: Declaración de la clase “c_VecArchivo”, que es la que
encapsula la representación vectorial de los documentos.
• VecArchivos.cpp: Implementación de los métodos de la clase
“c_VecArchivo”.

A4.1.3 Módulo “Agrupamiento”

Este módulo implementa un tipo de objeto “agrupamiento”. La utilización de


este objeto permite al resto de los módulos abstraerse de la forma en la cual se manejan
las estructuras necesarias para representar los agrupamientos. El módulo incluye
funciones para crear grupos, asignar elementos a cada grupo y mover los elementos
entre los grupos del agrupamiento. Este módulo se compone de los siguientes archivos
de código fuente:
• ClsAgrupamiento.h: Declaración de la clase “c_Agrupamiento”, que es la
que encapsula la representación del objeto de tipo “agrupamiento”.
• ClsAgrupamiento.cpp: Implementación de los métodos de la clase
“c_Agrupamiento”. Estos métodos permiten inicializar el agrupamiento,
crear y eliminar grupos, y agregar y quitar elementos de los grupos.
• ClsAgrupImprime.h: Declaración de la clase “c_Agrup_Imprime”. Esta
clase implementa funciones para imprimir en un archivo de texto la
composición de un agrupamiento. Estas funciones son utilizadas por la
aplicación para preparar los archivos de salida.
• ClsAgrupImprime.cpp: Implementación de los métodos de la clase
“c_Agrup_Imprime”.

144 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.1.4 Módulo “K-Means”

Este módulo implementa el algoritmo de categorización automática “Bisecting


K-Means con refinamiento”. El módulo incluye la implementación de las funciones del
algoritmo “K-Means”, que es utilizado por el algoritmo “Bisecting K-Means con
refinamiento” en el paso de bisección. Este módulo se compone de los siguientes
archivos de código fuente:
• ClsKMeans.h: Declaración de la clase “c_KMeans”, que implementa
todas las funciones que requiere el algoritmo “Bisecting K-Means con
refinamiento”.
• ClsKMeans.cpp: Implementación de los métodos de la clase
“c_KMeans”.

A4.1.5 Módulo “Genético”

Este módulo implementa el algoritmo propuesto para la categorización


automática de documentos. Este algoritmo (que se describe en detalle en el capítulo 4)
es una adaptación de un algoritmo genético al problema de la categorización automática
de documentos, e incluye nuevos operadores diseñados específicamente para el
problema a resolver. Este módulo se compone de los siguientes archivos de código
fuente:
• ClsGenetico.h: Declaración de la clase “c_Genetico”. Esta clase
implementa todos los operadores del algoritmo genético, incluyendo los
nuevos operadores diseñados como parte de la solución propuesta.
• ClsGenetico.cpp: Implementación de los operadores del algoritmo
genético. Este archivo contiene el constructor de la clase “c_Genetico”,
donde se fijan todos los parámetros que utiliza el algoritmo genético
(tamaño de la población, tamaño del torneo, y probabilidades con las que
se aplica cada operador).

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 145


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.1.6 Módulo “Principal”

Este módulo implementa la interfaz con el usuario, que permite seleccionar qué
subconjunto de datos se quiere agrupar, qué algoritmo se desea utilizar, y cuántos
grupos se van a formar. El módulo contiene procedimientos que, utilizando las
funciones y clases definidas en los otros módulos, ejecutan las acciones seleccionadas.
Este módulo se compone de los siguientes archivos de código fuente:
• Def.h: Definición de tipos de datos y de constantes utilizadas en la
aplicación.
• Sis.h, SisDos.h y SisDos.cpp: Declaración e implementación de
funciones auxiliares.
• Ppal.cpp: Implementación de las funciones de interfaz con el usuario, y
de los procedimientos que ejecutan las acciones seleccionadas.

146 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2 Código fuente

A4.2.1 ArchivosTexto.h

#ifndef __ArchivosTextoH__
#define __ArchivosTextoH__

uent CargarListaArchivos(char *dir, c_SkipList &ltxt);

uent CargarListaArchivosMAT(char *szMat, c_SkipList &ltxt);

uent ProcesarArchivosTexto(c_SkipList &ltxt, c_SkipList &lexico,


uent tbufftxt, uent &cantlex, c_SkipList *lLexArchivos[]);

uent ProcesarArchivosTextoMAT(char *szMat, c_SkipList &lexico,


uent &cantlex, c_SkipList *lLexArchivos[]);

uent ArmarVectoresArchivos(c_SkipList &lexico, uword cantArchivos,


c_SkipList *lLexArchivos[], c_VecArchivo *vVecArchivos[]);

#endif

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 147


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.2 ArchivosTexto.cpp
#include "def.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "skipl.h"
#include "archtxt.h"
#include "filtrarpalabras.h"
#include "steeming.h"
#include "vecArchivos.h"

uent CargarListaArchivos(char *dir, c_SkipList &ltxt)


/*
carga en ltxt los archivos de texto "*.txt" del directorio dir
devuelve la cantidad de archivos de texto que se cargaron
En vecfh va poniendo la fecha y hora de cada archivo txt
*/
{
t_dir d;
char arch[MAX_LONG_NOMARCH], archlwr[MAX_LONG_NOMARCH];
/* empiezo a contar desde 1 */
uent cant=1;
uword auxlong;

d = PrimeroDir(dir,arch);
while (d!=-1)
/* mientras haya archivos en el directorio */
{
strcpy(archlwr,arch);
strlwr(archlwr);
if (strstr(archlwr,".txt"))
/* si es un .txt */
{
/* paso cant a long */
auxlong = (long)cant;
ltxt.Buscar_Insertar((ubyte*)arch,auxlong);
cant++;
//xxxdebug
//printf("Arch : %d - %s\n",cant-1,arch);
}
d = SiguienteDir(d,arch);
}
return (cant-1);
}

uent CargarListaArchivosMAT(char *szMat, c_SkipList &ltxt)


/*
carga en ltxt los nombres de archivos de texto del .mat.
devuelve la cantidad de archivos de texto que se cargaron
(en realidad, el nombre de archivo va a ser _D_nro.txt y la cantidad
de archivos la sacamos de la primera linea del .mat)
*/
{

148 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

char arch[MAX_LONG_NOMARCH];
/* empiezo a contar desde 1 */
uent cant,i;
uword auxlong;
FILE *fMat;

/* leemos el primer numero del .mat */


fMat = fopen(szMat,"r");
fscanf(fMat,"%d",&cant);
fclose(fMat);

/* cargamos la lista */
for (i=1;i <= cant; i++)
/* para cada "archivo" */
{
sprintf((char*)&arch,"_D_%d.txt",i);
/* paso "i" a long */
auxlong = (long)i;
ltxt.Buscar_Insertar((ubyte*)arch,auxlong);
//xxxdebug
//printf("Arch : %d - %s\n",i,arch);
}

return cant;
}

uent ProcesarArchivosTexto(c_SkipList &ltxt, c_SkipList &lexico,


uent tbufftxt, uent &cantlex, c_SkipList *lLexArchivos[])
/*
Devuelve la tabla de lexico en lexico
Utiliza el tamanio de buffer especificado en tbufftxt para los
archivos de texto
devuelve en cantlex la cantidad de terminos del lexico
Devuelve OK o el error que corresponda
*/
{
uent nropal;
uword nroarch;
ubyte nomtxt[MAX_LONG_NOMARCH], pal[MAX_LONG_PALABRA];
c_ArchTexto atxt;
uword auxlong;
c_SkipList *lLexA;
uword nroTerm;
uent frecTerm;
uent codRet;

cantlex = 1;
if (ltxt.MoverPrimero() == ERROR)
/* la lista estaba vacia, no hay archivos */
return OK;
if (atxt.CrearBuffer(tbufftxt) == ERROR_MEMORIA)
return ERROR_MEMORIA;
do
{
ltxt.ObtenerClave(nomtxt);
nroarch = ltxt.ObtenerValor();
lLexArchivos[nroarch] = new c_SkipList();
if (lLexArchivos[nroarch] == NULL)

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 149


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

return ERROR_MEMORIA;
/* obtenemos los datos del archivo de texto */
if (atxt.Abrir((char*)nomtxt) == ERROR_ARCHIVO)
return ERROR_ARCHIVO;
lexico.ResetFrecs();
/* reseteamos las frecuencias de la lista de lexico */
while (atxt.LeerPalabra(pal))
/* leemos todas las palabras y las metemos en el lexico si
es que no estan */
{
/* procesamos la palabra */
codRet = ProcesarPalabra(pal);
if (codRet != ERROR)
/* Hay que guardar esta palabra */
{
/* le aplicamos las reglas de steeming */
steeming_porter((char*)pal);

nropal = cantlex;
/* pasamos el nropal a long */
auxlong = nropal;
if (lexico.Buscar_Insertar(pal,auxlong) == ERROR_MEMORIA)
return ERROR_MEMORIA;
nropal = (uent)auxlong;
if (nropal == cantlex)
{
cantlex++;
}
}
}
atxt.Cerrar();
/* no hay mas palabras, completemos la lista de ese archivo */
if (lexico.MoverPrimero() == OK)
{
/* vamos a trabajar con la lista de ese archivo */
lLexA = lLexArchivos[nroarch];
do
{
if (lexico.ObtenerFrec() != 0)
/* si la palabra estaba en el archivo que procesamos */
{
/* la insertamos en la lista del archivo */
lexico.ObtenerClave(pal);
nroTerm = lexico.ObtenerValor();
frecTerm = lexico.ObtenerFrec();
if (lLexA->Buscar_Insertar(pal,nroTerm) ==
ERROR_MEMORIA)
return ERROR_MEMORIA;
/* seteamos la frecuencia del termino */
lLexA->SetearFrecuencia(frecTerm);
}
} while (lexico.MoverSiguiente() == OK);
}
} while (ltxt.MoverSiguiente() == OK);
lexico.ResetFrecs();
/* cantlex habia quedado con 1 de mas */
cantlex--;
return OK;

150 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent ProcesarArchivosTextoMAT(char *szMat, c_SkipList &lexico,


uent &cantlex, c_SkipList *lLexArchivos[])
/*
Devuelve la tabla de lexico en lexico
devuelve en cantlex la cantidad de terminos del lexico
Devuelve OK o el error que corresponda
*/
{
ubyte pal[MAX_LONG_PALABRA];
c_SkipList *lLexA;
uword nroTerm;
uent frecTerm;
uent cantArchivos, iArchivo;
FILE *fp;
char szCLabel[200],dummyChar;
float fNroTerm,fFrecTerm;

/* la cantidad de archivos es el primer nro del .mat


y la cantidad de términos es el segundo */
fp = fopen(szMat,"r");
fscanf(fp,"%d %d",&cantArchivos,&cantlex);
fclose(fp);

/* abrimos el archivo de palabras (.mat.clabel) y las vamos


ingresando el la lista de lexico */
sprintf((char*)&szCLabel,"%s.clabel",szMat);
fp = fopen((char*)&szCLabel,"r");
for (nroTerm = 1; nroTerm <= cantlex; nroTerm++)
{
fscanf(fp,"%s",(char*)&pal);
fscanf(fp,"%c",&dummyChar);
if (lexico.Buscar_Insertar(pal,nroTerm) == ERROR_MEMORIA)
return ERROR_MEMORIA;
}
fclose(fp);

/* ahora abrimos el .mat y leemos los archivos


(cada linea del .mat, excepto la primera, se corresponde
con un archivo) */
fp = fopen(szMat,"r");

/* la primera linea la salteamos */


while (fgetc(fp) != '\n');

for (iArchivo = 1; iArchivo <= cantArchivos; iArchivo++)


{
/* creamos una nueva lista para ese archivo */
lLexArchivos[iArchivo] = new c_SkipList();
/* la ordenamos por numero */
lLexArchivos[iArchivo]->SetearOrden(1);
if (lLexArchivos[iArchivo] == NULL)
return ERROR_MEMORIA;
lLexA = lLexArchivos[iArchivo];

lexico.ResetFrecs();
/* vamos leyendo los pares (palabra,frecuencia) de ese archivo */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 151


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

do
{
fscanf(fp,"%f %f",&fNroTerm,&fFrecTerm);
nroTerm = (uword)fNroTerm;
frecTerm = (uent)fFrecTerm;
/* buscamos esa palabra en el lexico */
lexico.Buscar(pal,nroTerm);
/* la insertamos el la lista del archivo */
if (lLexA->Buscar_Insertar(pal,nroTerm) == ERROR_MEMORIA)
return ERROR_MEMORIA;
/* asignamos la frecuencia en ambas listas */
lexico.SetearFrecuencia(frecTerm);
lLexA->SetearFrecuencia(frecTerm);
/* leemos un caracter, a ver si viene el fin de linea */
fscanf(fp,"%c",&dummyChar);
} while (dummyChar != '\n');

}
lexico.ResetFrecs();

fclose(fp);

return OK;
}

uent ArmarVectoresArchivos(c_SkipList &lexico, uword cantArchivos,


c_SkipList *lLexArchivos[], c_VecArchivo *vVecArchivos[])
/* arma los vectores de terminos de los archivos */
/* devuelve OK o el error que corresponda */
{
uent codRet,iArch, iPal, frec, countFrecs;
ubyte pal[MAX_LONG_PALABRA],pal2[MAX_LONG_PALABRA];
uent nroPalEnt;
uword nroPalWord;
real tfIdf;

/* para cada archivo */


for (iArch=1; iArch <= cantArchivos; iArch++) {
/* creamos el vector con la cantidad de entradas que necesitamos */
vVecArchivos[iArch] = new c_VecArchivo();
if (vVecArchivos[iArch] == NULL)
return ERROR_MEMORIA;
codRet = vVecArchivos[iArch]->CrearVector((uent)lLexArchivos[iArch]-
>ObtenerCantElementos());
if (codRet != OK)
return codRet;
/* las entradas en el vector empiezan en 0 */
iPal = 0;
if (0 < lLexArchivos[iArch]->ObtenerCantElementos())
{
lLexArchivos[iArch]->MoverPrimero();
do {
/* para cada palabra del archivo */
/* buscamos la palabra y la frecuencia en el archivo */
lLexArchivos[iArch]->ObtenerClave(pal);
frec = lLexArchivos[iArch]->ObtenerFrec();
nroPalWord = lLexArchivos[iArch]->ObtenerValor();
/* buscamos el nuevo numero de palabra y la cantidad

152 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

de archivos en la que aparece */


strcpy((char *)pal2,(char *)pal);
lexico.Buscar(pal,nroPalWord);
nroPalEnt = (uent)nroPalWord;
countFrecs = lexico.ObtenerCountFrecs();
/* calculamos el valor tf-idf */
tfIdf = (real)frec *
((real)log((double)cantArchivos/(double)countFrecs) / (real)log(2.0));
/* insertamos la entrada en el vector */
vVecArchivos[iArch]-
>ModificarEntrada(iPal,nroPalEnt,tfIdf,false);
iPal++;
} while (lLexArchivos[iArch]->MoverSiguiente() == OK);
}
/* ahora lo normalizamos */
vVecArchivos[iArch]->Normalizar();
/* y calculamos las palabras claves */
vVecArchivos[iArch]->ActualizarPalabrasClave();
}
return OK;
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 153


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.3 VecArchivos.h
/*
Clase de vector de archivos

El vector contiene entradas compuestas de dos valores :


un valor entero y un valor real

El vector se crea con un tamaño y luego no se puede cambiar

*/

#ifndef __vecArchivosH__

#define __vecArchivosH__

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "def.h"
#include "sis.h"

#define NRO_ENT_KEYWORDS 5

typedef struct _t_RegVecArchivo {


uent valEnt;
real valReal;
} t_RegVecArchivo;

class c_VecArchivo {
private:
uent cantEntradas; /* numero de entradas en el vector */
t_RegVecArchivo *entradas; /* vector con una entrada por cada palabra del
archivo */
t_RegVecArchivo keywords[NRO_ENT_KEYWORDS]; /* palabras clave que
describen al archivo */
real normaValor; /* valor de la norma del vector */
bool normaActualizada; /* true si el valor de la norma está actualizado */
uent SumarPriv(c_VecArchivo &otroVec, real signo, bool
soloEntradasEnComun);
public:
static uword contMultiplicaciones; /* cuenta las veces que se llamó a la funcion
multiplicacion */
static uword contCalculoNorma; /* cuenta la cantidad de veces que se llamó a la
funcion calcular norma */
c_VecArchivo();
uent CrearVector(uent parCantEntradas);
uent Duplicar(c_VecArchivo &otroVec);
void ModificarEntrada(uent nroEntrada, uent parValEnt, real parValReal, bool
usarKeywords);
void ConseguirEntrada(uent nroEntrada, uent &parValEnt, real &parValReal, bool
usarKeywords);

154 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent ConseguirCantEntradas(bool usarKeywords);


real Multiplicar(c_VecArchivo &otroVec, bool usarKeywords);
uent EnComun(c_VecArchivo &otroVec, bool usarKeywords);
uent Sumar(c_VecArchivo &otroVec);
uent Restar(c_VecArchivo &otroVec);
real CalcularNorma(bool incContador);
void MultiplicarPorReal(real nroReal);
~c_VecArchivo();
void Normalizar();
void ActualizarPalabrasClave();
};

#endif

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 155


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.4 VecArchivos.cpp
#include "vecArchivos.h"

uword c_VecArchivo::contMultiplicaciones = 0;
uword c_VecArchivo::contCalculoNorma = 0;

c_VecArchivo::c_VecArchivo()
/* constructor */
{
cantEntradas = 0;
entradas = NULL;
normaValor = (real)0.0;
normaActualizada = false;
}

c_VecArchivo::~c_VecArchivo()
/* destructor */
{
if (cantEntradas != 0)
free((void*)entradas);
}

uent c_VecArchivo::CrearVector(uent parCantEntradas)


/* reserva espacio para la cantidad de entradas pedida */
/* devuelve OK o el error que corresponda */
{
uent i;

cantEntradas = parCantEntradas;

/* inicializamos el vector de palabras claves */


for (i=0; i < NRO_ENT_KEYWORDS; i++)
{
keywords[i].valEnt = 0;
keywords[i].valReal = 0.0;
}

if (cantEntradas == 0)
return OK;

entradas = (t_RegVecArchivo*)malloc(cantEntradas * sizeof(t_RegVecArchivo));


if (entradas == NULL)
return ERROR_MEMORIA;

return OK;
}

uent c_VecArchivo::Duplicar(c_VecArchivo &otroVec)


{
/* copia el vector otroVec en el actual
el actual no debe estar inicializado
devuelve OK o el error que corresponda */

/* copiamos las keywords */

156 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

memcpy((void*)keywords,(void*)otroVec.keywords,NRO_ENT_KEYWORDS *
sizeof(t_RegVecArchivo));

/* copiamos las entradas */


cantEntradas = otroVec.cantEntradas;
entradas = (t_RegVecArchivo*)malloc(cantEntradas * sizeof(t_RegVecArchivo));
if (entradas == NULL)
return ERROR_MEMORIA;
memcpy((void*)entradas,(void*)otroVec.entradas,cantEntradas *
sizeof(t_RegVecArchivo));

/* copiamos el valor de la norma y el flag que marca si está actualizada */


normaValor = otroVec.normaValor;
normaActualizada = otroVec.normaActualizada;

return OK;
}

void c_VecArchivo::ModificarEntrada(uent nroEntrada,uent parValEnt,real parValReal, bool


usarKeywords)
/* modifica la entrada */
/* si el valor "parValReal" le permite a la palabra ser una de las
keywords del archivo, la incluye en el vector y saca una de ellas */
{
if (usarKeywords)
{
keywords[nroEntrada].valEnt = parValEnt;
keywords[nroEntrada].valReal = parValReal;
}
else
{
entradas[nroEntrada].valEnt = parValEnt;
entradas[nroEntrada].valReal = parValReal;
}
/* la norma no está actualizada porque cambió una entrada */
normaActualizada = false;
}

void c_VecArchivo::ConseguirEntrada(uent nroEntrada,uent &parValEnt,real &parValReal, bool


usarKeywords)
/* devuelve los valores de la entrada */
{
if (usarKeywords)
{
if (nroEntrada < NRO_ENT_KEYWORDS) {
parValEnt = keywords[nroEntrada].valEnt;
parValReal = keywords[nroEntrada].valReal;
} else {
parValEnt = 0;
parValReal = 0;
}
}
else
{
if (nroEntrada < cantEntradas) {
parValEnt = entradas[nroEntrada].valEnt;
parValReal = entradas[nroEntrada].valReal;
} else {

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 157


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

parValEnt = 0;
parValReal = 0;
}
}
}

uent c_VecArchivo::ConseguirCantEntradas(bool usarKeywords)


{
if (usarKeywords)
return NRO_ENT_KEYWORDS;
else
return cantEntradas;
}

real c_VecArchivo::Multiplicar(c_VecArchivo &otroVec, bool usarKeywords)


/* multiplica el vector por el que viene como parametro */
/* producto interno */
/* devuelve el resultado */
{
real rAux,valReal1,valReal2;
uent i1,i2,valEnt1,valEnt2;
uent ent1,ent2;

contMultiplicaciones++;

ent1 = ConseguirCantEntradas(usarKeywords);
ent2 = otroVec.ConseguirCantEntradas(usarKeywords);

i1 = 0;
i2 = 0;

ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);

rAux = 0;

while (i1 < ent1 && i2 < ent2) {


if (valEnt1 == valEnt2) {
rAux += valReal1 * valReal2;
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
} else if (valEnt1 < valEnt2) {
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
} else {
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
}
}

return rAux;
}

uent c_VecArchivo::EnComun(c_VecArchivo &otroVec, bool usarKeywords)


/* devuelve la cantidad de elementos en comun */
{

158 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

real valReal1,valReal2;
uent i1,i2,valEnt1,valEnt2,entAux;
uent ent1,ent2;

ent1 = ConseguirCantEntradas(usarKeywords);
ent2 = otroVec.ConseguirCantEntradas(usarKeywords);

i1 = 0;
i2 = 0;

ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);

entAux = 0;

while (i1 < ent1 && i2 < ent2) {


if (valEnt1 == valEnt2) {
entAux++;
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
} else if (valEnt1 < valEnt2) {
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
} else {
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
}
}

return entAux;
}

uent c_VecArchivo::Sumar(c_VecArchivo &otroVec)


{
return SumarPriv(otroVec,(real)1.0,false);
}

uent c_VecArchivo::Restar(c_VecArchivo &otroVec)


{
return SumarPriv(otroVec,(real)-1.0,true);
}

uent c_VecArchivo::SumarPriv(c_VecArchivo &otroVec, real signo, bool


soloEntradasEnComun)
/* suma al vector las entradas del otro vector, multiplicandolas
por el valor "signo"
Si "soloEntradasEnComun" es true, se ignoran todas las entradas que
estén en el otro vector y no en este
Si "soloEntradasEnComun" es false, si es necesario, le agrega entradas al vector
devuelve OK o el error que corresponda */
{
real valReal1,valReal2;
uent i1,i2,iNuevo,valEnt1,valEnt2;
uent ent1,ent2,entComun,nuevoTam;
t_RegVecArchivo *nuevasEntradas;
bool usarKeywords;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 159


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

real normaVec; /* vamos a aprovechar para calcular la norma */


bool ignoramosEntrada;

usarKeywords = false;

ent1 = ConseguirCantEntradas(usarKeywords);
ent2 = otroVec.ConseguirCantEntradas(usarKeywords);

if (soloEntradasEnComun == false)
{
entComun = EnComun(otroVec,usarKeywords);

/* el nuevo tamaño es la suma menos la interseccion */


nuevoTam = ent1 + ent2 - entComun;

nuevasEntradas =
(t_RegVecArchivo*)malloc(nuevoTam*sizeof(t_RegVecArchivo));
if (nuevasEntradas == NULL)
return ERROR_MEMORIA;
}
else
{
nuevasEntradas = entradas;
}

i1 = 0;
i2 = 0;
iNuevo = 0;
normaVec = (real)0.0;

ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);

while (i1 < ent1 && i2 < ent2) {


ignoramosEntrada = false;
if (valEnt1 == valEnt2) {
nuevasEntradas[iNuevo].valEnt = valEnt1;
nuevasEntradas[iNuevo].valReal = valReal1 + (signo * valReal2);
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
} else if (valEnt1 < valEnt2) {
/* esta entrada solo está en este vector */
nuevasEntradas[iNuevo].valEnt = valEnt1;
nuevasEntradas[iNuevo].valReal = valReal1;
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
} else {
/* esta entrada solo está en el otro vector */
if (soloEntradasEnComun == false)
{
nuevasEntradas[iNuevo].valEnt = valEnt2;
nuevasEntradas[iNuevo].valReal = signo * valReal2;
}
else
{
ignoramosEntrada = true;

160 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

}
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
}
if (ignoramosEntrada == false)
{
normaVec += nuevasEntradas[iNuevo].valReal *
nuevasEntradas[iNuevo].valReal;
iNuevo++;
}
}
/* alguno de los vectores se terminó */
while (i1 < ent1) {
/* se terminó el otro vector */
nuevasEntradas[iNuevo].valEnt = valEnt1;
nuevasEntradas[iNuevo].valReal = valReal1;
i1++;
ConseguirEntrada(i1,valEnt1,valReal1,usarKeywords);
normaVec += nuevasEntradas[iNuevo].valReal *
nuevasEntradas[iNuevo].valReal;
iNuevo++;
}
while ((i2 < ent2) && (soloEntradasEnComun == false)) {
/* se terminó este vector */
nuevasEntradas[iNuevo].valEnt = valEnt2;
nuevasEntradas[iNuevo].valReal = signo * valReal2;
i2++;
otroVec.ConseguirEntrada(i2,valEnt2,valReal2,usarKeywords);
normaVec += nuevasEntradas[iNuevo].valReal *
nuevasEntradas[iNuevo].valReal;
iNuevo++;
}

if (soloEntradasEnComun == false)
{
/* liberamos el viejo vector de entradas */
free((void*)entradas);
/* asignamos el nuevo vector de entradas */
entradas = nuevasEntradas;
}

cantEntradas = iNuevo;
/* guardamos la norma y marcamos que está actualizada */
normaValor = (real)sqrt((double)normaVec);
normaActualizada = true;
return OK;

real c_VecArchivo::CalcularNorma(bool incContador)


{
/* calculamos la norma (raiz del vector multiplicado por si mismo */

real normaVec;
uent i;

if (incContador)
contCalculoNorma++;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 161


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (normaActualizada == false)
{
/* la norma no está actualizada, hay que calcularla */
normaVec = (real)0.0;
for (i=0; i < cantEntradas; i++)
{
normaVec += entradas[i].valReal * entradas[i].valReal;
}
normaVec = (real)sqrt((double)normaVec);
/* la guardamos, y marcamos que está actualizada */
normaValor = normaVec;
normaActualizada = true;
}
else
{
normaVec = normaValor;
}

return normaVec;
}

void c_VecArchivo::Normalizar()
{
/* divide las entradas del vector por su norma, de forma tal
que la norma del vector sea igual a 1 */
real normaVec,unoSobre;

normaVec = CalcularNorma(false);
/* dividimos los valores de todas las entradas por la norma */
unoSobre = (real)1.0 / normaVec;
MultiplicarPorReal(unoSobre);
}

void c_VecArchivo::MultiplicarPorReal(real nroReal)


{
/*
Multiplica las entradas del vector por el numero real
*/
uent i;

for (i=0; i < cantEntradas; i++)


{
entradas[i].valReal *= nroReal;
}
/* si la norma estaba actualizada, va a quedar bien si la multiplicamos tambien por el
real */
normaValor *= nroReal;
}

void c_VecArchivo::ActualizarPalabrasClave()
{
/* actualiza la lista de palabras clave del vector
*/

uent iEntradas,i,j;

for (j=0; j < NRO_ENT_KEYWORDS; j++)

162 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
keywords[j].valReal = (real)0.0;
keywords[j].valEnt = 0;
}

for (iEntradas=0; iEntradas < cantEntradas; iEntradas++)


{

i = 0;

for (j=0; j < NRO_ENT_KEYWORDS; j++)


if (entradas[iEntradas].valReal > keywords[j].valReal)
i++;
if (i > 0)
/* la palabra entra en las keywords, en la posicion i-1 */
{
i--;
for (j = 0; j < i; j++)
{
keywords[j].valEnt = keywords[j+1].valEnt;
keywords[j].valReal = keywords[j+1].valReal;
}
keywords[i].valEnt = entradas[iEntradas].valEnt;
keywords[i].valReal = entradas[iEntradas].valReal;
}
}
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 163


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.5 ClsAgrupamiento.h
/*
Clase que implementa un agrupamiento

*/

#ifndef __clsAgrupamiento__

#define __clsAgrupamiento__

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "vecArchivos.h"

#define AGRUP_MIN_GRUPOS 5
#define AGRUP_INC_CANT_GRUPOS 5

typedef struct _t_RegVecGrupos {


uent nroGrupo; /* identificador del grupo */
uent menorNroElem; /* menor numero de elemento del grupo */
c_VecArchivo *vecCentroide; /* centroide del grupo */
uent cantElementos; /* cantidad de elementos del grupo */
} tRegVecGrupos;

class c_Agrupamiento {
friend class c_KMeans;
friend class c_Agrup_Imprime;
friend class c_Genetico;
private:
tRegVecGrupos *vecGrupos;
uent *vecElementos;
uent capacidadVecGrupos;
void CopiarRegVecGrupos(uent i, uent j, tRegVecGrupos *nuevoVecGrupos);
public:
uent cantGrupos;
uent cantElementos;
uent IndiceDeGrupo(uent nroGrupo, bool puedeNoEstar);
uent SiguienteNroGrupo();
c_Agrupamiento();
~c_Agrupamiento();
uent Inicializar(uent parCantElementos);
uent Duplicar(c_Agrupamiento &agrup);
uent AgruparAlAzar(uent cantGrupMin, uent cantGrupMax);
uent AgregarGrupos(uent cantidad);
void RenumerarGrupos();
void MoverElemento(uent nroElem, uent indGrupNuevo, uent indGrupAnterior);
void EliminarRegVecGrupos(uent indGrupo);
};

#endif

164 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.6 ClsAgrupamiento.cpp
#include "clsAgrupamiento.h"

c_Agrupamiento::c_Agrupamiento()
{
cantElementos = 0;
capacidadVecGrupos = 0;
cantGrupos = 0;
}

c_Agrupamiento::~c_Agrupamiento()
{
uent i;
for (i=0 ; i < cantGrupos ; i++)
{
if (vecGrupos[i].vecCentroide != NULL)
delete(vecGrupos[i].vecCentroide);
}
if (vecGrupos != NULL)
free((void*)vecGrupos);
if (vecElementos != NULL)
free((void*)vecElementos);

uent c_Agrupamiento::SiguienteNroGrupo()
{
/* devuelve el siguiente número de grupo que se puede
utilizar para un grupo nuevo
*/
uent i;
uent max;

max = 1;
for (i=0; i < cantGrupos; i++)
if (vecGrupos[i].nroGrupo > max)
max = vecGrupos[i].nroGrupo;
/* veamos si no hay un numero mayor, en ese caso,
devolvemos 0 */
if (max >= MAX_UENT)
return 0;
return (max + 1);
}

uent c_Agrupamiento::IndiceDeGrupo(uent nroGrupo,bool puedeNoEstar)


{
/* devuelve el indice en el vector de grupos del grupo
cuyo número es "nroGrupo"
si "puedeNoEstar" es true, quiere decir que no es error si no
está el nro de grupo buscado. en ese caso, devolvemos el
indice de un grupo al azar
*/
uent i = 0;
while ((i < cantGrupos) && (vecGrupos[i].nroGrupo != nroGrupo))
i++;
if (i >= cantGrupos) /* no lo encontramos */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 165


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
if (puedeNoEstar)
return RANDOM(cantGrupos);
else
return MAX_UENT; /* para que de error y detectemos el problema */
}
else
return i;
}

uent c_Agrupamiento::Inicializar(uent parCantElementos)


{
/* inicializa el agrupamiento para que contenga "parCantElementos"
elementos */
/* devuelve OK o el error que corresponda */
uent i;

vecElementos = (uent*)malloc(parCantElementos * sizeof(uent));


if (vecElementos == NULL)
return ERROR_MEMORIA;
cantElementos = parCantElementos;
for (i=0; i < cantElementos; i++)
vecElementos[i] = 0;
return OK;
}

uent c_Agrupamiento::Duplicar(c_Agrupamiento &agrup)


{
/* el agrupamiento copia exactamente al agrupamiento agrup
el agrupamiento no debe estar inicializado (agrup si)
devuelve OK o el error que corresponda */
uent i, codRet;

/* copiamos el vector de elementos */


cantElementos = agrup.cantElementos;
vecElementos = (uent*)malloc(cantElementos * sizeof(uent));
if (vecElementos == NULL)
return ERROR_MEMORIA;
memcpy((void*)vecElementos,(void*)agrup.vecElementos,cantElementos *
sizeof(uent));
/* copiamos el vector de grupos */
capacidadVecGrupos = agrup.capacidadVecGrupos;
cantGrupos = agrup.cantGrupos;
vecGrupos = (tRegVecGrupos*)malloc(capacidadVecGrupos * sizeof(tRegVecGrupos));
if (vecGrupos == NULL)
return ERROR_MEMORIA;
memcpy((void*)vecGrupos,(void*)agrup.vecGrupos,capacidadVecGrupos *
sizeof(tRegVecGrupos));
/* duplicamos los centroides */
for (i = 0; i < cantGrupos; i++)
{
if (agrup.vecGrupos[i].vecCentroide != NULL)
{
vecGrupos[i].vecCentroide = new c_VecArchivo();
codRet = vecGrupos[i].vecCentroide-
>Duplicar(*(agrup.vecGrupos[i].vecCentroide));
if (codRet != OK)
return codRet;

166 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

}
else
{
vecGrupos[i].vecCentroide = NULL;
}
}

return OK;
}

uent c_Agrupamiento::AgruparAlAzar(uent cantGrupMin, uent cantGrupMax)


{
/* Agrupa los elementos al azar */
/* Debe llamarse luego de ::Inicializar() */
/* Devuelve OK o el error que corresponda */
uent i;
uent nroElemRand;
uent grupAsig;

/* la cantidad de grupos debe estar entre cantGrupMin y cantGrupMax */


cantGrupos = RANDOM(1 + cantGrupMax - cantGrupMin) + cantGrupMin;
vecGrupos = (tRegVecGrupos*)malloc(cantGrupos * sizeof(tRegVecGrupos));
if (vecGrupos == NULL)
return ERROR_MEMORIA;
capacidadVecGrupos = cantGrupos;
/* inicializamos cada grupo */
for (i=0; i < cantGrupos; i++)
{
vecGrupos[i].cantElementos = 0;
vecGrupos[i].nroGrupo = i+1;
/* en el campo menorNroElem ponemos el numero "cantElementos"
del agrupamiento, para que sea mayor a cualquier
número de elemento */
vecGrupos[i].menorNroElem = cantElementos;
vecGrupos[i].vecCentroide = NULL;
}
/* ahora nos aseguramos de poner 1 elemento por grupo */
for (i=0; i < cantGrupos; i++)
{
/* elegimos un elemento al azar */
nroElemRand = RANDOM(cantElementos);
/* si ya está asignado, buscamos otro */
while (vecElementos[nroElemRand] != 0)
nroElemRand = RANDOM(cantElementos);
/* le asignamos el grupo */
vecElementos[nroElemRand] = vecGrupos[i].nroGrupo;
}
/* ahora recorremos el vector y vamos asignando grupos al azar */
for (i=0; i < cantElementos; i++)
{
/* veamos si ese elemento no tiene grupo */
if (vecElementos[i] == 0)
{
/* le asignamos uno */
grupAsig = RANDOM(cantGrupos);
vecElementos[i] = vecGrupos[grupAsig].nroGrupo;
}
else

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 167


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
/* buscamos el grupo del elemento */
grupAsig = IndiceDeGrupo(vecElementos[i],false);
}
/* sumamos un elemento al grupo */
vecGrupos[grupAsig].cantElementos++;
/* vemos si este elemento es el menor nro de elementos del grupo */
if (vecGrupos[grupAsig].menorNroElem > i)
vecGrupos[grupAsig].menorNroElem = i;
}
return OK;
}

void c_Agrupamiento::CopiarRegVecGrupos(uent i, uent j, tRegVecGrupos *nuevoVecGrupos)


{
/* copia la entrada "i" del vector de grupos a la entrada j
del nuevo vector de grupos */
nuevoVecGrupos[j].cantElementos = vecGrupos[i].cantElementos;
nuevoVecGrupos[j].menorNroElem = vecGrupos[i].menorNroElem;
nuevoVecGrupos[j].nroGrupo = vecGrupos[i].nroGrupo;
nuevoVecGrupos[j].vecCentroide = vecGrupos[i].vecCentroide;
}

uent c_Agrupamiento::AgregarGrupos(uent cantidad)


{
/* agrega "cantidad" grupos al agrupamiento, alocando más memoria
si es necesario */
/* los grupos se crean vacíos, por lo que el agrupamiento queda en
un estado inconsistente */
/* devuelve OK o el error que corresponda */
uent capacidadAgregar, incrementosAgregar;
tRegVecGrupos *nuevoVecGrupos;
uent i;
uent siguienteNro;
uent cantGrupOld;

/* veamos cuanto tenemos que agrandar el vector */


if (capacidadVecGrupos < (cantGrupos+cantidad))
{
capacidadAgregar = (cantGrupos+cantidad) - capacidadVecGrupos;
incrementosAgregar = 1 + (capacidadAgregar /
AGRUP_INC_CANT_GRUPOS);
capacidadVecGrupos +=
(incrementosAgregar*AGRUP_INC_CANT_GRUPOS);
nuevoVecGrupos = (tRegVecGrupos*)malloc(capacidadVecGrupos *
sizeof(tRegVecGrupos));
if (nuevoVecGrupos == NULL)
return ERROR_MEMORIA;
/* copiamos el vector anterior al nuevo */
for (i=0; i < cantGrupos; i++)
{
CopiarRegVecGrupos(i, i, nuevoVecGrupos);
}
/* damos de baja el viejo vector y usamos el nuevo */
free((void*)vecGrupos);
vecGrupos = nuevoVecGrupos;
}
/* veamos si quedan suficientes numeros de grupo para agregar */

168 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

siguienteNro = SiguienteNroGrupo();
if ((siguienteNro + cantidad) > MAX_UENT) /* renumeramos los grupos */
{
RenumerarGrupos();
siguienteNro = SiguienteNroGrupo();
}
/* agregamos los nuevos grupos al vector */
cantGrupOld = cantGrupos;
for (i=0; i < cantidad; i++)
{
vecGrupos[cantGrupOld + i].cantElementos = 0;
/* en el campo "menorNroElemento" ponemos la cantidad de elementos
del agrupamiento, para que sea mayor a cualquier numero de elemento */
vecGrupos[cantGrupOld + i].menorNroElem = cantElementos;
vecGrupos[cantGrupOld + i].nroGrupo = siguienteNro;
vecGrupos[cantGrupOld + i].vecCentroide = NULL;
siguienteNro++;
cantGrupos++;
}
return OK;
}

void c_Agrupamiento::RenumerarGrupos()
{
/* renumera los grupos */
/* esta función debe utilizarse en el improbable caso de que se
hayan usado más de 65536 números de grupo, por agregar y borrar
grupos muchas veces */
uent i,j, nroAnterior;

for (i=0; i < cantGrupos; i++)


{
nroAnterior = vecGrupos[i].nroGrupo;
vecGrupos[i].nroGrupo = i + 1;
for (j=0; j < cantElementos; j++)
if (vecElementos[j] == nroAnterior)
vecElementos[j] = vecGrupos[i].nroGrupo;
}
}

void c_Agrupamiento::EliminarRegVecGrupos(uent indGrupo)


{
/*
Elimina la entrada con índice "indGrupo" del vector de grupos
*/
uent i;
if (vecGrupos[indGrupo].vecCentroide != NULL)
delete(vecGrupos[indGrupo].vecCentroide);
for (i = indGrupo; i < cantGrupos - 1; i++)
CopiarRegVecGrupos(i+1, i, vecGrupos);
cantGrupos--;
}

void c_Agrupamiento::MoverElemento(uent nroElem, uent indGrupNuevo, uent


indGrupAnterior)
{
/*

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 169


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

Mueve el elemento "nroElem" del grupo con índice "indGrupAnterior"


al grupo con índice "indGrupNuevo"
Si el grupo anterior queda vacío, lo elimina
*/
uent i;

if (indGrupNuevo != indGrupAnterior)
{

vecElementos[nroElem] = vecGrupos[indGrupNuevo].nroGrupo;
vecGrupos[indGrupNuevo].cantElementos++;
/* veamos si el que agregamos al nuevo grupo es el menor nro de elemento */
if (nroElem < vecGrupos[indGrupNuevo].menorNroElem)
vecGrupos[indGrupNuevo].menorNroElem = nroElem;

if (vecGrupos[indGrupAnterior].cantElementos <= 1)
EliminarRegVecGrupos(indGrupAnterior);
else
{
vecGrupos[indGrupAnterior].cantElementos--;
/* veamos si el que le sacamos era el menor numero de elemento */
if (nroElem == vecGrupos[indGrupAnterior].menorNroElem)
{
/* buscamos el nuevo menor numero de elemento */
i = nroElem + 1;
while (i < cantElementos)
{
if (vecElementos[i] ==
vecGrupos[indGrupAnterior].nroGrupo)
break;
i++;
}
vecGrupos[indGrupAnterior].menorNroElem = i;
}
}
}
}

170 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.7 ClsAgrupImprime.h
/*
Clase que imprime agrupamientos, grupos y documentos
para ser desplegados al usuario

*/

#ifndef __clsAgrupImprime__

#define __clsAgrupImprime__

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "sis.h"
#include "vecArchivos.h"
#include "clsAgrupamiento.h"
#include "skipl.h"
#include "clsKMeans.h"

class c_Agrup_Imprime {
private:

public:
static bool salidaCompacta;
c_Agrup_Imprime() {};
~c_Agrup_Imprime() {};
static uent ImprimirVecArchivo(FILE *fp, c_VecArchivo &vecArchivo, c_SkipList
&lexico);
static uent ImprimirTodo(FILE *fp, c_Agrupamiento &agrup, c_VecArchivo
*vVecArchivos[], c_SkipList &lexico, c_SkipList &ltxt);
static uent ImprimirGrupo(FILE *fp, uent indGrupo, c_Agrupamiento &agrup,
c_VecArchivo *vVecArchivos[], c_SkipList &lexico, c_SkipList &ltxt);
static uent ImprimirDocumento(FILE *fp, uent nroElem, c_VecArchivo
*vVecArchivos[], c_SkipList &lexico);
};

#endif

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 171


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.8 ClsAgrupImprime.cpp
#include "clsAgrupImprime.h"

/* si se setea salidaCompacta en true, la salida va a estar preparada


para ser procesada en forma automática por otro programa */
bool c_Agrup_Imprime::salidaCompacta = false;

uent c_Agrup_Imprime::ImprimirVecArchivo(FILE *fp, c_VecArchivo &vecArchivo, c_SkipList


&lexico)
{
/* En "fp" recibe un archivo de texto abierto */
/* Imprime las palabras claves del vector */
uent i, cantKeywords;
ubyte palabra[MAX_LONG_PALABRA];
uent nroPalEnt;
uword nroPalLong;
real auxReal;

cantKeywords = vecArchivo.ConseguirCantEntradas(true);
/* recorremos la lista de atras para adelante porque las ultimas
entradas son las de mayor peso */
for (i=cantKeywords; i > 0; i--)
{
vecArchivo.ConseguirEntrada(i-1,nroPalEnt,auxReal,true);
if (nroPalEnt > 0)
{
/* la buscamos en la lista de lexico */
nroPalLong = (uword)nroPalEnt;
lexico.Buscar(palabra,nroPalLong);
/* la imprimimos */
fprintf(fp,"%s",(char*)palabra);
}
if (i > 1)
fprintf(fp," ; ");
}

return OK;
}

uent c_Agrup_Imprime::ImprimirDocumento(FILE *fp, uent nroElem, c_VecArchivo


*vVecArchivos[], c_SkipList &lexico)
{
/* En "fp" recibe un archivo de texto abierto */
/* Imprime las palabras claves del documento */
uent codRet;

if (salidaCompacta)
{
fprintf(fp,"%d",nroElem);
}
else
{
codRet = ImprimirVecArchivo(fp,*(vVecArchivos[nroElem]),lexico);
if (codRet != OK)
return codRet;

172 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

}
return OK;
}

uent c_Agrup_Imprime::ImprimirGrupo(FILE *fp,uent indGrupo,c_Agrupamiento


&agrup,c_VecArchivo *vVecArchivos[],c_SkipList &lexico, c_SkipList &ltxt)
{
/* en fp recibe un archivo abierto */
/* imprime el numero del grupo, sus palabras claves, y cada uno de los
documentos que lo componen */

uent j;
uword jLong;
ubyte nomArch[MAX_LONG_NOMARCH];
real similPromGrupo;
real simElemCent;

/* calculamos la similitud promedio de los elementos del grupo


(es igual al cuadrado de la norma del centroide) */
if (agrup.vecGrupos[indGrupo].vecCentroide != NULL)
similPromGrupo = agrup.vecGrupos[indGrupo].vecCentroide-
>CalcularNorma(false);
else
similPromGrupo = 0;
similPromGrupo *= similPromGrupo; /* al cuadrado */

/* imprimimos el numero del grupo */


if (salidaCompacta)
{
fprintf(fp,"_G_%d[%f]=",indGrupo,similPromGrupo);
}
else
{
fprintf(fp,"Grupo %d (%d). Elementos=%d. Similitud Promedio=%f :
",indGrupo+1,agrup.vecGrupos[indGrupo].nroGrupo,agrup.vecGrupos[indGrupo].cantElementos
,similPromGrupo);
if (agrup.vecGrupos[indGrupo].vecCentroide != NULL)
{
agrup.vecGrupos[indGrupo].vecCentroide->ActualizarPalabrasClave();

ImprimirVecArchivo(fp,*(agrup.vecGrupos[indGrupo].vecCentroide),lexico);
}
//xxxdebug
else

ImprimirVecArchivo(fp,*(vVecArchivos[agrup.vecGrupos[indGrupo].menorNroElem +
1]),lexico);
fprintf(fp,"\n");
}
/* imprimimos los elementos del grupo */
for (j=0; j < agrup.cantElementos; j++)
if (agrup.vecElementos[j] == agrup.vecGrupos[indGrupo].nroGrupo)
if (salidaCompacta)
{
jLong = (uword)j + 1;
ltxt.Buscar(nomArch,jLong);
fprintf(fp,"%s;",(char*)nomArch);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 173


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

//ImprimirDocumento(fp,j+1,vVecArchivos,lexico);
//fprintf(fp,";");
}
else
{
jLong = (uword)j + 1;
ltxt.Buscar(nomArch,jLong);
simElemCent =
c_KMeans::ValorCriterioActual(agrup,vVecArchivos,j,indGrupo);
fprintf(fp,"\t%s (%f)\n",(char*)nomArch,simElemCent);
fprintf(fp,"\t\t");
ImprimirDocumento(fp,j+1,vVecArchivos,lexico);
fprintf(fp,"\n");
}
fprintf(fp,"\n");
return OK;
}

uent c_Agrup_Imprime::ImprimirTodo(FILE *fp,c_Agrupamiento &agrup,c_VecArchivo


*vVecArchivos[],c_SkipList &lexico, c_SkipList &ltxt)
{
/* imprime el agrupamiento */
uent i, codRet;

for (i=0; i < agrup.cantGrupos ; i++)


{
codRet = ImprimirGrupo(fp,i,agrup,vVecArchivos,lexico,ltxt);
if (codRet != OK)
return codRet;
}

return OK;
}

174 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.9 ClsKMeans.h
/*
Clase que implementa las funciones del algoritmo kmeans

*/

#ifndef __clsKMeans__

#define __clsKMeans__

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "sis.h"
#include "vecArchivos.h"
#include "clsAgrupamiento.h"

//xxxdebug
#include "skipl.h"
#include "clsAgrupImprime.h"

class c_KMeans {
private:
static uent ElegirKCentroides(c_Agrupamiento &agrup, uent nroGrupo, uent
*indGrupos, c_VecArchivo *vVecArchivos[], bool bOptimizarSeparacion, uent cantMuestras);
public:
static uword contMoverYRecalcular; /* cuenta las veces que se llamó a la
función de mover y recalcular */
static uent k;
static uent codCriterio; /* el criterio de optimizacion que se utiliza para refinar */
/* 1 : minima distancia de cada elemento al centroide del grupo */
/* 2 : ... */
c_KMeans() {};
~c_KMeans() {};
static uent FaseInicial(c_Agrupamiento &agrup, uent nroGrupo, c_VecArchivo
*vVecArchivos[], uent *indGrupos, bool bOptimizarSeparacion, uent cantMuestras);
static uent FaseInicialLite(c_Agrupamiento &agrup, uent nroGrupo,
c_VecArchivo *vVecArchivos[], uent *indGrupos, bool bOptimizarSeparacion, uent
cantMuestras);
static uent CalcularCentroides(c_Agrupamiento &agrup,c_VecArchivo
*vVecArchivos[],uent cantGrup,uent *vecIndGrupos);
static uent FaseRefinar(c_Agrupamiento &agrup, c_VecArchivo
*vVecArchivos[], uent *indGrupos,bool iteracionesFijas, uent &cantIteraciones, uent
&cantCambiosTotal);
static uent FaseRefinarLite(c_Agrupamiento &agrup, c_VecArchivo
*vVecArchivos[], uent *indGrupos,bool iteracionesFijas, uent &cantIteraciones, uent
&cantCambiosTotal);
static bool NroGrupoEstaEnVectorIndices(uent nro, uent *vector,uent
cantEntradas, c_Agrupamiento &agrup, uent &indGrupo);
static real ValorCriterioActual(c_Agrupamiento &agrup, c_VecArchivo
*vVecArchivos[], uent nroElemAnalisis, uent indGrupoAnalisis);
static real ValorCriterioAlternativa(c_Agrupamiento &agrup, c_VecArchivo
*vVecArchivos[], uent nroElemAnalisis, uent indGrupoCandidato, real valCriterioActual);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 175


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

static uent MoverElementoyRecalcular(c_Agrupamiento &agrup,c_VecArchivo


*vVecArchivos[],uent nroElem,uent indGrupoOrig,uent indGrupoGanador, bool
restarACentroide);
static uent BisectingKMeans(c_Agrupamiento* &agrup, uent nroGrupo,
c_VecArchivo *vVecArchivos[], uent kBisect, bool refinar);
};

#endif

176 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.10 ClsKMeans.cpp
#include "clsKMeans.h"

#define MAX_VALOR_CRITERIO (real)1000000.0


/* maximo valor que va a tomar cualquiera de los criterios de
optimizacion */
#define MARGEN_CRITERIO (real)0.1

/* por defecto k = 5 */
uent c_KMeans::k = 5;
uword c_KMeans::contMoverYRecalcular = 0;

/* por defecto criterio = 1 */


uent c_KMeans::codCriterio = 1;

uent c_KMeans::ElegirKCentroides(c_Agrupamiento &agrup, uent nroGrupo, uent *indGrupos,


c_VecArchivo *vVecArchivos[], bool bOptimizarSeparacion, uent cantMuestras)
{
/* elige K centroides al azar
los K centroides al azar los toma del grupo "nroGrupo"
En el campo "menorNroElem" del grupo "nroGrupo"
pone el nro de elemento de uno de los centroides.
Tambien crea (k - 1) grupos más en el agrupamiento
y al campo "menorNroElem" de cada uno de esos grupos
le asigna su respectivo centroide
Deja el agrupamiento en un estado inconsistente,
ya que se usa el campo de menor grupo de elemento
para designar al centroide elegido.
(solo es inconsistente para el grupo "nroGrupo",
para los nuevos grupos, el centroide es el único elemento
En el vector "indGrupos" (que se recibe con memoria alocada para k
números) devuelve un vector con los índices del grupo original
y los grupos que se crearon
En el caso particular de que haya que elegir 2 centroides, si el
parámetro bOptimizarSeparacion es true, toma "cantMuestras" elementos
al azar y elige los 2 que están más distantes el uno del otro
*/
uent *nrosAzar, *vNroElem;
uent indGrupo, cantElemGrupo, cantGruposAnterior;
uent codRet;
uent i, j, indElem, indElemGrupo;
uent parejaMasDistante[2];
real menorSimProm, simProm;
c_VecArchivo *vArch1, *vArch2;

indGrupo = agrup.IndiceDeGrupo(nroGrupo,false);
cantElemGrupo = agrup.vecGrupos[indGrupo].cantElementos;
cantGruposAnterior = agrup.cantGrupos;

/* generamos los numeros al azar */


if ((bOptimizarSeparacion == false) || (k != 2))
{
/* deben generarse k numeros al azar */
cantMuestras = k;
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 177


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* generamos cantMuestras números que esten entre 1 y la cantidad de elementos


del grupo */
nrosAzar = kNumerosRandom(cantMuestras,1,cantElemGrupo,true);
if (nrosAzar == NULL)
return ERROR_MEMORIA;
vNroElem = (uent*)malloc(cantMuestras * SINT);
if (vNroElem == NULL)
return ERROR_MEMORIA;
/* asignamos el numero de elemento que corresponde a cada uno */
indElem = 0;
indElemGrupo = 0;
for (i=0; i < cantMuestras; i++)
{
while(indElemGrupo < nrosAzar[i])
{
if (agrup.vecElementos[indElem] == nroGrupo)
indElemGrupo++;
indElem++;
}
vNroElem[i] = indElem - 1;
}

if ((bOptimizarSeparacion == true) && (k == 2))


{
/* tenemos que elegir los 2 elementos mas distantes */
menorSimProm = (real)10000.0;
/* vamos del primero al anteultimo */
for (i = 0; i < cantMuestras - 1; i++)
{
vArch1 = vVecArchivos[vNroElem[i]+1];
/* vamos desde el siguiente a i hasta el ultimo */
for (j=i+1; j < cantMuestras; j++)
{
vArch2 = vVecArchivos[vNroElem[j]+1];
/* calculamos la similitud */
simProm = vArch1->Multiplicar(*vArch2,false);
if (simProm < menorSimProm)
{
menorSimProm = simProm;
parejaMasDistante[0] = vNroElem[i];
parejaMasDistante[1] = vNroElem[j];
}
}
}
vNroElem[0] = parejaMasDistante[0];
vNroElem[1] = parejaMasDistante[1];
}

/* creamos k - 1 grupos mas */


codRet = agrup.AgregarGrupos(k - 1);
if (codRet != OK)
return codRet;
/* ahora, al campo "menorNroElem" de cada grupo le asignamos el
número de elemento elegido al azar */
indElem = 0;
indElemGrupo = 0;
for (i=0; i < k; i++)
{

178 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (i == 0) /* el primero es el grupo original */


{
agrup.vecGrupos[indGrupo].menorNroElem = vNroElem[i];
indGrupos[i] = indGrupo;
}
else /* los siguientes son los que se agregaron */
{
agrup.vecGrupos[cantGruposAnterior - 1 + i].menorNroElem =
vNroElem[i];
indGrupos[i] = cantGruposAnterior - 1 + i;
}
}

free((void*)nrosAzar);
free((void*)vNroElem);

return OK;
}

uent c_KMeans::FaseInicial(c_Agrupamiento &agrup, uent nroGrupo, c_VecArchivo


*vVecArchivos[], uent *indGrupos, bool bOptimizarSeparacion, uent cantMuestras)
{
/* Fase inicial del algoritmo kmeans
Se supone que el agrupamiento "agrup" se ha inicializado
y contiene al menos 1 grupo
En "nroGrupo" recibe el numero de grupo a separar
En la fase inicial, se arma un agrupamiento de la siguiente forma:
- se eligen k elementos como los centroides
- se asigna cada elemento al grupo del centroide más cercano
En el vector "indGrupos" (que se recibe con memoria alocada para k
números) devuelve un vector con los índices de los
grupos en los que se separaron los elementos
Devuelve OK o el error que corresponda
*/
uent grupGanador, indGrupo, cantGruposAnterior;
real similGanador, similAux;
uent codRet;
uent *ordenProceso, *nrosElementos;
uent cantElemGrupo, i, j, indElemGrupo, nroElem;
c_VecArchivo *vecArchivoElem;
bool esCentroide,ganoEmpate;
uent empates;

/* tomamos el índice del grupo y la cantidad de grupos */


indGrupo = agrup.IndiceDeGrupo(nroGrupo,false);
cantGruposAnterior = agrup.cantGrupos;

/* elegimos los k centroides de los elementos del grupo */


codRet =
ElegirKCentroides(agrup,nroGrupo,indGrupos,vVecArchivos,bOptimizarSeparacion,cantMuestr
as);
if (codRet != OK)
return codRet;

/* elegimos un orden al azar para procesar los elementos del grupo */


cantElemGrupo = agrup.vecGrupos[indGrupo].cantElementos;
ordenProceso = kNumerosRandom(cantElemGrupo,1,cantElemGrupo,false);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 179


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (ordenProceso == NULL)
return ERROR_MEMORIA;
/* armamos un vector con los numeros de elemento del grupo */
nrosElementos = (uent*)malloc(cantElemGrupo * SINT);
indElemGrupo = 0;
for (i = 0; i < agrup.cantElementos; i++)
{
if (agrup.vecElementos[i] == nroGrupo)
{
//xxxdebug
//printf("c_KMeans::FI::orAzar : %d ;; nroElem :
%d\n",ordenProceso[indElemGrupo]-1,i);
nrosElementos[ordenProceso[indElemGrupo]-1] = i;
indElemGrupo++;
}
}
/* el centroide de cada grupo es el elemento que figura en el campo "menorNroElem" */
for (i = 0; i < k; i++)
{
if (i == 0)
j = indGrupo;
else
j = cantGruposAnterior + i - 1;
if (agrup.vecGrupos[j].vecCentroide != NULL)
delete(agrup.vecGrupos[j].vecCentroide);
agrup.vecGrupos[j].vecCentroide = new c_VecArchivo;
agrup.vecGrupos[j].vecCentroide-
>Duplicar(*(vVecArchivos[agrup.vecGrupos[j].menorNroElem + 1]));
}

/* los procesamos en el orden al azar, buscando su nuevo grupo */


for (i = 0; i < cantElemGrupo; i++)
{
empates = 0;
esCentroide = false;
nroElem = nrosElementos[i];
vecArchivoElem = vVecArchivos[nroElem + 1];
/* veamos la similitud con el centroide del grupo original */
if (nroElem == agrup.vecGrupos[indGrupo].menorNroElem)
{
esCentroide = true;
grupGanador = indGrupo;
}
else
{
similGanador = vecArchivoElem-
>Multiplicar(*(agrup.vecGrupos[indGrupo].vecCentroide),false);
grupGanador = indGrupo;
}
/* ahora con los otros */
for (j = 0; j < k-1; j++)
{
if (!esCentroide)
{
if (nroElem == agrup.vecGrupos[cantGruposAnterior +
j].menorNroElem)
{
esCentroide = true;

180 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

grupGanador = cantGruposAnterior + j;
}
else
{
similAux = vecArchivoElem-
>Multiplicar(*(agrup.vecGrupos[cantGruposAnterior + j].vecCentroide),false);
ganoEmpate = false;
if (similAux == similGanador)
{
empates++;
ganoEmpate = (RANDOM(empates+1)==0);
}
if ((similAux > similGanador) || ganoEmpate)
{
similGanador = similAux;
grupGanador = cantGruposAnterior + j;
}
}
}
}
if (bOptimizarSeparacion)
{

c_KMeans::MoverElementoyRecalcular(agrup,vVecArchivos,nroElem,indGrupo,grupGa
nador,false);
}
else
{
/* si hace falta, lo movemos */
if (grupGanador != indGrupo)
{
agrup.MoverElemento(nroElem, grupGanador, indGrupo);
}
}
//xxxdebug
//if (esCentroide)
//printf("c_KMeans:FI: Elem : %d ;; Es centroide de :
%d\n",nroElem,grupGanador + 1);
//else
//printf("c_KMeans:FI: Elem : %d ;; SimGan : %f ;; GrupGan :
%d\n",nroElem,similGanador,grupGanador + 1);
}

free((void*)ordenProceso);
free((void*)nrosElementos);

return OK;
}

uent c_KMeans::FaseInicialLite(c_Agrupamiento &agrup, uent nroGrupo, c_VecArchivo


*vVecArchivos[], uent *indGrupos, bool bOptimizarSeparacion, uent cantMuestras)
{
/*
Igual que la fase inicial pero version "Lite"
*/
uent grupGanador, indGrupo, cantGruposAnterior;
real similGanador, similAux;
uent codRet;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 181


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent *ordenProceso, *nrosElementos;


uent cantElemGrupo, i, j, indElemGrupo, nroElem;
c_VecArchivo *vecArchivoElem;
bool esCentroide,ganoEmpate;
uent empates;
uent cantGruposMuestra;
uent *vecIndGruposMuestra;

/* tomamos el índice del grupo y la cantidad de grupos */


indGrupo = agrup.IndiceDeGrupo(nroGrupo,false);
cantGruposAnterior = agrup.cantGrupos;

/* elegimos los k centroides de los elementos del grupo */


codRet =
ElegirKCentroides(agrup,nroGrupo,indGrupos,vVecArchivos,bOptimizarSeparacion,cantMuestr
as);
if (codRet != OK)
return codRet;

/* elegimos un orden al azar para procesar los elementos del grupo */


cantElemGrupo = agrup.vecGrupos[indGrupo].cantElementos;
ordenProceso = kNumerosRandom(cantElemGrupo,1,cantElemGrupo,false);
if (ordenProceso == NULL)
return ERROR_MEMORIA;
/* armamos un vector con los numeros de elemento del grupo */
nrosElementos = (uent*)malloc(cantElemGrupo * SINT);
indElemGrupo = 0;
for (i = 0; i < agrup.cantElementos; i++)
{
if (agrup.vecElementos[i] == nroGrupo)
{
//xxxdebug
//printf("c_KMeans::FI::orAzar : %d ;; nroElem :
%d\n",ordenProceso[indElemGrupo]-1,i);
nrosElementos[ordenProceso[indElemGrupo]-1] = i;
indElemGrupo++;
}
}
/* la cantidad de grupos muestra es del orden de log k */
cantGruposMuestra = (uent)(log(k)/log(2))*2;
/* los procesamos en el orden al azar, buscando su nuevo grupo */
for (i = 0; i < cantElemGrupo; i++)
{
/* armamos el vector de muestra de grupos */
vecIndGruposMuestra = kNumerosRandom(cantGruposMuestra,0,k-1,true);
if (vecIndGruposMuestra == NULL)
return ERROR_MEMORIA;
empates = 0;
esCentroide = false;
nroElem = nrosElementos[i];
vecArchivoElem = vVecArchivos[nroElem + 1];
/* veamos la similitud con el centroide del grupo original */
if (nroElem == agrup.vecGrupos[vecIndGruposMuestra[0]].menorNroElem)
{
esCentroide = true;
grupGanador = vecIndGruposMuestra[0];
}
else

182 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
similGanador = vecArchivoElem-
>Multiplicar(*(vVecArchivos[agrup.vecGrupos[vecIndGruposMuestra[0]].menorNroElem +
1]),false);
grupGanador = vecIndGruposMuestra[0];
}
/* ahora con los otros */
for (j = 1; j < cantGruposMuestra-1; j++)
{
if (!esCentroide)
{
if (nroElem ==
agrup.vecGrupos[vecIndGruposMuestra[j]].menorNroElem)
{
esCentroide = true;
grupGanador = vecIndGruposMuestra[j];
}
else
{
similAux = vecArchivoElem-
>Multiplicar(*(vVecArchivos[agrup.vecGrupos[vecIndGruposMuestra[j]].menorNroElem +
1]),false);
ganoEmpate = false;
if (similAux == similGanador)
{
empates++;
ganoEmpate = (RANDOM(empates+1)==0);
}
if ((similAux > similGanador) || ganoEmpate)
{
similGanador = similAux;
grupGanador = vecIndGruposMuestra[j];
}
}
}
}
/* si hace falta, lo movemos */
if (grupGanador != indGrupo)
{
agrup.MoverElemento(nroElem, grupGanador, indGrupo);
}

free((void*)vecIndGruposMuestra);

//xxxdebug
//if (esCentroide)
//printf("c_KMeans:FI: Elem : %d ;; Es centroide de :
%d\n",nroElem,grupGanador + 1);
//else
//printf("c_KMeans:FI: Elem : %d ;; SimGan : %f ;; GrupGan :
%d\n",nroElem,similGanador,grupGanador + 1);
}

free((void*)ordenProceso);
free((void*)nrosElementos);

return OK;
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 183


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent c_KMeans::CalcularCentroides(c_Agrupamiento &agrup,c_VecArchivo


*vVecArchivos[],uent cantGrup,uent *vecIndGrupos)
{
/* calcula los centroides de los grupos */
/* devuelve OK o el error que corresponda */
/* si cantGrup es 0, calcula los centroides de todos los grupos
si no, calcula solamente los centroides de los grupos que estan
en vecIndGrupos */
uent i,codRet,indAux;
uent j, cantElemGrup;
real unoSobre;
c_VecArchivo *centroide;

for (i=0; i < agrup.cantGrupos; i++)


{
if ((cantGrup == 0) ||
NroGrupoEstaEnVectorIndices(agrup.vecGrupos[i].nroGrupo,vecIndGrupos,cantGrup,agrup,ind
Aux))
{
/* si tenía el centroide creado, lo reinicializamos */
if (agrup.vecGrupos[i].vecCentroide != NULL)
{
delete(agrup.vecGrupos[i].vecCentroide);
}
centroide = new c_VecArchivo;
agrup.vecGrupos[i].vecCentroide = centroide;
codRet = centroide->CrearVector(0);
if (codRet != OK)
return codRet;
cantElemGrup = agrup.vecGrupos[i].cantElementos;
/* sumamos los elementos de ese grupo */
for (j=0; j < agrup.cantElementos; j++)
if (agrup.vecElementos[j] == agrup.vecGrupos[i].nroGrupo)
centroide->Sumar(*(vVecArchivos[j+1]));
/* dividimos cada entrada por la cantidad de elementos del grupo */
unoSobre = (real)1.0 / (real)cantElemGrup;
centroide->MultiplicarPorReal(unoSobre);
/* actualizamos las palabras clave */
centroide->ActualizarPalabrasClave();
}
}

return OK;
}

uent c_KMeans::FaseRefinar(c_Agrupamiento &agrup, c_VecArchivo *vVecArchivos[], uent


*indGrupos,bool iteracionesFijas, uent &cantIteraciones, uent &cantCambiosTotal)
{
/* ejecuta la fase de refinamiento del algoritmo k-means
en el vector indGrupos recibe los indices de los grupos entre los
cuales puede mover documentos
en agrup recibe un agrupamiento que ya tiene calculados
los centroides de sus grupos
el parametro iteracionesFijas indica si el algoritmo debe ejecutarse
hasta un numero máximo de iteraciones. en caso de que sea verdadero,
el parametro cantIteraciones indica este número máximo

184 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

la función itera hasta que no se producen cambios en los grupos o


hasta alcanzar el máximo número de iteraciones (si corresponde)
en el parametro cantIteraciones se devuelve la cantidad de iteraciones
que se realizaron
*/
uent iIteraciones,iElem,iGrupos,cantCambios, indGrupoOrig;
uent cantElementos, nroElem, nroGrupoElem, indGrupoGanador;
uent *ordenProceso;
real valorActual, valorAux, incGanador;
uent codRet;
bool bParar;

cantElementos = agrup.cantElementos;
iIteraciones = 0;
cantCambiosTotal = 0;
bParar = false;

while (!bParar)
{
cantCambios = 0;
/* buscamos un orden al azar para procesar los elementos */
ordenProceso = kNumerosRandom(cantElementos,0,cantElementos-1,false);
if (ordenProceso == NULL)
return ERROR_MEMORIA;
/* vamos iterando por todos los elementos pero procesamos
solamente los de los grupos que nos interesan */
for (iElem=0; iElem<cantElementos; iElem++)
{
/* tomamos el elemento */
nroElem = ordenProceso[iElem];

///xxxdebug
//printf("KMRefinar:Proc.Elem=%d\n",nroElem);

nroGrupoElem = agrup.vecElementos[nroElem];
/* veamos si esta en uno de los grupos que nos interesan */
if
(NroGrupoEstaEnVectorIndices(nroGrupoElem,indGrupos,k,agrup,indGrupoOrig))
{
///xxxdebug
//printf(" nos interesa(grupo=%d)\n",nroGrupoElem);

/* calculamos el valor actual, y decimos que el ganador es el


grupo
actual */
indGrupoGanador = indGrupoOrig;
valorActual =
ValorCriterioActual(agrup,vVecArchivos,nroElem,indGrupoOrig);
incGanador = 0.0;
/* evaluamos el movimiento a cada uno de los otros
grupos */
//xxxdebug
//printf(" increm:[%f];;;",valorActual);
for (iGrupos=0; iGrupos < k; iGrupos++)
{
if (iGrupos != indGrupoGanador) /* no
evaluamos 2 veces el grupo original */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 185


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
valorAux =
ValorCriterioAlternativa(agrup,vVecArchivos,nroElem,iGrupos,valorActual);
if ((valorAux - valorActual) > incGanador)
{
/* este incremento va ganando por
ahora */
indGrupoGanador = iGrupos;
incGanador = (valorAux - valorActual);
}
//xxxdebug
//printf("%f;;;",valorAux - valorActual);
}
}
//xxxdebug
//printf("\n");
/* veamos si hubo un ganador */
if (indGrupoGanador != indGrupoOrig)
{
/* hay que mover el elemento */
codRet =
MoverElementoyRecalcular(agrup,vVecArchivos,nroElem,indGrupoOrig,indGrupoGanador,true)
;
if (codRet != OK)
return codRet;
cantCambios++; /* sumamos un cambio esta vuelta */
//xxxdebug
//printf("KMRefinar::Cambio.Iter=%d
Elem=%d;Orig=%d;Dest=%d\n",iIteraciones,nroElem,indGrupoOrig,indGrupoGanador);
}
}
}

cantCambiosTotal += cantCambios;

//xxxdebug
//printf("KMRefinar::FinIter=%d Cambios=%d\n",iIteraciones,cantCambios);

/* liberamos el vector de orden aleatorio */


free((void*)ordenProceso);
/* si no hubo ningun cambio tenemos que parar */
if (cantCambios == 0)
bParar = true;
/* sumamos una iteracion mas y vemos si ya tenemos que parar */
iIteraciones++;
if (iIteraciones >= cantIteraciones)
bParar = true;
}

/* devolvemos la cantidad de iteraciones */


cantIteraciones = iIteraciones;

//xxxdebug
printf("KMRefinar::Fin TotalIter=%d
TotalCambios=%d\n",iIteraciones,cantCambiosTotal);

return OK;

186 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent c_KMeans::FaseRefinarLite(c_Agrupamiento &agrup, c_VecArchivo *vVecArchivos[], uent


*indGrupos,bool iteracionesFijas, uent &cantIteraciones, uent &cantCambiosTotal)
{
/*
Igual que la fase inicial pero version "Lite"
*/
uent iIteraciones,iElem,iGrupos,cantCambios, indGrupoOrig;
uent cantElementos, nroElem, nroGrupoElem, indGrupoGanador;
uent *ordenProceso;
real valorActual, valorAux, incGanador;
uent codRet;
bool bParar;
uent cantGruposMuestra;
uent *vecIndGruposMuestra;
uent h;

cantElementos = agrup.cantElementos;
iIteraciones = 0;
cantCambiosTotal = 0;
bParar = false;

/* la cantidad de grupos muestra es del orden de log k */


cantGruposMuestra = (uent)(log(k)/log(2))*2;

while (!bParar)
{
cantCambios = 0;
/* buscamos un orden al azar para procesar los elementos */
ordenProceso = kNumerosRandom(cantElementos,0,cantElementos-1,false);
if (ordenProceso == NULL)
return ERROR_MEMORIA;
/* vamos iterando por todos los elementos pero procesamos
solamente los de los grupos que nos interesan */
for (iElem=0; iElem<cantElementos; iElem++)
{
/* tomamos el elemento */
nroElem = ordenProceso[iElem];

///xxxdebug
//printf("KMRefinar:Proc.Elem=%d\n",nroElem);

nroGrupoElem = agrup.vecElementos[nroElem];
/* veamos si esta en uno de los grupos que nos interesan */
if
(NroGrupoEstaEnVectorIndices(nroGrupoElem,indGrupos,k,agrup,indGrupoOrig))
{
///xxxdebug
//printf(" nos interesa(grupo=%d)\n",nroGrupoElem);

/* armamos el vector de muestra de grupos */


vecIndGruposMuestra =
kNumerosRandom(cantGruposMuestra,0,k-1,true);
if (vecIndGruposMuestra == NULL)
{
//xxxdebug
perror("Null vecIndGruposMuestra...");

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 187


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

getchar(); getchar();
return ERROR_MEMORIA;
}

/* calculamos el valor actual, y decimos que el ganador es el


grupo
actual */
indGrupoGanador = indGrupoOrig;
valorActual =
ValorCriterioActual(agrup,vVecArchivos,nroElem,indGrupoOrig);
incGanador = 0.0;
/* evaluamos el movimiento a cada uno de los otros
grupos */
//xxxdebug
//printf(" increm:[%f];;;",valorActual);
for (h=0; h < cantGruposMuestra; h++)
{
iGrupos = vecIndGruposMuestra[h];
if (iGrupos != indGrupoGanador) /* no
evaluamos 2 veces el grupo original */
{
valorAux =
ValorCriterioAlternativa(agrup,vVecArchivos,nroElem,iGrupos,valorActual);
if ((valorAux - valorActual) > incGanador)
{
/* este incremento va ganando por
ahora */
indGrupoGanador = iGrupos;
incGanador = (valorAux - valorActual);
}
//xxxdebug
//printf("%f;;;",valorAux - valorActual);
}
}
free((void*)vecIndGruposMuestra);
//xxxdebug
//printf("\n");
/* veamos si hubo un ganador */
if (indGrupoGanador != indGrupoOrig)
{
/* hay que mover el elemento */
codRet =
MoverElementoyRecalcular(agrup,vVecArchivos,nroElem,indGrupoOrig,indGrupoGanador,true)
;
if (codRet != OK)
return codRet;
cantCambios++; /* sumamos un cambio esta vuelta */
//xxxdebug
//printf("KMRefinar::Cambio.Iter=%d
Elem=%d;Orig=%d;Dest=%d\n",iIteraciones,nroElem,indGrupoOrig,indGrupoGanador);
}
}
}

cantCambiosTotal += cantCambios;

//xxxdebug
//printf("KMRefinar::FinIter=%d Cambios=%d\n",iIteraciones,cantCambios);

188 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* liberamos el vector de orden aleatorio */


free((void*)ordenProceso);
/* si no hubo ningun cambio tenemos que parar */
if (cantCambios == 0)
bParar = true;
/* sumamos una iteracion mas y vemos si ya tenemos que parar */
iIteraciones++;
if (iIteraciones >= cantIteraciones)
bParar = true;
}

/* devolvemos la cantidad de iteraciones */


cantIteraciones = iIteraciones;

//xxxdebug
printf("KMRefinarLite::Fin TotalIter=%d
TotalCambios=%d\n",iIteraciones,cantCambiosTotal);

return OK;
}

bool c_KMeans::NroGrupoEstaEnVectorIndices(uent nro, uent *vector,uent cantEntradas,


c_Agrupamiento &agrup, uent &indGrupo)
{
/* busca si el numero de grupo "nro" tiene un indice que esté dentro
del vector "vector", que tiene "cantEntradas" entradas
si está, en el parametro "indGrupo" devuelve el indice del grupo
*/

uent i;

for (i=0; i < cantEntradas; i++)


if (agrup.vecGrupos[vector[i]].nroGrupo == nro)
{
indGrupo = vector[i];
return true;
}

return false;

real c_KMeans::ValorCriterioActual(c_Agrupamiento &agrup, c_VecArchivo *vVecArchivos[],


uent nroElemAnalisis, uent indGrupoAnalisis)
{
/*
calcula el valor actual del criterio que se optimiza con el algoritmo
en "nroElemAnalisis" recibe el nro de elemento que está siendo analizado
para ver si se mueve a otro grupo (para algunos criterios va a hacer falta)
en "indGrupoAnalisis" recibe el indice del grupo al cual pertenece el
elemento que se está analizando (para algunos criterios va a hacer falta)
*/

/* antes que nada, veamos si el elemento es el ultimo que queda


en el grupo. En ese caso, devolvemos el maximo valor, ya que
no se deben eliminar grupos */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 189


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (agrup.vecGrupos[indGrupoAnalisis].cantElementos <= 1)
return MAX_VALOR_CRITERIO;

real valorCriterio;
real normaCent;

switch (codCriterio)
{
case 1 :
{
c_VecArchivo *vecCent, *vecElem;
real simil;
/* este criterio es igual a la similitud entre
el centroide del grupo y el elemento */
vecCent = agrup.vecGrupos[indGrupoAnalisis].vecCentroide;
vecElem = vVecArchivos[nroElemAnalisis+1];
simil = vecCent->Multiplicar(*vecElem,false);
normaCent = vecCent->CalcularNorma(false);
valorCriterio = simil / normaCent;
break;
}
default :
{
/* error : no estaba definido el criterio */
valorCriterio = 0.0;
}
}

/* siempre tenemos que devolver algo menor que el maximo */


if (valorCriterio >= MAX_VALOR_CRITERIO)
valorCriterio = MAX_VALOR_CRITERIO - MARGEN_CRITERIO;

return valorCriterio;
}

real c_KMeans::ValorCriterioAlternativa(c_Agrupamiento &agrup, c_VecArchivo


*vVecArchivos[], uent nroElemAnalisis, uent indGrupoCandidato, real valCriterioActual)
{
/*
calcula el valor del criterio para la alternativa de mover el
elemento "nroElem" al grupo de indice "indGrupoCandidato"
en "nroElemAnalisis" recibe el nro de elemento que está siendo analizado
en "indGrupoCandidato" recibe el indice del grupo al cual se está
evaluando mover el elemento
en "valCriterioActual" recibe el valor actual del criterio
(para algunos criterios puede hacer falta)
*/
real valorCriterio;
real normaCent;

switch (codCriterio)
{
case 1 :
{
c_VecArchivo *vecCent, *vecElem;
real simil;
/* este criterio es igual a la similitud entre

190 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

el centroide del grupo y el elemento */


vecCent = agrup.vecGrupos[indGrupoCandidato].vecCentroide;
vecElem = vVecArchivos[nroElemAnalisis+1];
simil = vecCent->Multiplicar(*vecElem,false);
normaCent = vecCent->CalcularNorma(false);
valorCriterio = simil / normaCent;
break;
}
default :
{
/* error : no estaba definido el criterio */
valorCriterio = 0.0;
}
}

/* siempre tenemos que devolver algo menor que el maximo */


if (valorCriterio >= MAX_VALOR_CRITERIO)
valorCriterio = MAX_VALOR_CRITERIO - MARGEN_CRITERIO;

return valorCriterio;

uent c_KMeans::MoverElementoyRecalcular(c_Agrupamiento &agrup,c_VecArchivo


*vVecArchivos[],uent nroElem,uent indGrupoOrig,uent indGrupoGanador, bool
restarACentroide)
{
/* mueve el elemento "nroElem" del grupo con indice "indGrupoOrig"
al grupo con indice "indGrupoGanador"
recalcula todo lo que haga falta dentro del agrupamiento
(ej : centroides) que sea necesario de acuerdo a cada criterio
*/

uent codRet;

contMoverYRecalcular++;

switch (codCriterio)
{
case 1 :
{
c_VecArchivo *vecCentOrig, *vecCentGanador, *vecElem;
real unoSobre;
uent cantElemOrig, cantElemGanador;
/* recalculamos los centroides de los 2 grupos */
vecCentOrig = agrup.vecGrupos[indGrupoOrig].vecCentroide;
vecCentGanador = agrup.vecGrupos[indGrupoGanador].vecCentroide;
vecElem = vVecArchivos[nroElem+1];
cantElemOrig = agrup.vecGrupos[indGrupoOrig].cantElementos;
cantElemGanador =
agrup.vecGrupos[indGrupoGanador].cantElementos;
/* al original le restamos el elemento que le sacamos */
/* primero lo multiplicamos por la cantidad de elementos anterior */
if (restarACentroide == true)
{
vecCentOrig->MultiplicarPorReal((real)cantElemOrig);
codRet = vecCentOrig->Restar(*vecElem);
if (codRet != OK)

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 191


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

return codRet;
unoSobre = (real)1.0 / (real)(cantElemOrig - 1);
vecCentOrig->MultiplicarPorReal(unoSobre);
}
/* al ganador le sumamos el elemento que le agregamos */
/* primero lo multiplicamos por la cantidad de elementos anterior */
vecCentGanador->MultiplicarPorReal((real)cantElemGanador);
codRet = vecCentGanador->Sumar(*vecElem);
if (codRet != OK)
return codRet;
unoSobre = (real)1.0 / (real)(cantElemGanador + 1);
vecCentGanador->MultiplicarPorReal(unoSobre);
/* movemos el elemento de un grupo al otro */
agrup.MoverElemento(nroElem,indGrupoGanador,indGrupoOrig);
break;
}
default :
{
/* error : no estaba definido el criterio */

}
}

return OK;

uent c_KMeans::BisectingKMeans(c_Agrupamiento* &agrup, uent nroGrupo, c_VecArchivo


*vVecArchivos[], uent kBisect, bool refinar)
/*
Divide al grupo "nroGrupo" en k grupos usando el algoritmo
bisecting kmeans (Steinbach et al, 2000)
Se divide el grupo en "kBisect" grupos usando el algoritmo kmeans basico, luego
se toma el grupo mas grande y se lo vuelve a dividir en "kBisect", etc
Para que esto funcione, debe cumplirse que
k = 1 + (n * (kBisect-1)) con "n" cualquier entero mayor a 0
Si refinar es "true", cuando termina, corre la fase de refinacion
sobre el agrupamiento
Devuelve OK o el error que corresponda
*/
{
uent codRet;
uent *vec2Ind, *vecIndices, indiceAux;
uent kOriginal, cantCambiosTotal = 0;
uent iCantGrupos, i, cantIter;
uent nroADividir, cantElemMax;

uent j, cantCandidatosKMeans = 5; /* cantidad de veces que se hace el KMeans


basico */
real normaCent, simProm, maxSimProm;
uent indMejor;
c_Agrupamiento **vecAgrups;

/* creamos un vector de punteros a los agrupamientos candidatos */


vecAgrups = (c_Agrupamiento**)malloc(cantCandidatosKMeans *
sizeof(c_Agrupamiento*));

192 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (vecAgrups == NULL)
return ERROR_MEMORIA;

kOriginal = k; /* guardamos la variable de clase k */


k = kBisect; /* seteamos k = kBisect */

/* este vector va a contener los kBisect indices de los grupos que vamos
a ir refinando */
vec2Ind = (uent*)malloc(k * SINT);
if (vec2Ind == NULL)
return ERROR_MEMORIA;

/* en este vector vamos a tener los indices de los grupos que vamos
generando */
vecIndices = (uent*)malloc(kOriginal * SINT);
if (vecIndices == NULL)
return ERROR_MEMORIA;

iCantGrupos = 1; /* ahora tenemos 1 solo grupo */


vecIndices[0] = agrup->IndiceDeGrupo(nroGrupo,false); /* es el grupo original */

while (iCantGrupos < kOriginal) /* hasta que no tengamos la cantidad de grupos que
queremos */
{
/* buscamos el grupo que tenga la mayor cantidad de elementos */
cantElemMax = 0;
for (i=0; i < agrup->cantGrupos; i++)
{
if (NroGrupoEstaEnVectorIndices(agrup-
>vecGrupos[i].nroGrupo,vecIndices,iCantGrupos,*agrup,indiceAux))
{
if (agrup->vecGrupos[i].cantElementos > cantElemMax)
{
nroADividir = agrup->vecGrupos[i].nroGrupo;
cantElemMax = agrup->vecGrupos[i].cantElementos;
}
}
}

/* vamos a buscar candidatos usando el kmeans basico */


/* creamos los candidatos */
maxSimProm = -1; /* inicializamos el maximo como negativo */
for (i=0; i < cantCandidatosKMeans; i++)
{
/* creamos un agrupamiento y lo hacemos igual al que tenemos
hasta ahora */
vecAgrups[i] = new c_Agrupamiento();
if (vecAgrups[i] == NULL)
return ERROR_MEMORIA;
codRet = vecAgrups[i]->Duplicar(*agrup);
if (codRet != OK)
return codRet;

/* dividimos el nro de grupo que tenia mas elementos */


codRet =
FaseInicial(*(vecAgrups[i]),nroADividir,vVecArchivos,vec2Ind,false,0);
if (codRet != OK)
return codRet;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 193


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* calculamos los centroides */


codRet = CalcularCentroides(*(vecAgrups[i]),vVecArchivos,k,vec2Ind);
if (codRet != OK)
return codRet;
/* refinamos */
cantIter = 100;
codRet =
FaseRefinar(*(vecAgrups[i]),vVecArchivos,vec2Ind,true,cantIter,cantCambiosTotal);
if (codRet != OK)
return codRet;

/* calculamos la similitud promedio de los nuevos grupos */


simProm = 0;
for (j = 0; j < k; j++)
{
/* buscamos la norma del centroide */
normaCent = ((vecAgrups[i]-
>vecGrupos[vec2Ind[j]]).vecCentroide)->CalcularNorma(false);
simProm += normaCent * normaCent;
//xxxdebug
printf("BisKM:NormaCent[%d,%d] = %f\n",i,j,normaCent *
normaCent);
}

if (simProm > maxSimProm)


{
/* este es el mejor que tenemos hasta el momento */
maxSimProm = simProm;
indMejor = i;
}

//xxxdebug
printf("BisKM:SimProm[%d] = %f\n",i,simProm / k);
//c_Agrup_Imprime::salidaCompacta = false;
//c_Agrup_Imprime::ImprimirTodo(stdout,agrup,vVecArchivos,lLex,lTxt);
//printf ("Otra Iter \n");
}

//xxxdebug
printf("BisKM:SimPromGanador[%d] = %f\n",indMejor,maxSimProm / k);

/* nos quedamos con el mejor candidato y destruimos el resto */


for (i=0; i < cantCandidatosKMeans; i++)
{
if (i!=indMejor)
delete(vecAgrups[i]);
}
delete agrup;
agrup = vecAgrups[indMejor];

/* ingresamos los nuevos grupos en el vector */


for (i=1; i < k; i++)
vecIndices[iCantGrupos + i - 1] = vec2Ind[i];
iCantGrupos += k - 1;
}

/* restauramos el valor de k */
k = kOriginal;

194 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* veamos si hay que refinar */


if (refinar)
{
cantIter = 100;
FaseRefinar(*agrup,vVecArchivos,vecIndices,true,cantIter,cantCambiosTotal);
}

/* liberamos los vectores que creamos */


free((void*)vecIndices);
free((void*)vec2Ind);
free((void*)vecAgrups);

return OK;
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 195


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.11 ClsGenetico.h
/*
Clase que implementa las funciones del algoritmo genetico

*/

#ifndef __clsGenetico__

#define __clsGenetico__

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "def.h"
#include "sis.h"
#include "vecArchivos.h"
#include "clsAgrupamiento.h"
#include "clsKMeans.h"

//xxxdebug
#include "skipl.h"
#include "clsAgrupImprime.h"

typedef struct _t_RegConfigGenetico {


FILE *fpSalidaDebug; /* puntero a un archivo al que se envía la salida de depuracion */
uent generacionesMaximo; /* maximo numero de generaciones */
uent poblacionTamanio; /* tamaño de la poblacion */
uent poblacionTamanioDeseado; /* el tamaño de la poblacion tiene que llegar a ser
este */
uent torneoTamanio; /* tamaño del torneo */
real torneoProbMejor; /* probabilidad que tiene de ser elegido el mejor del torneo */
uent fitnessCriterio; /* criterio para calcular el fitness
1 : similitud promedio de los elementos
de cada grupo
2 : promedio de las normas de los
centroides
3 : .. (no definido todavia)
*/
uent cruzaOperador; /* operador de cruza a utilizar
1 : pasar un grupo del padre al hijo
2 : ... (no definido todavia)
*/
real cruzaPasaGrupoProbMejor; /* probabilidad de que la cruza que pasa grupos pase
el de mayor similitud promedio */
real cruzaPasaGrupoProbMasElemComun; /* probabilidad de que el grupo destino sea
el que tiene mas elementos en comun */
real cruzaPasaGrupoProbMasSimilar; /* probabilidad de que el grupo destino sea el
mas similar */
real cruzaPasaGrupoProbMenorSimilProm; /* probabilidad de que el grupo destino sea
el que tiene menor similitud promedio */
real cruzaPasaGrupoProbAzar; /* probabilidad de que el grupo destino se elija por azar
*/

196 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

real cruzaPasaGrupoProbMejorDestino; /* probabilidad de el elemento que se saca del


grupo destino pase al grupo mas similar */
uent k; /* cantidad de grupos */
uent mutacionRefinarKMCantIter; /* cantidad de iteraciones de refinamiento en la
mutacion que refina */
real mutacionRefinarKMProb; /* probabilidad de que se aplique la mutacion que refina
*/
uent generacionInicialModo; /* forma de generar la poblacion inicial :
1 : al azar
2 : con la fase inicial
(lite) del kmeans
3 : fase inicial del
kmeans pero solo log k grupos
*/
real mutacionJoinProb; /* probabilidad de que se aplique la mutacion que junta 2
grupos */
real mutacionJoinProbMasSimilar; /* probabilidad de que el grupo destino sea el mas
similar */
real mutacionJoinProbMenorSimilProm; /* probabilidad de que el grupo origen sea el
que tiene menor similitud promedio */
real mutacionJoinProbMasChico; /* probabilidad de que el grupo origen sea el mas
chico */
real mutacionJoinProbAzar; /* probabilidad de que los grupos se elijan por azar */
real mutacionSplitProb; /* probabilidad de que se aplique la mutacion que separa 1
grupo */
real mutacionSplitProbMasGrande; /* probabilidad de que el grupo sea el que tiene más
elementos */
real mutacionSplitProbMenorSimilProm; /* probabilidad de que el grupo origen sea el
que tiene menor similitud promedio */
real mutacionSplitProbAzar; /* probabilidad de que los grupos se elijan por azar */
uent mutacionSplitCantMuestras; /* cantidad de muestras a tomar para buscar los
elementos mas distantes del grupo */
real mutacionRefinarSelectivoProb; /* probabilidad de que se aplique la mutacion de
refinacion selectiva */
} tRegConfigGenetico;

typedef struct _t_Cromosoma {


c_Agrupamiento *agrup;
real fitness;
bool disponible;
ent ultimoJoin; //indice del ultimo grupo en el cual se hizo un join (o -1)
} tCromosoma;

class c_Genetico {
private:
uent AsignarFormaElegirGrupoDestino();
uent AsignarFormaElegirGrupoSplit();
tCromosoma **poblacion;
real FitnessDeCromosoma(tCromosoma &cromosoma);
uent privCruzaPasaGrupo(tCromosoma *padre1, tCromosoma *padre2,
tCromosoma **hijo1, c_VecArchivo *vVecArchivos[]);
void ActualizarParametros(uent genActual,uent genLimite);
FILE *DebugFP();
public:
uent ElegirPorTorneo(uent &indElegido, bool invertido);
tRegConfigGenetico RegConfig;
c_Genetico();
~c_Genetico();

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 197


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent GenerarPoblacionInicial(uent cantElemAAgrupar, c_VecArchivo


*vVecArchivos[]);
uent Evolucionar(c_VecArchivo *vVecArchivos[],bool generacionesFijas, uent
&cantGeneraciones);
uent DevolverMejorSolucion(c_Agrupamiento **solucion);
uent CruzaPasaGrupo(tCromosoma *padre1, tCromosoma *padre2,
tCromosoma **hijo1, tCromosoma **hijo2, c_VecArchivo *vVecArchivos[]);
uent OperadorCruza(c_VecArchivo *vVecArchivos[]);
uent UbicarEnPoblacion(tCromosoma *hijo1, tCromosoma *hijo2);
uent MutacionRefinarKM(tCromosoma *cromosoma, c_VecArchivo
*vVecArchivos[]);
uent MutacionJoin(tCromosoma *cromosoma, c_VecArchivo *vVecArchivos[]);
uent MutacionSplit(tCromosoma *cromosoma, c_VecArchivo *vVecArchivos[]);
uent MutacionRefinarSelectivo(tCromosoma *cromosoma, c_VecArchivo
*vVecArchivos[]);
};

#endif

198 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.12 ClsGenetico.cpp

#include "clsGenetico.h"

c_Genetico::c_Genetico()
/* constructor */
{
/* seteos por defecto */
RegConfig.generacionesMaximo = 200;
RegConfig.k = 5; /* por defecto k=5 */
RegConfig.generacionInicialModo = 3;
RegConfig.fitnessCriterio = 1;
RegConfig.poblacionTamanio = 12;
RegConfig.poblacionTamanioDeseado = RegConfig.poblacionTamanio;
RegConfig.torneoTamanio = 2;
RegConfig.torneoProbMejor = (real)0.7;
RegConfig.cruzaOperador = 1;
RegConfig.cruzaPasaGrupoProbMejor = (real)0.7;
RegConfig.cruzaPasaGrupoProbMejorDestino = (real)0.95;
/* las siguientes 4 probabilidades deben sumar 1 */
RegConfig.cruzaPasaGrupoProbMasElemComun = (real)0.4;
RegConfig.cruzaPasaGrupoProbMasSimilar = (real)0.56;
RegConfig.cruzaPasaGrupoProbMenorSimilProm = (real)0.02;
RegConfig.cruzaPasaGrupoProbAzar = (real)0.02;
/* */
RegConfig.mutacionRefinarKMCantIter = 1;
RegConfig.mutacionRefinarKMProb = (real)0.3;
RegConfig.fpSalidaDebug = NULL;
RegConfig.mutacionJoinProb = (real)0.1;
/* las siguientes 3 probabilidades deben sumar 1 */
RegConfig.mutacionJoinProbAzar = (real)0.00;
RegConfig.mutacionJoinProbMenorSimilProm = (real)0.30;
RegConfig.mutacionJoinProbMasChico = (real)0.70;
/* */
RegConfig.mutacionJoinProbMasSimilar = (real)0.95;
RegConfig.mutacionSplitProb = (real)0.1;
/* las siguientes 3 probabilidades deben sumar 1 */
RegConfig.mutacionSplitProbAzar = (real)0.05;
RegConfig.mutacionSplitProbMasGrande = (real)0.9;
RegConfig.mutacionSplitProbMenorSimilProm = (real)0.05;
RegConfig.mutacionSplitCantMuestras = 6;
/* */
RegConfig.mutacionRefinarSelectivoProb = (real)0.0;
}

void c_Genetico::ActualizarParametros(uent genActual,uent genLimite)


/* actualiza los parámetros de RegConfig de acuerdo a la fase del
algoritmo en que nos encontramos
genActual es el número de generacion actual
genLimite es el límite de generaciones
*/
{
real pctCompleto;

pctCompleto = (real)((real)genActual / (real)genLimite);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 199


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/*
RegConfig.torneoProbMejor = (real)(0.6 + (0.2 * pctCompleto));
RegConfig.cruzaPasaGrupoProbMejor = (real)(0.60 + (0.3 * pctCompleto));
RegConfig.mutacionRefinarKMProb = (real)(0.4 - (0.35 * sin((PI/2)*pctCompleto)));
*/
if (pctCompleto == 0.0) {
RegConfig.poblacionTamanioDeseado =
RegConfig.poblacionTamanioDeseado;
}
if (pctCompleto < 0.2) /* 0 a 20% */ {
RegConfig.torneoProbMejor = (real)(0.75);
RegConfig.cruzaPasaGrupoProbMejor = (real)(0.8);
RegConfig.mutacionRefinarKMProb = (real)(0.1);
RegConfig.mutacionJoinProb = (real)0.1;
RegConfig.mutacionSplitProb = (real)0.1;
RegConfig.torneoTamanio = 2;
} else if (pctCompleto < 0.4) /* 20 a 40% */ {
RegConfig.torneoProbMejor = (real)(0.75);
RegConfig.cruzaPasaGrupoProbMejor = (real)(0.8);
RegConfig.mutacionRefinarKMProb = (real)(0.1);
RegConfig.mutacionJoinProb = (real)0.1;
RegConfig.mutacionSplitProb = (real)0.1;
RegConfig.torneoTamanio = 3;
} else if (pctCompleto < 0.8) /* 40 a 80% */ {
RegConfig.poblacionTamanioDeseado = 10;
RegConfig.torneoProbMejor = (real)(0.8);
RegConfig.cruzaPasaGrupoProbMejor = (real)(0.8);
RegConfig.mutacionRefinarKMProb = (real)(0.1);
RegConfig.mutacionJoinProb = (real)0.15;
RegConfig.mutacionSplitProb = (real)0.1;
RegConfig.torneoTamanio = 3;
RegConfig.mutacionRefinarSelectivoProb = (real)0.1;
} else if (pctCompleto < 0.9) /* 80 a 90% */ {
RegConfig.torneoProbMejor = (real)(0.85);
RegConfig.cruzaPasaGrupoProbMejor = (real)(0.9);
RegConfig.mutacionRefinarKMProb = (real)(0.25);
RegConfig.torneoTamanio = 3;
RegConfig.mutacionJoinProb = (real)0.05;
RegConfig.mutacionSplitProb = (real)0.05;
RegConfig.mutacionRefinarSelectivoProb = (real)0.3;
} else /* 90 a 100% */ {
RegConfig.mutacionRefinarSelectivoProb = (real)0.0;
}
}

FILE* c_Genetico::DebugFP()
{
return (RegConfig.fpSalidaDebug ? RegConfig.fpSalidaDebug : stdout);
}

c_Genetico::~c_Genetico()
/* destructor */
{
uent i;
for (i=0; i < RegConfig.poblacionTamanio; i++)
{
if (poblacion[i] != NULL)
{

200 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (poblacion[i]->agrup != NULL)
{
delete (poblacion[i]->agrup);
}
free((void*)poblacion[i]);
}
}
free((void*)poblacion);
}

real c_Genetico::FitnessDeCromosoma(tCromosoma &cromosoma)


/* calcula el fitness del cromosoma "cromosoma" */
{
c_Agrupamiento *agrup;
uent iGrupos, cantGrupos, cantElemGrupo;
real simSuma, normaCent, penalizacion;
c_VecArchivo *vecCent;

switch (RegConfig.fitnessCriterio)
{
case 1:
/* este criterio evalua el promedio de similitudes entre
los elementos de cada grupo */
simSuma = (real)0.0;

/* tomamos el agrupamiento del cromosoma */


agrup = cromosoma.agrup;
cantGrupos = agrup->cantGrupos;
/* vamos recorriendo los grupos */
for (iGrupos = 0; iGrupos < cantGrupos; iGrupos++)
{
/* tomamos el centroide del grupo y la cantidad de elementos */
vecCent = agrup->vecGrupos[iGrupos].vecCentroide;
cantElemGrupo = agrup->vecGrupos[iGrupos].cantElementos;
/* calculamos la norma del centroide al cuadrado */
normaCent = vecCent->CalcularNorma(true);
normaCent *= normaCent;
/* sumamos la norma multiplicada por la cantidad de elementos del
grupo */
simSuma += (real)(cantElemGrupo * normaCent);
}
/* penalizamos a los que se apartan de k grupos */
//penalizacion = (real)abs(RegConfig.k - agrup->cantGrupos)/(real)RegConfig.k;
//penalizacion = (real)1.0 - penalizacion;
penalizacion = (real)1.0;
/* el criterio a devolver es la suma dividida la cantidad total de elementos */
return ((simSuma / agrup->cantElementos) * penalizacion);
break;
case 2:
/* este criterio evalua el promedio de la norma de los centroides */
simSuma = (real)0.0;
/* tomamos el agrupamiento del cromosoma */
agrup = cromosoma.agrup;
cantGrupos = agrup->cantGrupos;
/* vamos recorriendo los grupos */
for (iGrupos = 0; iGrupos < cantGrupos; iGrupos++)
{
/* tomamos el centroide del grupo */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 201


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

vecCent = agrup->vecGrupos[iGrupos].vecCentroide;
/* calculamos la norma del centroide al cuadrado */
normaCent = vecCent->CalcularNorma(true);
normaCent *= normaCent;
/* sumamos la norma */
simSuma += (real)(normaCent);
}
/* el criterio a devolver es la suma dividida la cantidad total de grupos */
return ((simSuma / cantGrupos));
break;
default: /* criterio desconocido ... */
return((real)0.0);
break;
}

uent c_Genetico::GenerarPoblacionInicial(uent cantElemAAgrupar, c_VecArchivo


*vVecArchivos[])
/* inicializa la poblacion del algoritmo genetico
eso incluye alocar memoria para los cromosomas,
agrupar al azar los elementos en el agrupamiento de cada
cromosoma, calcular los centroides para el agrupamiento de
cada cromosoma y calcular el fitness de cada cromosoma */
{
uent i, j, codRet;
uent *vecIndGruposAux;

/* inicializamos el vector de grupos auxiliar (lo necesita


la funcion que calcula los centroides */
vecIndGruposAux = (uent*)malloc(RegConfig.k * SINT);
if (vecIndGruposAux == NULL)
return ERROR_MEMORIA;

/* creamos el vector de punteros a cromosomas */


poblacion = (tCromosoma**)malloc(RegConfig.poblacionTamanio *
sizeof(tCromosoma*));
if (poblacion == NULL)
return ERROR_MEMORIA;
/* inicializamos cada puntero a cromosoma */
for (i = 0; i < RegConfig.poblacionTamanio; i++)
{
/* creamos un cromosoma */
poblacion[i] = (tCromosoma*)malloc(sizeof(tCromosoma));
if (poblacion[i] == NULL)
return ERROR_MEMORIA;
/* creamos el agrupamiento del cromosoma */
poblacion[i]->agrup = new c_Agrupamiento;
if (poblacion[i]->agrup == NULL)
return ERROR_MEMORIA;
/* inicializamos el agrupamiento */
codRet = poblacion[i]->agrup->Inicializar(cantElemAAgrupar);
if (codRet != OK)
return codRet;

switch (RegConfig.generacionInicialModo)
{

202 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

case 1:
/* lo agrupamos al azar */
codRet = poblacion[i]->agrup-
>AgruparAlAzar(RegConfig.k,RegConfig.k);
if (codRet != OK)
return codRet;
break;
case 2:
/* lo inicializamos con la fase inicial (lite) del kmeans */
codRet = poblacion[i]->agrup->AgruparAlAzar(1,1);
if (codRet != OK)
return codRet;
c_KMeans::k = RegConfig.k;
codRet = c_KMeans::FaseInicialLite(*(poblacion[i]-
>agrup),1,vVecArchivos,vecIndGruposAux,false,0);
if (codRet != OK)
return codRet;
break;
case 3:
/* fase inicial, pero solamente log k grupos */
codRet = poblacion[i]->agrup->AgruparAlAzar(1,1);
if (codRet != OK)
return codRet;
c_KMeans::k = (uent)(log(RegConfig.k)/log(2));
codRet = c_KMeans::FaseInicial(*(poblacion[i]-
>agrup),1,vVecArchivos,vecIndGruposAux,false,0);
if (codRet != OK)
return codRet;
break;
}
/* calculamos los centroides */
for (j=0; j<RegConfig.k; j++)
vecIndGruposAux[j] = j;
codRet = c_KMeans::CalcularCentroides(*(poblacion[i]-
>agrup),vVecArchivos,RegConfig.k,vecIndGruposAux);
if (codRet != OK)
return codRet;
/* le asociamos el fitness */
poblacion[i]->fitness = FitnessDeCromosoma(*(poblacion[i]));
/* esta disponible para ser seleccionado */
poblacion[i]->disponible = true;
/* no hubo un join */
poblacion[i]->ultimoJoin = -1;
fprintf(DebugFP(),"GenInic : %d; Fitness : %f \n",i,poblacion[i]->fitness);
}

free((void*)vecIndGruposAux);

return OK;
}

uent c_Genetico::DevolverMejorSolucion(c_Agrupamiento **solucion)


/* devuelve un puntero al agrupamiento del cromosoma
que tiene fitness mas alto */
{
uent iPob, iMax;
real fitMax;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 203


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

iMax = 0;
fitMax = (real)-1.0;

for (iPob = 0; iPob < RegConfig.poblacionTamanio; iPob++)


{
if (poblacion[iPob]->fitness > fitMax)
{
fitMax = poblacion[iPob]->fitness;
iMax = iPob;
}
}

*solucion = poblacion[iMax]->agrup;

return OK;
}

uent c_Genetico::ElegirPorTorneo(uent &indElegido, bool invertido)


/* elige un cromosoma mediante el método del torneo
los parametros son las variables de configuracion:
- torneoTamanio : cantidad de cromosomas que se examinan
- torneoProbMejor : probabilidad de que se seleccione al mejor
si "invertido" es true, se busca al reves (intentando elegir al
peor), esto se usa para elegir a quien se reemplaza
en "indElegido", devuelve el numero del cromosoma seleccionado
*/
{
uent *elemAzar;
uent *ordenTorneo;
uent iElemTorneo,iElem,j;
bool bSalir;

if (invertido == false)
fprintf(DebugFP(),"Torneo : ");
else
fprintf(DebugFP(),"Torneo invertido : ");

/* "ordenTorneo" es un vector de tamaño "torneoTamanio" */


ordenTorneo = (uent*)malloc(RegConfig.torneoTamanio * SINT);

/* en "elemAzar" generamos un vector de numeros de cromosoma


ordenados al azar. Lo hacemos un poco mas grande que el
tamaño del torneo por las dudas de que alguno esté marcado
como no disponible */
elemAzar = kNumerosRandom(RegConfig.torneoTamanio +
3,0,RegConfig.poblacionTamanio - 1,false);
if (elemAzar == NULL)
return ERROR_MEMORIA;

/* iElem avanza mas rapido que iElemTorneo cuando hay cromosomas no disponibles
*/
iElem = 0;
for (iElemTorneo=0;iElemTorneo<RegConfig.torneoTamanio;iElemTorneo++)
{
/* iElem saltea los cromosomas no disponibles */
while(poblacion[elemAzar[iElem]]->disponible == false)
iElem++;

204 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

fprintf(DebugFP(),"(%d) %f ; ",elemAzar[iElem],poblacion[elemAzar[iElem]]-
>fitness);
/* ahora veamos en que posicion del vector "ordenTorneo" tiene que ir */
/* empezamos a evaluar por el ultimo del vector (el de mas fitness) */
j = iElemTorneo;
while (j > 0)
{
/* veamos si el que acabamos de elegir tiene mas fitness */
if (poblacion[elemAzar[iElem]]->fitness < poblacion[ordenTorneo[j-1]]-
>fitness)
{
/* movemos el elemento del vector hacia arriba */
ordenTorneo[j] = ordenTorneo[j-1];
}
else
{
break; /* salimos del while */
}
j--;
}
/* el elemento va en la posicion j */
ordenTorneo[j] = elemAzar[iElem];
iElem++;
}
fprintf(DebugFP()," --> ");
/* ya tenemos los elementos en el vector "ordenTorneo" ordenados
por fitness (primero el de menor fitness) */
/* ahora elegimos al elemento con la probabilidad que corresponde */
bSalir = false;
j = 0;
while ((j < RegConfig.torneoTamanio) && (bSalir == false))
{
if (TirarMonedaCargada(RegConfig.torneoProbMejor))
{
bSalir = true;
}
else
{
fprintf(DebugFP()," salteo - ");
j++;
}
}
if (bSalir == false) /* j se pasó 1 */
j--;
/* de acuerdo al valor de "invertido" devolvemos el que corresponde */
if (invertido == true)
indElegido = ordenTorneo[j];
else
indElegido = ordenTorneo[RegConfig.torneoTamanio - 1 - j];

fprintf(DebugFP(),"[%f]\n",poblacion[indElegido]->fitness);

free((void*)elemAzar);
free((void*)ordenTorneo);

return (0);
}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 205


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent c_Genetico::CruzaPasaGrupo(tCromosoma *padre1, tCromosoma *padre2, tCromosoma


**hijo1, tCromosoma **hijo2, c_VecArchivo *vVecArchivos[])
/* Operador de cruza. Recibe punteros a los 2 padres.
Crea 2 cromosomas nuevos (que devuelve en los 2 punteros a los hijos)
Para generar el hijo 1 hace lo siguiente :
- crea el agrupamiento para el hijo 1 igual al del padre 2
- busca en el padre 1 un grupo para pasar al hijo. Con cierta probabilidad
el grupo a pasar es el que tiene mejor promedio de similitud entre sus
elementos
- busca en el hijo 1 (que por ahora es igual al padre 2), el grupo que
tenga mas elementos en comun con el grupo que eligio para pasarle
- saca de ese grupo los elementos que no estan en el grupo que le va
a pasar, y agrega a ese grupo los elementos que le faltan
- si algun grupo del hijo se queda sin elementos, lo borra
Para generar el hijo 2 es el mismo procedimiento pero tomando los padres
al revés
*/
{
uent codRet;

/* generamos el hijo 1 */
fprintf(DebugFP(),"Cruza PasaGrup 1 : fitness padre1(%d) = %f ; fitness padre2(%d) =
%f\n",padre1->agrup->cantGrupos,padre1->fitness,padre2->agrup->cantGrupos,padre2-
>fitness);
codRet = privCruzaPasaGrupo(padre1,padre2,hijo1,vVecArchivos);
if (codRet != OK)
return codRet;
/* generamos el hijo 2 */
fprintf(DebugFP(),"Cruza PasaGrup 2 : fitness padre1 = %f ; fitness padre2 =
%f\n",padre2->fitness,padre1->fitness);
codRet = privCruzaPasaGrupo(padre2,padre1,hijo2,vVecArchivos);
return codRet;
return OK;
}

uent c_Genetico::AsignarFormaElegirGrupoDestino()
/* calcula la forma de elegir el grupo destino de acuerdo a las probabilidades
(usado por el operador de cruza)
Devuelve : 1 = Mas elementos en comun
2 = Mas similar
3 = Menor similitud promedio
4 = Al Azar
*/
{
real totalProbRestante;

totalProbRestante = (real)1.0;
if (TirarMonedaCargada(RegConfig.cruzaPasaGrupoProbMasElemComun * (real)(1.0 /
totalProbRestante)))
{
return 1;
}
totalProbRestante -= RegConfig.cruzaPasaGrupoProbMasElemComun;
if (TirarMonedaCargada(RegConfig.cruzaPasaGrupoProbMasSimilar * (real)(1.0 /
totalProbRestante)))
{
return 2;

206 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

}
totalProbRestante -= RegConfig.cruzaPasaGrupoProbMasSimilar;
if (TirarMonedaCargada(RegConfig.cruzaPasaGrupoProbMenorSimilProm * (real)(1.0 /
totalProbRestante)))
{
return 3;
}
/* si llegamos hasta aca, es al azar */
return 4;
}

uent c_Genetico::privCruzaPasaGrupo(tCromosoma *padre1, tCromosoma *padre2,


tCromosoma **hijo1, c_VecArchivo *vVecArchivos[])
/* implementa el operador de cruza "CruzaPasaGrupo", para generar uno de
los dos hijos.
Para generar el otro, se deben pasar los padres en orden inverso */
{
uent codRet;
c_Agrupamiento *agrupHijo, *agrupPadre;
uent indGrupoPasar, indGrupoDestino, i, nroGrupoPasar, nroGrupoDestino;
uent nroGrupoElemHijo, maxElemComun, cantGruposHijo, indGrupoAux;
real maxSimProm, simProm, maxSimPromDest;
uent *vecNroElemComun, j;
real valorActual, valorAlternativa;
uent formaElegirGrupoDestino, h;
c_VecArchivo *vecCent1,*vecCent2;
real vMaxSimProm[3]; /* para buscar los 2 grupos mas similares en el segundo padre
*/
uent vIndGrupoDestino[3], vNroGrupoDestino[3];

/* creamos el cromosoma */
*hijo1 = (tCromosoma*)malloc(sizeof(tCromosoma));
if (*hijo1 == NULL)
return ERROR_MEMORIA;
/* creamos el agrupamiento del cromosoma */
(*hijo1)->agrup = new c_Agrupamiento();
if ((*hijo1)->agrup == NULL)
return ERROR_MEMORIA;
agrupHijo = (*hijo1)->agrup;
/* hacemos el agrupamiento del hijo igual al del padre 2 */
codRet = agrupHijo->Duplicar(*(padre2->agrup));
if (codRet != OK)
return codRet;
/* le tenemos que pasar un grupo del padre 1 */
agrupPadre = padre1->agrup;
/* veamos si tenemos que pasar el mejor grupo */
if (TirarMonedaCargada(RegConfig.cruzaPasaGrupoProbMejor))
{
/* buscamos el grupo del padre con mejor similitud promedio */
maxSimProm = (real)-1.0;
for (i=0; i < agrupPadre->cantGrupos; i++)
{
simProm = agrupPadre->vecGrupos[i].vecCentroide-
>CalcularNorma(false);
if (simProm > maxSimProm)
{
indGrupoPasar = i;
maxSimProm = simProm;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 207


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

}
}
}
else
{
/* el grupo a pasar se elige al azar */
indGrupoPasar = RANDOM(agrupPadre->cantGrupos);
maxSimProm = 0;
}
nroGrupoPasar = agrupPadre->vecGrupos[indGrupoPasar].nroGrupo;

/* buscamos los 2 grupos mas similares del otro padre */


for (i=0; i < 2; i++)
{
vMaxSimProm[i] = (real)-1.0;
vIndGrupoDestino[i] = 0;
}
vecCent1 = agrupPadre->vecGrupos[indGrupoPasar].vecCentroide;
for (i=0; i < agrupHijo->cantGrupos; i++)
{
vecCent2 = agrupHijo->vecGrupos[i].vecCentroide;
simProm = vecCent1->Multiplicar(*vecCent2,false);
j=0;
while ((j<2) && (simProm > vMaxSimProm[j]))
{
vMaxSimProm[j] = vMaxSimProm[j+1];
vIndGrupoDestino[j] = vIndGrupoDestino[j+1];
j++;
}
if (j > 0) /* entra en el vector, en la posicion j-1 */
{
vMaxSimProm[j-1] = simProm;
vIndGrupoDestino[j-1] = i;
}
}
for (i=0; i<2; i++)
{
vNroGrupoDestino[i] = agrupHijo->vecGrupos[vIndGrupoDestino[i]].nroGrupo;
}

/* ahora elegimos el grupo destino */


formaElegirGrupoDestino = AsignarFormaElegirGrupoDestino();
switch (formaElegirGrupoDestino)
{
case 1: /* mas elementos en comun */
/* creamos un vector para contar los elementos en comun de cada grupo */
vecNroElemComun = (uent*)malloc(agrupHijo->cantGrupos * SINT);
if (vecNroElemComun == NULL)
return ERROR_MEMORIA;
for (i=0; i < agrupHijo->cantGrupos; i++)
{
vecNroElemComun[i] = 0;
}
/* buscamos en el hijo el grupo con mas elementos en comun */
for (i=0; i < agrupPadre->cantElementos; i++)
{
/* si el elemento es del grupo a pasar */
if (agrupPadre->vecElementos[i] == nroGrupoPasar)

208 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
/* sumamos uno al grupo del hijo que tiene ese elemento */
nroGrupoElemHijo = agrupHijo->vecElementos[i];
vecNroElemComun[agrupHijo-
>IndiceDeGrupo(nroGrupoElemHijo,false)]++;
}
}
/* buscamos la mayor entrada en el vector */
maxElemComun = 0;
for (i=0; i < agrupHijo->cantGrupos; i++)
{
if (vecNroElemComun[i] > maxElemComun)
{
maxElemComun = vecNroElemComun[i];
indGrupoDestino = i;
}
}
free((void*)vecNroElemComun);
maxSimPromDest = (real)maxElemComun;
break;
case 2: /* mas similar */
maxSimPromDest = vMaxSimProm[1];
indGrupoDestino = vIndGrupoDestino[1];
break;
case 3: /* menor similitud promedio */
maxSimPromDest = (real)-10000.0;
for (i=0; i < agrupHijo->cantGrupos; i++)
{
vecCent2 = agrupHijo->vecGrupos[i].vecCentroide;
simProm = (real)-1.0 * vecCent2->CalcularNorma(false);
if (simProm > maxSimPromDest)
{
maxSimPromDest = simProm;
indGrupoDestino = i;
}
}
break;
case 4: /* al azar */
maxSimPromDest = (real)0.0;
indGrupoDestino = RANDOM(agrupHijo->cantGrupos);
break;
}
nroGrupoDestino = agrupHijo->vecGrupos[indGrupoDestino].nroGrupo;

fprintf(DebugFP()," Grupos : fuente=(%d) [%d] %f, destino=(%d) [%d] Sim :


%f\n",nroGrupoPasar,agrupPadre-
>vecGrupos[indGrupoPasar].cantElementos,maxSimProm,nroGrupoDestino,agrupHijo-
>vecGrupos[indGrupoDestino].cantElementos,maxSimPromDest);

/* ahora reacomodamos los elementos para que el grupo pase al hijo */


for (i=0; i < agrupPadre->cantElementos; i++)
{
if (agrupPadre->vecElementos[i] == nroGrupoPasar)
{
/* si en el hijo el elemento no está en el grupo destino, hay que
agregarlo */
if (agrupHijo->vecElementos[i] != nroGrupoDestino)
{

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 209


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* guardamos la cantidad actual de grupos del hijo para saber si


cambia */
cantGruposHijo = agrupHijo->cantGrupos;
/* pasamos el elemento al grupo destino */
indGrupoAux = agrupHijo->IndiceDeGrupo(agrupHijo-
>vecElementos[i],false);
codRet =
c_KMeans::MoverElementoyRecalcular(*agrupHijo,vVecArchivos,i,indGrupoAux,indGrupoDesti
no,true);
if (codRet != OK)
return codRet;
/* veamos si cambio la cantidad de grupos */
if (cantGruposHijo != agrupHijo->cantGrupos)
{
/* tomamos el nuevo indice del grupo */
indGrupoDestino = agrupHijo-
>IndiceDeGrupo(nroGrupoDestino,true);
for (h=0; h<2; h++)
vIndGrupoDestino[h] = agrupHijo-
>IndiceDeGrupo(vNroGrupoDestino[h],true);
}
}
}
else
{
/* si en el hijo el elemento está en el grupo destino, hay que sacarlo */
if (agrupHijo->vecElementos[i] == nroGrupoDestino)
{
/* veamos si tenemos que buscar el mejor grupo */
if
(TirarMonedaCargada(RegConfig.cruzaPasaGrupoProbMejorDestino))
{
/* hay que buscar el mejor grupo (solo entre los 2 mas
similares) */
valorActual =
c_KMeans::ValorCriterioActual(*agrupHijo,vVecArchivos,i,indGrupoDestino);
indGrupoAux = indGrupoDestino;
for (h=0; h < 2; h++)
{
j = vIndGrupoDestino[h];
if (j != indGrupoDestino) /* no evaluamos 2
veces el mismo */
{
valorAlternativa =
c_KMeans::ValorCriterioAlternativa(*agrupHijo,vVecArchivos,i,j,valorActual);
if (valorAlternativa > valorActual)
{
valorActual = valorAlternativa;
indGrupoAux = j;
}
}
}
}
else
{
indGrupoAux = RANDOM(agrupHijo->cantGrupos);

210 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* lo pasamos al otro grupo */


if (indGrupoAux != indGrupoDestino)
{
cantGruposHijo = agrupHijo->cantGrupos; /* para ver si
cambia la cantidad de grupos */
codRet =
c_KMeans::MoverElementoyRecalcular(*agrupHijo,vVecArchivos,i,indGrupoDestino,indGrupoA
ux,true);
if (codRet != OK)
return (codRet);
if (cantGruposHijo != agrupHijo->cantGrupos)
{ /* buscamos los nuevos indices */
indGrupoDestino = agrupHijo-
>IndiceDeGrupo(nroGrupoDestino,true);
for (h=0; h<2; h++)
vIndGrupoDestino[h] = agrupHijo-
>IndiceDeGrupo(vNroGrupoDestino[h],true);
}
}
}
}
}

return OK;
}

uent c_Genetico::OperadorCruza(c_VecArchivo *vVecArchivos[])


/* elige 2 cromosomas mediante el metodo del torneo
los cruza generando 2 hijos
elige 2 cromosomas mediante el metodo del torneo para ser reemplazados
los reemplaza por los 2 hijos generados
*/
{
tCromosoma *hijo1, *hijo2;
uent indPadre1, indPadre2;
uent codRet;

/* elegimos los padres */


codRet = ElegirPorTorneo(indPadre1,false);
if (codRet != OK)
return (codRet);
poblacion[indPadre1]->disponible = false; /* lo marcamos para no elegirlo de nuevo */
codRet = ElegirPorTorneo(indPadre2,false);
if (codRet != OK)
return (codRet);
/* desmarcamos el padre 1 */
poblacion[indPadre1]->disponible = true;

if (RegConfig.cruzaOperador == 1)
{
codRet =
CruzaPasaGrupo(poblacion[indPadre1],poblacion[indPadre2],&hijo1,&hijo2,vVecArchivos);
if (codRet != OK)
return (codRet);
}
else
{
/* ... no definido aun */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 211


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

hijo1->ultimoJoin = -1;
hijo2->ultimoJoin = -1;

/* ahora calculamos el fitness del hijo 1 */


hijo1->fitness = FitnessDeCromosoma(*hijo1);
/* ahora calculamos el fitness del hijo 2 */
hijo2->fitness = FitnessDeCromosoma(*hijo2);

fprintf(DebugFP(),"Hijo 1 = %f ; Hijo 2 = %f\n",hijo1->fitness,hijo2->fitness);

/* veamos si tenemos que mutar (operador split) al hijo 1 */


if ((hijo1->agrup->cantGrupos < RegConfig.k) ||
(TirarMonedaCargada(RegConfig.mutacionSplitProb)))
{
fprintf(DebugFP(),"MutarSplit 1 : ");
codRet = MutacionSplit(hijo1,vVecArchivos);
if (codRet != OK)
return (codRet);
}
/* veamos si tenemos que mutar (operador split) al hijo 2 */
if ((hijo2->agrup->cantGrupos < RegConfig.k) ||
(TirarMonedaCargada(RegConfig.mutacionSplitProb)))
{
fprintf(DebugFP(),"MutarSplit 2 : ");
codRet = MutacionSplit(hijo2,vVecArchivos);
if (codRet != OK)
return (codRet);
}

/* veamos si tenemos que mutar (operador join) al hijo 1 */


if ((hijo1->agrup->cantGrupos > RegConfig.k) ||
(TirarMonedaCargada(RegConfig.mutacionJoinProb)))
{
fprintf(DebugFP(),"MutarJoin 1 : ");
codRet = MutacionJoin(hijo1,vVecArchivos);
if (codRet != OK)
return (codRet);
}
/* veamos si tenemos que mutar (operador join) al hijo 2 */
if ((hijo2->agrup->cantGrupos > RegConfig.k) ||
(TirarMonedaCargada(RegConfig.mutacionJoinProb)))
{
fprintf(DebugFP(),"MutarJoin 2 : ");
codRet = MutacionJoin(hijo2,vVecArchivos);
if (codRet != OK)
return (codRet);
}

/* veamos si tenemos que mutar (operador refinar) al hijo 1 */


if (TirarMonedaCargada(RegConfig.mutacionRefinarKMProb))
{
fprintf(DebugFP(),"MutarRef 1 : ");
codRet = MutacionRefinarKM(hijo1,vVecArchivos);
if (codRet != OK)
return (codRet);
}

212 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

/* veamos si tenemos que mutar (operador refinar) al hijo 2 */


if (TirarMonedaCargada(RegConfig.mutacionRefinarKMProb))
{
fprintf(DebugFP(),"MutarRef 2 : ");
codRet = MutacionRefinarKM(hijo2,vVecArchivos);
if (codRet != OK)
return (codRet);
}
/* veamos si tenemos que mutar (operador refinar selectivo) al hijo 1 */
if (TirarMonedaCargada(RegConfig.mutacionRefinarSelectivoProb))
{
fprintf(DebugFP(),"MutarRefSelectivo 1 : ");
codRet = MutacionRefinarSelectivo(hijo1,vVecArchivos);
if (codRet != OK)
return (codRet);
}
/* veamos si tenemos que mutar (operador refinar) al hijo 2 */
if (TirarMonedaCargada(RegConfig.mutacionRefinarSelectivoProb))
{
fprintf(DebugFP(),"MutarRefSelectivo 2 : ");
codRet = MutacionRefinarSelectivo(hijo2,vVecArchivos);
if (codRet != OK)
return (codRet);
}

hijo1->ultimoJoin = -1;
hijo2->ultimoJoin = -1;

/* ahora calculamos el fitness del hijo 1 */


hijo1->fitness = FitnessDeCromosoma(*hijo1);
hijo1->disponible = true;
/* ahora calculamos el fitness del hijo 2 */
hijo2->fitness = FitnessDeCromosoma(*hijo2);
hijo2->disponible = true;

fprintf(DebugFP(),"Hijo 1 = %f ; Hijo 2 = %f\n",hijo1->fitness,hijo2->fitness);

/* los insertamos en la poblacion */


codRet = UbicarEnPoblacion(hijo1,hijo2);
if (codRet != OK)
return (codRet);

return OK;
}

uent c_Genetico::UbicarEnPoblacion(tCromosoma *hijo1, tCromosoma *hijo2)


/* Ubica los dos hijos en la poblacion */
{
uent codRet;
uent indReemp1, indReemp2;
uent i;
tCromosoma **pobAux;
tCromosoma *hijoAux;

/* seleccionamos 2 para ser reemplazados */


codRet = ElegirPorTorneo(indReemp1,true);
if (codRet != OK)
return (codRet);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 213


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

poblacion[indReemp1]->disponible = false; /* lo marcamos */


codRet = ElegirPorTorneo(indReemp2,true);
if (codRet != OK)
return (codRet);
poblacion[indReemp1]->disponible = true; /* desmarcamos al primero */

/* veamos si la poblacion tiene que crecer o disminuir */


if (RegConfig.poblacionTamanio < RegConfig.poblacionTamanioDeseado)
{
/* la poblacion tiene que crecer */
/* alocamos lugar para uno mas */
pobAux = (tCromosoma**)malloc((RegConfig.poblacionTamanio + 1) *
sizeof(tCromosoma*));
/* pasamos la poblacion al nuevo vector */
for (i=0; i < RegConfig.poblacionTamanio; i++)
pobAux[i] = poblacion[i];
/* el ultimo lo ponemos en null */
pobAux[RegConfig.poblacionTamanio] = NULL;
/* cambiamos los vectores */
free((void*)poblacion);
poblacion = pobAux;
RegConfig.poblacionTamanio++;
/* solamente vamos a reemplazar al peor de los 2 elegidos */
if (poblacion[indReemp1]->fitness < poblacion[indReemp2]->fitness)
indReemp2 = RegConfig.poblacionTamanio;
else
indReemp1 = RegConfig.poblacionTamanio;
}
else if (RegConfig.poblacionTamanio > RegConfig.poblacionTamanioDeseado)
{
/* la poblacion tiene que disminuir */
/* nos quedamos solamente con el mejor hijo */
/* ponemos el mejor hijo en hijo1 y el otro en hijo2 */
if (hijo1->fitness < hijo2->fitness)
{
hijoAux = hijo2;
hijo2 = hijo1;
hijo1 = hijoAux;
}
/* eliminamos el hijo2 */
if (hijo2->agrup != NULL)
delete(hijo2->agrup);
free((void*)hijo2);
hijo2 = NULL;
/* sacamos uno de los elegidos y disminuimos el tamaño de la poblacion */
if (indReemp1 > indReemp2)
{
i = indReemp1;
indReemp1 = indReemp2;
}
else
{
i = indReemp2;
indReemp2 = indReemp1;
}
if (poblacion[i]->agrup != NULL)
delete(poblacion[i]->agrup);
free((void*)poblacion[i]);

214 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

for (; i < (RegConfig.poblacionTamanio - 1); i++)


poblacion[i] = poblacion[i+1];
RegConfig.poblacionTamanio--;
}
/* los reemplazamos */
if (poblacion[indReemp1] != NULL)
{
delete (poblacion[indReemp1]->agrup);
free((void*)poblacion[indReemp1]);
poblacion[indReemp1] = NULL;
}
if (poblacion[indReemp2] != NULL)
{
delete (poblacion[indReemp2]->agrup);
free((void*)poblacion[indReemp2]);
poblacion[indReemp2] = NULL;
}

if (hijo1 != NULL)
poblacion[indReemp1] = hijo1;
if (hijo2 != NULL)
poblacion[indReemp2] = hijo2;

return OK;
}

uent c_Genetico::Evolucionar(c_VecArchivo *vVecArchivos[],bool generacionesFijas, uent


&cantGeneraciones)
/* Implementa el ciclo de evolucion del algoritmo genetico
Antes de llamarse a esta funcion debe llamarse a "GenerarPoblacionInicial"
Despues de esta funcion, puede llamarse a "DevolverMejorSolucion"
*/
{
uent codRet, iGeneraciones, limiteGeneraciones;

if (generacionesFijas == true)
limiteGeneraciones = cantGeneraciones;
else
limiteGeneraciones = RegConfig.generacionesMaximo;

iGeneraciones = 0;
while (iGeneraciones < limiteGeneraciones)
{
//xxxdebug
printf("Gcion : %d\n",iGeneraciones);
fprintf(DebugFP(),"Gcion : %d\n",iGeneraciones);

ActualizarParametros(iGeneraciones,limiteGeneraciones);

codRet = OperadorCruza(vVecArchivos);
if (codRet != OK)
return (codRet);

iGeneraciones++;
}

cantGeneraciones = iGeneraciones;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 215


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

return OK;
}

uent c_Genetico::MutacionRefinarKM(tCromosoma *cromosoma, c_VecArchivo


*vVecArchivos[])
/* operador de mutacion que consiste en realizar una iteracion de
la refinacion KMeans sobre el agrupamiento del cromosoma */
{
uent codRet,i;
uent *indGrupos;
uent cantIteraciones, cantCambiosTotal = 0;

/* creamos un vector para poner los indices de los grupos */


indGrupos = (uent*)malloc(cromosoma->agrup->cantGrupos * SINT);
if (indGrupos == NULL)
return ERROR_MEMORIA;
for (i=0; i < cromosoma->agrup->cantGrupos; i++)
indGrupos[i] = i;

cantIteraciones = RegConfig.mutacionRefinarKMCantIter;
c_KMeans::k = cromosoma->agrup->cantGrupos;
codRet = c_KMeans::FaseRefinarLite(*(cromosoma-
>agrup),vVecArchivos,indGrupos,true,cantIteraciones,cantCambiosTotal);
if (codRet != OK)
return codRet;

fprintf(DebugFP()," %d\n",cantCambiosTotal);

free((void*)indGrupos);

return OK;
}

uent c_Genetico::MutacionRefinarSelectivo(tCromosoma *cromosoma, c_VecArchivo


*vVecArchivos[])
/* operador de mutacion que consiste en refinar solamente los
mejores grupos, con la esperanza de aislar los elementos "ruidosos"
en 1 o 2 grupos de baja similitud promedio */
{
uent i,j,h;
c_Agrupamiento *agrup;
uent *vecOrdenTamano, *vecOrdenSimilProm, *vecPuntaje;
real *vecSimilPromAux;
uent *vecPeores, *vecMejores;
uent cantMejores;
uent cantPeores;
real desvioSim, simProm, simDestino, simDestinoAux;
uent indGrupoOrigen, indGrupoDestino;
uent cantCambios;

real pctMejores = (real)0.25;


real pctPeores = (real)0.25;
real factorDesvioTolerado = (real)0.8;

agrup = cromosoma->agrup;

cantMejores = (int)(agrup->cantGrupos * pctMejores);

216 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

cantPeores = (int)(agrup->cantGrupos * pctPeores);

/* creamos los vectores que vamos a usar */


vecMejores = (uent*)malloc(cantMejores * sizeof(uent));
if (vecMejores == NULL)
return ERROR_MEMORIA;
vecPeores = (uent*)malloc(cantPeores * sizeof(uent));
if (vecPeores == NULL)
return ERROR_MEMORIA;
vecOrdenTamano = (uent*)malloc(agrup->cantGrupos * sizeof(uent));
if (vecOrdenTamano == NULL)
return ERROR_MEMORIA;
vecOrdenSimilProm = (uent*)malloc(agrup->cantGrupos * sizeof(uent));
if (vecOrdenSimilProm == NULL)
return ERROR_MEMORIA;
vecPuntaje = (uent*)malloc(agrup->cantGrupos * sizeof(uent));
if (vecPuntaje == NULL)
return ERROR_MEMORIA;
vecSimilPromAux = (real*)malloc(agrup->cantGrupos * sizeof(real));
if (vecSimilPromAux == NULL)
return ERROR_MEMORIA;

/* vamos a armar 2 vectores


en uno vamos a ordenar los grupos por tamaño (descendentemente)
en el otro, por similitud promedio (descendentemente) */
for (i=0; i<agrup->cantGrupos; i++)
{
/* calculamos la similitud promedio del grupo y lo ubicamos en el vector */
vecSimilPromAux[i] = agrup->vecGrupos[i].vecCentroide-
>CalcularNorma(false);
vecSimilPromAux[i] *= vecSimilPromAux[i]; // al cuadrado
//fprintf(DebugFP(),"Grupo : %d, Sim : %f, Tam :
%d\n",i,vecSimilPromAux[i],agrup->vecGrupos[i].cantElementos);
j = 0;
while ((j < i) && (vecSimilPromAux[i] <
vecSimilPromAux[vecOrdenSimilProm[j]]))
j++;
/* va en la posicion j, hay que correr al resto */
for (h = (agrup->cantGrupos - 1); h > j; h--)
vecOrdenSimilProm[h] = vecOrdenSimilProm[h-1];
vecOrdenSimilProm[j] = i;
/* ahora hacemos lo mismo pero con el tamaño del grupo */
j = 0;
while ((j < i) && (agrup->vecGrupos[i].cantElementos < agrup-
>vecGrupos[vecOrdenTamano[j]].cantElementos))
j++;
/* va en la posicion j, hay que correr al resto */
for (h = (agrup->cantGrupos - 1); h > j; h--)
vecOrdenTamano[h] = vecOrdenTamano[h-1];
vecOrdenTamano[j] = i;
}
/* ahora calculamos un puntaje para cada grupo
mayor el puntaje -> peor el grupo */
/* primero inicializamos el vector de puntajes en 0 */
for (i=0; i < agrup->cantGrupos; i++)
vecPuntaje[i] = 0;
for (i=0; i < agrup->cantGrupos; i++)
{

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 217


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

h = vecOrdenTamano[i];
if (vecPuntaje[h] == 0)
{
vecPuntaje[h] = i + 1;
}
else
{
if (vecPuntaje[h] < (i+1))
{
vecPuntaje[h] *= 2;
vecPuntaje[h] += i + 1;
}
else
{
vecPuntaje[h] += 2 * (i+1);
}
// fprintf(DebugFP(),"Grupo : %d, Puntaje : %d\n",h,vecPuntaje[h]);
}

h = vecOrdenSimilProm[i];
if (vecPuntaje[h] == 0)
{
vecPuntaje[h] = i + 1;
}
else
{
if (vecPuntaje[h] < (i+1))
{
vecPuntaje[h] *= 2;
vecPuntaje[h] += i + 1;
}
else
{
vecPuntaje[h] += 2 * (i+1);
}
// fprintf(DebugFP(),"Grupo : %d, Puntaje : %d\n",h,vecPuntaje[h]);
}
}

/* armamos los vectores de mejores y peores */


for (i=0; i<cantMejores; i++)
vecMejores[i] = agrup->cantGrupos;
for (i=0; i<cantPeores; i++)
vecPeores[i] = agrup->cantGrupos;

for (i=0; i < agrup->cantGrupos; i++)


{
/* veamos si este grupo entra en el vector de mejores */
j = 0;
while (j < cantMejores)
{
if (vecMejores[j] == agrup->cantGrupos)
j++;
else if (vecPuntaje[i] < vecPuntaje[vecMejores[j]])
j++;
else
break;
}

218 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (j > 0)
{
/* va en la posicion j - 1 */
/* hay que correr los demas */
j--;
for (h=0; h < j; h++)
vecMejores[h] = vecMejores[h+1];
vecMejores[j] = i;
}
/* ahora en el de peores */
j = 0;
while (j < cantPeores)
{
if (vecPeores[j] == agrup->cantGrupos)
j++;
else if (vecPuntaje[i] > vecPuntaje[vecPeores[j]])
j++;
else
break;
}
if (j > 0)
{
/* va en la posicion j - 1 */
/* hay que correr los demas */
j--;
for (h=0; h < j; h++)
vecPeores[h] = vecPeores[h+1];
vecPeores[j] = i;
}
}

/* ahora vamos a buscar en los mejores grupos los elementos


que tengan baja similitud con el centroide y los vamos a pasar
a los peores grupos */
cantCambios = 0;
for (i=0; i < agrup->cantElementos; i++)
{
if (c_KMeans::NroGrupoEstaEnVectorIndices(agrup-
>vecElementos[i],vecMejores,cantMejores,*agrup,indGrupoOrigen))
{
/* veamos si la similitud de este elemento con el centroide es peor que
el promedio */
simProm = agrup->vecGrupos[indGrupoOrigen].vecCentroide-
>Multiplicar(*(vVecArchivos[i+1]),false);
//fprintf(DebugFP(),"Elemento : %d, Grupo : %d, Sim :
%f\n",i,indGrupoOrigen,simProm);
if (simProm < vecSimilPromAux[indGrupoOrigen])
{
/* es menos similar que el promedio */
desvioSim = vecSimilPromAux[indGrupoOrigen] - simProm;
/* buscamos entre los peores grupos al mas similar */
simDestino = (real)0.0;
for (h=0; h < cantPeores; h++)
{
simDestinoAux = agrup-
>vecGrupos[vecPeores[h]].vecCentroide->Multiplicar(*(vVecArchivos[i+1]),false);
if (simDestinoAux > simDestino)
{

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 219


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

indGrupoDestino = vecPeores[h];
simDestino = simDestinoAux;
}
}
/* veamos si la mejor similitud esta dentro de lo tolerado */
//fprintf(DebugFP()," Mejor Sim Alternativa : %f, Grupo :
%d, Desvio : %f\n",simDestino,indGrupoDestino,desvioSim);
if (simDestino > (simProm - (desvioSim *
factorDesvioTolerado)))
{
cantCambios++;

c_KMeans::MoverElementoyRecalcular(*agrup,vVecArchivos,i,indGrupoOrigen,indGrup
oDestino,true);
}
}
}
}

fprintf(DebugFP()," %d\n",cantCambios);

free((void*)vecMejores);
free((void*)vecPeores);
free((void*)vecOrdenSimilProm);
free((void*)vecOrdenTamano);
free((void*)vecPuntaje);
free((void*)vecSimilPromAux);

return OK;
}

uent c_Genetico::MutacionJoin(tCromosoma *cromosoma, c_VecArchivo *vVecArchivos[])


/* operador de mutacion que consiste en juntar 2 grupos */
{
uent codRet,i;
uent formaElegirGrupoOrigen, formaElegirGrupoDestino;
c_Agrupamiento *agrup;
real probAux, probRestante;
uent indGrupoOrigen, indGrupoDestino, nroGrupoOrigen, nroGrupoDestino;
real maxSimProm, simProm, simPromDest, maxSimPromDest;
uent cantElem, minCantElem;
c_VecArchivo *vecCent2, *vecCent1;
uent cantGrupos;

agrup = cromosoma->agrup;

/* veamos de que forma elegimos al grupo origen */


probRestante = (real)1.0;
probAux = (real)(RegConfig.mutacionJoinProbAzar / probRestante);
if (TirarMonedaCargada(probAux))
formaElegirGrupoOrigen = 4; /* al azar */
else
{
probRestante -= probAux;
probAux = (real)(RegConfig.mutacionJoinProbMasChico / probRestante);
if (TirarMonedaCargada(probAux))
formaElegirGrupoOrigen = 2; /* el mas chico */

220 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

else
formaElegirGrupoOrigen = 3; /* menor similitud promedio */
}

switch (formaElegirGrupoOrigen)
{
case 2: /* mas chico */
minCantElem = MAX_UENT;
for (i=0; i < agrup->cantGrupos; i++)
{
cantElem = agrup->vecGrupos[i].cantElementos;
if (cantElem < minCantElem)
{
minCantElem = cantElem;
indGrupoOrigen = i;
}
}
maxSimProm = (real)(0 - minCantElem);
break;
case 3: /* menor similitud promedio */
maxSimProm = (real)-10000.0;
for (i=0; i < agrup->cantGrupos; i++)
{
vecCent2 = agrup->vecGrupos[i].vecCentroide;
simProm = (real)-1.0 * vecCent2->CalcularNorma(false);
if (simProm > maxSimProm)
{
maxSimProm = simProm;
indGrupoOrigen = i;
}
}
break;
case 4: /* al azar */
maxSimProm = (real)0.0;
indGrupoOrigen = RANDOM(agrup->cantGrupos);
break;
}
nroGrupoOrigen = agrup->vecGrupos[indGrupoOrigen].nroGrupo;

/* veamos de que forma elegimos al grupo destino */


probAux = (real)(RegConfig.mutacionJoinProbAzar / (RegConfig.mutacionJoinProbAzar
+ RegConfig.mutacionJoinProbMasSimilar));
if (TirarMonedaCargada(probAux))
formaElegirGrupoDestino = 4;
else
formaElegirGrupoDestino = 2;

switch (formaElegirGrupoDestino)
{
case 2: /* mas similar */
maxSimPromDest = (real)-1.0;
vecCent1 = agrup->vecGrupos[indGrupoOrigen].vecCentroide;
for (i=0; i < agrup->cantGrupos; i++)
{
if (i != indGrupoOrigen)
{
vecCent2 = agrup->vecGrupos[i].vecCentroide;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 221


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

simPromDest = vecCent1->Multiplicar(*vecCent2,false);
if (simPromDest > maxSimPromDest)
{
maxSimPromDest = simPromDest;
indGrupoDestino = i;
}
}
}
break;
case 4: /* al azar */
maxSimPromDest = (real)0.0;
indGrupoDestino = RANDOM(agrup->cantGrupos);
break;
}
nroGrupoDestino = agrup->vecGrupos[indGrupoDestino].nroGrupo;

cromosoma->ultimoJoin = indGrupoDestino;

fprintf(DebugFP(),"Join Grupos : fuente=(%d) [%d] %f, destino=(%d) [%d] Sim :


%f\n",nroGrupoOrigen,agrup-
>vecGrupos[indGrupoOrigen].cantElementos,maxSimProm,nroGrupoDestino,agrup-
>vecGrupos[indGrupoDestino].cantElementos,maxSimPromDest);

if (indGrupoDestino != indGrupoOrigen)
/* puede pasar que sean iguales cuando se elige al azar */
{
/* juntamos los 2 grupos */
for (i=0; i < agrup->cantElementos; i++)
{
if (agrup->vecElementos[i] == nroGrupoOrigen)
{
/* lo pasamos al otro */
cantGrupos = agrup->cantGrupos; /* para ver si cambia */
codRet =
c_KMeans::MoverElementoyRecalcular(*agrup,vVecArchivos,i,indGrupoOrigen,indGrupoDestin
o,true);
if (codRet != OK)
return codRet;
if (cantGrupos != agrup->cantGrupos)
{
indGrupoOrigen = agrup-
>IndiceDeGrupo(nroGrupoOrigen,false);
indGrupoDestino = agrup-
>IndiceDeGrupo(nroGrupoDestino,true);
}
}
}
}

return OK;
}

uent c_Genetico::AsignarFormaElegirGrupoSplit()
/* calcula la forma de elegir el grupo a partir de acuerdo a las probabilidades
(usado por el operador de mutacion split)
Devuelve : 1 = (... no definido)
2 = Mas grande
3 = Menor similitud promedio

222 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

4 = Al Azar
*/
{
real totalProbRestante;

totalProbRestante = (real)1.0;
if (TirarMonedaCargada(RegConfig.mutacionSplitProbMasGrande * (real)(1.0 /
totalProbRestante)))
{
return 2;
}
totalProbRestante -= RegConfig.mutacionSplitProbMasGrande;
if (TirarMonedaCargada(RegConfig.mutacionSplitProbMenorSimilProm * (real)(1.0 /
totalProbRestante)))
{
return 3;
}
/* si llegamos hasta aca, es al azar */
return 4;
}

uent c_Genetico::MutacionSplit(tCromosoma *cromosoma, c_VecArchivo *vVecArchivos[])


/* operador de mutacion que consiste en tomar un grupo y separarlo en 2 */
{
uent codRet,i;
uent formaElegirGrupoOrigen;
c_Agrupamiento *agrup;
uent indGrupoOrigen, nroGrupoOrigen;
real maxSimProm, simProm;
c_VecArchivo *vecCent2;
uent cantElem, maxCantElem;
uent kAux;
uent *vec2Ind;

agrup = cromosoma->agrup;

if (cromosoma->ultimoJoin == -1)
{

/* veamos de que forma elegimos al grupo a partir */


formaElegirGrupoOrigen = AsignarFormaElegirGrupoSplit();

switch (formaElegirGrupoOrigen)
{
case 2: /* mas grande */
maxCantElem = 0;
for (i=0; i < agrup->cantGrupos; i++)
{
cantElem = agrup->vecGrupos[i].cantElementos;
if (cantElem > maxCantElem)
{
maxCantElem = cantElem;
indGrupoOrigen = i;
}
}
maxSimProm = (real)maxCantElem;
break;
case 3: /* menor similitud promedio */

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 223


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

maxSimProm = (real)-10000.0;
for (i=0; i < agrup->cantGrupos; i++)
{
vecCent2 = agrup->vecGrupos[i].vecCentroide;
simProm = (real)-1.0 * vecCent2->CalcularNorma(false);
if (simProm > maxSimProm)
{
maxSimProm = simProm;
indGrupoOrigen = i;
}
}
break;
case 4: /* al azar */
maxSimProm = (real)0.0;
indGrupoOrigen = RANDOM(agrup->cantGrupos);
break;
}
}
else //tomamos el grupo donde se hizo el ultimo join
{
indGrupoOrigen = cromosoma->ultimoJoin;
maxSimProm = (real)-1.0;
}
nroGrupoOrigen = agrup->vecGrupos[indGrupoOrigen].nroGrupo;

fprintf(DebugFP(),"Split Grupos : fuente=(%d) [%d] %f\n",nroGrupoOrigen,agrup-


>vecGrupos[indGrupoOrigen].cantElementos,maxSimProm);

/* lo partimos */
/* guardamos el valor actual de k de la clase kmeans */
kAux = c_KMeans::k;
/* seteamos el k del kmeans igual a 2 */
c_KMeans::k = 2;
/* creamos un vector para contener el indice del nuevo grupo */
vec2Ind = (uent*)malloc(SINT * 2);
if (vec2Ind == NULL)
return ERROR_MEMORIA;
/* separamos el grupo en 2 usando la fase inicial del kmeans */
codRet =
c_KMeans::FaseInicial(*agrup,nroGrupoOrigen,vVecArchivos,vec2Ind,true,RegConfig.mutacion
SplitCantMuestras);
if (codRet != OK)
return codRet;
/* calculamos los centroides */
codRet = c_KMeans::CalcularCentroides(*agrup,vVecArchivos,2,vec2Ind);
if (codRet != OK)
return codRet;
/* reponemos el valor de k de la clase kmeans */
c_KMeans::k = kAux;

free((void*)vec2Ind);

return OK;
}

224 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.13 Def.h
/*
En este archivo se hacen las definiciones generales
que se utilizaran en el resto del programa
*/

#ifndef __NuestraDefH__
/* si no esta definido todo esto... */
/* lo definimos ahora */
#define __NuestraDefH__

#include "limits.h"

/* estamos en windows */
#define midefDOS

typedef char byte;


typedef unsigned char ubyte;
#define SBYTE sizeof(char)
#define MAX_UBYTE UCHAR_MAX
/* 8 bits, 1 byte */

typedef short int ent;


typedef unsigned short int uent;
#define SINT sizeof(short int)
#define MAX_UENT USHRT_MAX
/* 16 bits, 2 bytes */

typedef long int word;


typedef unsigned long int uword;
#define SWORD sizeof(long int)
#define MAX_UWORD ULONG_MAX
/* 32 bits, 4 bytes */

typedef float real;


#define SREAL sizeof(float);

#define BITS_A_BYTES(b) ((b & 7) ? ((b>>3)+1) : (b>>3))


/* devuelve la cantidad de bytes necesarias para almacenar b bits */
/* si b es divisible por 8, devuelve b/8, sino, (b/8)+1 */

#define TRUE 1
#define FALSE 0

#define MAX_LONG_PALABRA 250


/* cantidad maxima de caracteres que puede tener el nombre de un archivo */
#define MAX_LONG_NOMARCH 350

/* definimos el tamanio de los buffers */


#define TBUFFTXT 1000

#define OK 0
#define ERROR 1
#define ERROR_MEMORIA 2
#define ERROR_ARCHIVO 3
#define ERROR_DIRECTORIO 4

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 225


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

#define MODO_LECTURA 0
#define MODO_ESCRITURA 1

#endif

226 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.14 Sis.h
/*
En vez de incluir sisdos o sislinux debe incluirse
este archivo para poder tener definidas las funciones de sistema
*/

#include "def.h"

#ifdef midefDOS
/* dos */
#ifndef __SisDosH__
#include "sisdos.h"
#endif
#endif

#ifndef midefDOS
/* linux */
#ifndef __SisLinuxH__
#include "sislinux.h"
#endif
#endif

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 227


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.15 SisDos.h
/*
Va a contener las rutinas que dependen del sistema operativo en
version DOS
*/
#include <io.h>
#include <malloc.h>
#include "def.h"
#include <string.h>
#include <stdlib.h>

#define __SisDosH__

#define RANDOM(n) (random(n))


/* esta macro devuelve un nro random entre 0 y n-1 */

#define PI (real)3.14159

/* para hora y fecha voy a usar el formato DOS */


/* el puntero a directorio lo presento como puntero a unsigned, total...*/
typedef long t_dir;

t_dir PrimeroDir(char *path, char *nomarch);


/*
Abre el directorio "path" y devuelve en dir un puntero a la estructura
de directorio
Si devuelve NULL, el directorio no se pudo abrir o esta vacio
En nomarch devuelve el nombre del primer archivo del directorio
En f y h, fecha y hora de ultima modificacion
*/

t_dir SiguienteDir(t_dir d, char *nomarch);


/*
Obtiene el siguiente archivo del directorio
Si devuelve NULL, el directorio no tiene mas archivos
En nomarch devuelve el nombre del siguiente archivo del directorio
En f y h, fecha y hora de ultima modificacion
*/

ent random(int n);


/* Devuelve un nro aleatorio entre 0 y n-1 */

uent *kNumerosRandom(uent k, uent minimo, uent maximo, bool ordenados);


/* Devuelve k numeros al azar que esten entre minimo y maximo
(incluyendo el minimo y el máximo */

bool TirarMonedaCargada(real probabilidadTrue);


/* esta función devuelve "true" con probabilidad "probabilidadTrue"
"probabilidadTrue" debe estar comprendida entre 0 y 1 */

228 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.16 SisDos.cpp
/*
Va a contener las rutinas que dependen del sistema operativo en
version DOS
*/
#include "sisdos.h"

static struct _finddata_t blkarch;


static char ruta[255];
/* necesitamos que esto sea global */

t_dir PrimeroDir(char *path, char *nomarch)


/*
Abre el directorio "path" y devuelve en dir un puntero a la estructura
de directorio
Si devuelve NULL, el directorio no se pudo abrir o esta vacio
En nomarch devuelve el nombre del primer archivo del directorio
En f y h, fecha y hora de ultima modificacion
*/
{
char path2[256];
t_dir codRet;
strcpy(ruta,path);
strcpy(path2,path);
strcat(path2,"\\*.*");
if ((codRet = _findfirst(path2,&blkarch)) == -1)
/* no se pudo abrir */
return -1;
strcpy(nomarch,ruta);
strcat(nomarch,"\\");
strcat(nomarch,blkarch.name);
/* devolvemos un puntero no nulo */
return codRet;
}

t_dir SiguienteDir(t_dir d, char *nomarch)


/*
Obtiene el siguiente archivo del directorio
Si devuelve NULL, el directorio no tiene mas archivos
En nomarch devuelve el nombre del siguiente archivo del directorio
En f y h, fecha y hora de ultima modificacion
*/
{
if (_findnext(d, &blkarch) == -1)
return -1;
strcpy(nomarch,ruta);
strcat(nomarch,"\\");
strcat(nomarch,blkarch.name);
/* devolvemos no nulo */
return d;
}

ent random(int n)

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 229


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

{
/*
float f;

//conseguimos un nro entre 0 y 1


f = (float)(rand() - 1) / RAND_MAX;
f = f * n;

return (int)f;
*/

return (rand() % n);


}

uent *kNumerosRandom(uent k, uent minimo, uent maximo, bool ordenados)


{
uent *punt;
uent i,j,h,nroAzar,nroAzar2;

if (((maximo - minimo) + 1) < k)


return NULL;
/* creamos un vector de k numeros */
punt = (uent*)malloc(k * SINT);
if (punt==NULL)
return NULL;
/* vamos generando los numeros */
/* los generamos siempre ordenados, y si se necesitan desordenados,
los desordenamos despues */
if (((maximo - minimo) + 1) == k)
{
/* caso trivial */
for (i=0; i < k; i++)
punt[i] = minimo + i;
}
else
{
for (i=0; i < k; i++)
{
/* generamos un numero al azar en el intervalo que corresponde */
/* la primera vez va entre el minimo y el maximo
pero luego el intervalo se va achicando */
nroAzar = RANDOM(1 + (maximo - minimo) - i);
nroAzar += minimo;
/* veamos en que posicion del vector debe ingresarse */
j = 0;
while ((punt[j] <= nroAzar) && (j < i))
{
nroAzar++;
j++;
}
/* corremos las posiciones del vector hacia arriba */
for (h = i; h > j; h--)
{
punt[h] = punt[h-1];
}
/* lo insertamos */
punt[j] = nroAzar;
}

230 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

if (!ordenados)
{
/* los desordenamos */
for (i=0; i < k; i++)
{
nroAzar = RANDOM(k);
nroAzar2 = RANDOM(k);
j = punt[nroAzar];
punt[nroAzar] = punt[nroAzar2];
punt[nroAzar2] = j;
}
}

return punt;
}

bool TirarMonedaCargada(real probabilidadTrue)


{
uent nroAzar;

nroAzar = RANDOM(100);

return (nroAzar < (probabilidadTrue * 100));


}

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 231


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

A4.2.17 Ppal.cpp
#include "def.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <conio.h>
#include "skipl.h"
#include "archtxt.h"

#include "vecArchivos.h"
#include "archivostexto.h"
#include "filtrarpalabras.h"
#include "clsAgrupamiento.h"
#include "clsKMeans.h"
#include "clsAgrupImprime.h"
#include "clsGenetico.h"

/* VARIABLES GLOBALES */
uent generacionesGenetico;
char szSalida[300] = "salida\\salida_clustering.txt";
c_SkipList **lLexArchivos;
c_SkipList lTxt;
c_SkipList lLex;
c_VecArchivo **vVectoresArchivos;
time_t startTime, elapsedTime, endTime;
uent codRet;
uent kBisect;
char szMat[300] = "";
uent cantGrupos;
char szAlgoritmo[300];
uent iCorridas;

void ImprimirAgrupamiento(c_Agrupamiento &agrup)


/* imprime el agrupamiento en el archivo szSalida */
{
FILE *fpSalida;

fpSalida = fopen(szSalida,"wt");
fprintf(fpSalida,"CantMultip=%d\n",c_VecArchivo::contMultiplicaciones);
fprintf(fpSalida,"CantCalcNorma=%d\n",c_VecArchivo::contCalculoNorma);
fprintf(fpSalida,"CantMovimientos=%d\n",c_KMeans::contMoverYRecalcular);
c_Agrup_Imprime::salidaCompacta = true;
c_Agrup_Imprime::ImprimirTodo(fpSalida,agrup,vVectoresArchivos,lLex,lTxt);
fclose(fpSalida);
//xxxdebug
fpSalida = fopen("salida_no_compacta.txt","wt");
c_Agrup_Imprime::salidaCompacta = false;
c_Agrup_Imprime::ImprimirTodo(fpSalida,agrup,vVectoresArchivos,lLex,lTxt);
fclose(fpSalida);
}

/* Las funciones "Agrupar...." realizan un agrupamiento


y lo imprimen en szSalida
*/

232 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent AgruparRandom(uent k)
/* Realiza un agrupamiento al azar de los documentos en
k grupos */
{
c_Agrupamiento agrup;
uent codRet;

startTime = time(NULL);

codRet = agrup.Inicializar((uent)lTxt.ObtenerCantElementos());
if (codRet != OK)
return codRet;
codRet = agrup.AgruparAlAzar(k,k);
if (codRet != OK)
return codRet;

codRet = c_KMeans::CalcularCentroides(agrup,vVectoresArchivos,0,NULL);
if (codRet != OK)
return codRet;

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin agrupar al azar : %d segundos\n",elapsedTime);

ImprimirAgrupamiento(agrup);

return OK;
}

uent AgruparKMeansComun(uent k)
/* realiza un agrupamiento k-means en k grupos */
{
c_Agrupamiento agrup;
uent codRet;
uent *vecIndGrupos;
uent cantIteraciones = 100, cantCambiosTotal = 0;

startTime = time(NULL);

c_KMeans::k = k;

vecIndGrupos = (uent *)malloc(k * SINT);


if (vecIndGrupos == NULL)
return ERROR_MEMORIA;

codRet = agrup.Inicializar((uent)lTxt.ObtenerCantElementos());
if (codRet != OK)
return codRet;

codRet = agrup.AgruparAlAzar(1,1);
if (codRet != OK)
return codRet;

codRet = c_KMeans::FaseInicial(agrup,1,vVectoresArchivos,vecIndGrupos,false,0);
if (codRet != OK)
return codRet;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 233


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin fase inicial : %d segundos\n",elapsedTime);
startTime = time(NULL);

c_KMeans::CalcularCentroides(agrup,vVectoresArchivos,0,NULL);
//c_Agrup_Imprime::ImprimirTodo(stdout,agrup,vVectoresArchivos,lLex,lTxt);

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin calcular centroides : %d segundos\n",elapsedTime);
startTime = time(NULL);

printf("Vamos a refinar...\n");
c_KMeans::FaseRefinar(agrup,vVectoresArchivos,vecIndGrupos,true,cantIteraciones,c
antCambiosTotal);
printf("Refinar : %d iteraciones.\n",cantIteraciones);

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin refinar : %d segundos\n",elapsedTime);
startTime = time(NULL);

/* liberamos el vector de k indices */


free((void*)vecIndGrupos);

ImprimirAgrupamiento(agrup);

return OK;
}

uent AgruparBisectingKMeans(uent k, bool refinar)


/* realiza un agrupamiento bisecting k-means en k grupos */
{
c_Agrupamiento *agrup;
uent codRet;

agrup = new c_Agrupamiento();

startTime = time(NULL);

printf("Empezando bisecting k-means ...\n");

c_KMeans::k = k;

codRet = agrup->Inicializar((uent)lTxt.ObtenerCantElementos());
if (codRet != OK)
return codRet;

codRet = agrup->AgruparAlAzar(1,1);
if (codRet != OK)
return codRet;

codRet = c_KMeans::BisectingKMeans(agrup,1,vVectoresArchivos,kBisect,refinar);
if (codRet != OK)
return codRet;

234 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin bisecting k-means : %d segundos\n",elapsedTime);
startTime = time(NULL);

ImprimirAgrupamiento(*agrup);

delete(agrup);
return OK;
}

uent AgruparBisectingKMeansSinRef(uent k)
{
return AgruparBisectingKMeans(k,false);
}

uent AgruparBisectingKMeansConRef(uent k)
{
return AgruparBisectingKMeans(k,true);
}

uent AgruparGenetico(uent k)
/* Realiza un agrupamiento de los documentos en k grupos
usando el algoritmo genetico */
{
c_Genetico objGenetico;
uent codRet;
c_Agrupamiento *agrup = NULL;
uent cantGeneraciones, i, cantIteraciones, cantCambiosTotal;
FILE *fp;
uent *vecIndGrupos;
char szDebug[255];

//fp = NULL;
sprintf(szAlgoritmo,"Gen");
sprintf(szSalida,"salida\\salida_%s_%s_%d_%d.txt",szMat,szAlgoritmo,cantGrupos,iCor
ridas);

sprintf(szDebug,"%s_d.asc",szSalida);
fp = fopen(szDebug,"wt");

objGenetico.RegConfig.fpSalidaDebug = fp;

uent a = 0;

startTime = time(NULL);

objGenetico.RegConfig.k = k;

codRet =
objGenetico.GenerarPoblacionInicial((uent)lTxt.ObtenerCantElementos(),vVectoresArchivos);
if (codRet != OK)
return codRet;

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin generar poblacion inicial : %d segundos\n",elapsedTime);
startTime = time(NULL);

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 235


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

cantGeneraciones = generacionesGenetico;
codRet = objGenetico.Evolucionar(vVectoresArchivos,true,cantGeneraciones);
if (codRet != OK)
return codRet;

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin evolucion : %d segundos\n",elapsedTime);
startTime = time(NULL);

codRet = objGenetico.DevolverMejorSolucion(&agrup);
if (codRet != OK)
return codRet;

if (fp != NULL)
fclose(fp);

/* lo imprimimos sin refinar */


ImprimirAgrupamiento(*agrup);

/* ahora lo refinamos con el KMeans */


c_KMeans::k = agrup->cantGrupos;
vecIndGrupos = (uent*)malloc(agrup->cantGrupos * SINT);
for (i=0; i < agrup->cantGrupos; i++)
vecIndGrupos[i] = i;
cantIteraciones = 100;
codRet =
c_KMeans::FaseRefinar(*agrup,vVectoresArchivos,vecIndGrupos,true,cantIteraciones,cantCam
biosTotal);

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin refinar : %d segundos\n",elapsedTime);
startTime = time(NULL);
/* lo imprimimos refinado */
sprintf(szAlgoritmo,"Gen(ref)");
sprintf(szSalida,"salida\\salida_%s_%s_%d_%d.txt",szMat,szAlgoritmo,cantGrupos,iCor
ridas);
ImprimirAgrupamiento(*agrup);

return OK;
}

int main(void)
{
int i;
//int j;
//uent valEnt;
//real valReal;
char szDir[300] = "d:\\Tesis_Docs";
char szPathMat[300] = "";
uent cantLex;
uent cantArchivos;
char opcion;
uent codRet;
bool bCorrerAlgoritmo;
uent (*funcionAgrupar)(uent); /* puntero a la funcion */

236 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

uent cantCorridas;
uent cantGruposLoc;

/* inicializamos la serie de numeros al azar */


srand( (unsigned)time( NULL ) );

/* preguntamos por el directorio de los archivos */


printf ("Directorio donde se encuentran los archivos (ej: 'd:\\Tesis_Docs') : ");
scanf("%s",&szDir); getchar();
/* veamos si hay que leer archivos txt del disco
o si se debe cargar un dataset .mat */
printf ("Nombre del .mat (ej : 're0_1') o 'txt' para leer archivos .txt : ");
scanf("%s",&szMat); getchar();

if (strcmp((char*)&szMat,"txt") == 0)

/* ***************************************** */
/* LEEMOS LOS ARCHIVOS .TXT DEL DISCO */
/* Se leen los archivos y se arman las listas de
palabras */

startTime = time(NULL);

lTxt.SetearOrden(1); /* los ordenamos por numero */


cantArchivos = CargarListaArchivos(szDir,lTxt);

/* creamos los vectores de listas y vectores de palabras */


lLexArchivos = (c_SkipList**)malloc((cantArchivos+1)*sizeof(c_SkipList*));
if (lLexArchivos == NULL)
return ERROR_MEMORIA;
vVectoresArchivos =
(c_VecArchivo**)malloc((cantArchivos+1)*sizeof(c_VecArchivo*));
if (vVectoresArchivos == NULL)
return ERROR_MEMORIA;

codRet = ProcesarArchivosTexto(lTxt,lLex,TBUFFTXT,cantLex,lLexArchivos);
if (codRet != OK)
return codRet;

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin leer archivos : %d segundos\n",elapsedTime);
startTime = time(NULL);

/* FIN DE LEER LOS ARCHIVOS */


/*********************************************/

/* ******************************************** */
/* VAMOS A FILTRAR LAS LISTAS DE LEXICO */

codRet =
FiltrarListasDeLexico(lLex,lLexArchivos,lTxt.ObtenerCantElementos());
if (codRet != OK)
return codRet;

/* al renumerar los valores, la lista de lexico queda ordenada tanto

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 237


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

por numero de palabra como por orden alfabético */


lLex.RenumerarValores();

/* FIN FILTRAR LISTAS DE LEXICO */


/************************************/

}
else
{
/* Leemos un dataset en formato .mat */

sprintf((char*)&szPathMat,"%s\\%s.mat",szDir,szMat);

startTime = time(NULL);

lTxt.SetearOrden(1); /* los ordenamos por numero */

cantArchivos = CargarListaArchivosMAT(szPathMat,lTxt);

/* creamos los vectores de listas y vectores de palabras */


lLexArchivos = (c_SkipList**)malloc((cantArchivos+1)*sizeof(c_SkipList*));
if (lLexArchivos == NULL)
return ERROR_MEMORIA;
vVectoresArchivos =
(c_VecArchivo**)malloc((cantArchivos+1)*sizeof(c_VecArchivo*));
if (vVectoresArchivos == NULL)
return ERROR_MEMORIA;

lLex.SetearOrden(1); /* lo ordenamos por numero */

codRet = ProcesarArchivosTextoMAT(szPathMat,lLex,cantLex,lLexArchivos);
if (codRet != OK)
return codRet;

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin leer .mat : %d segundos\n",elapsedTime);
startTime = time(NULL);

/* ******************************************** */
/* VAMOS A CREAR LOS VECTORES DE ARCHIVOS */

codRet =
ArmarVectoresArchivos(lLex,lTxt.ObtenerCantElementos(),lLexArchivos,vVectoresArchivos);
if (codRet != OK)
return codRet;

/* a partir de aca no vamos a volver a buscar por orden


alfabetico en la lista de lexico */
lLex.SetearOrden(1);

/* no necesitamos más las listas de palabras de los archivos */


for (i=1; i <= cantArchivos; i++)
delete(lLexArchivos[i]);
free((void*)lLexArchivos);

238 APÉNDICE 4 - PROGRAMACION Eugenio Yolis


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

endTime = time(NULL);
elapsedTime = endTime - startTime;
printf("Fin inicializacion : %d segundos\n",elapsedTime);
startTime = time(NULL);

/* FIN DE ARMAR VECTORES DE ARCHIVOS */


/* ************************************************* */

/* Ahora vamos a mostrar un menu para que se pueda


elegir que hacer */

opcion = 0;
/* valores por default */
cantGrupos = 15;
cantCorridas = 5;
kBisect = 2;
generacionesGenetico = 50;

while (opcion != 'x')


{
bCorrerAlgoritmo = false;
printf("(1) Cambiar cantidad grupos (%d)\n",cantGrupos);
printf("(2) Cambiar cantidad corridas (%d)\n",cantCorridas);
printf("(3) Cambiar generaciones del genetico (%d)\n",generacionesGenetico);
// printf("(4) Cambiar k de bisecting K-Means (%d)\n",kBisect);
printf("(a) Bisecting K-Means (con refinamiento)\n");
printf("(b) Algoritmo Genetico (con y sin refinamiento)\n");
// printf("(c) Al Azar\n");
// printf("(d) K-Means Comun\n");
// printf("(e) Bisecting K-Means (sin refinar)\n");
printf("(x) Salir\n");
printf("\n");
printf ("? ");
opcion = (char)getchar(); getchar();

switch (opcion)
{
case 'a':
funcionAgrupar = &AgruparBisectingKMeansConRef;
sprintf(szAlgoritmo,"BisKM(ref)%d",kBisect);
bCorrerAlgoritmo = true;
break;
case 'b':
funcionAgrupar = &AgruparGenetico;
sprintf(szAlgoritmo,"Gen");
bCorrerAlgoritmo = true;
break;
case 'c':
funcionAgrupar = &AgruparRandom;
sprintf(szAlgoritmo,"Azar");
bCorrerAlgoritmo = true;
break;
case 'd':
funcionAgrupar = &AgruparKMeansComun;
sprintf(szAlgoritmo,"KMCom");
bCorrerAlgoritmo = true;
break;

Eugenio Yolis APÉNDICE 4 - PROGRAMACION 239


ALGORITMOS GENÉTICOS APLICADOS A LA CATEGORIZACIÓN AUTOMÁTICA DE DOCUMENTOS

case 'e':
funcionAgrupar = &AgruparBisectingKMeansSinRef;
sprintf(szAlgoritmo,"BisKM%d",kBisect);
bCorrerAlgoritmo = true;
break;
case '1':
printf("Grupos : ");
scanf("%d",&cantGruposLoc); getchar();
cantGrupos = cantGruposLoc;
break;
case '2':
printf("Corridas : ");
scanf("%d",&cantCorridas); getchar();
break;
case '3':
printf("Generaciones : ");
scanf("%d",&generacionesGenetico); getchar();
break;
case '4':
printf("K de bisecting k-means : ");
scanf("%d",&kBisect); getchar();
break;
}

if (bCorrerAlgoritmo)
{
for (iCorridas = 0; iCorridas < cantCorridas; iCorridas++)
{
/* reseteamos los contadores de las clases */
c_KMeans::contMoverYRecalcular = 0;
c_VecArchivo::contCalculoNorma = 0;
c_VecArchivo::contMultiplicaciones = 0;

sprintf(szSalida,"salida\\salida_%s_%s_%d_%d.txt",szMat,szAlgoritmo,cantGrupos,iCor
ridas);
codRet = (*funcionAgrupar)(cantGrupos);
if (codRet != OK)
return codRet;
}
}

/* liberamos los vectores de los archivos */


for (i=1; i <= cantArchivos; i++)
delete(vVectoresArchivos[i]);
free((void*)vVectoresArchivos);

return 0;
}

240 APÉNDICE 4 - PROGRAMACION Eugenio Yolis

Potrebbero piacerti anche