P. 1
navas-tesisdegradoingenieriainformatica

navas-tesisdegradoingenieriainformatica

|Views: 378|Likes:
Published by Yorman Diaz

More info:

Published by: Yorman Diaz on Oct 09, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

02/19/2013

pdf

text

original

Sections

  • 1 Introducción
  • 1.2 Clustering Temporal
  • 1.3 Contribución
  • 1.4 Algoritmos de Clustering
  • 1.4.1 Algoritmos de Particionamiento (Partitioning Algorithms)
  • 1.4.2 Algoritmos Jerárquicos (Hieralchical Algorithms)
  • 1.4.3 Algoritmos Basados en Densidad (Density-Based Algorithms)
  • 1.4.4 Algoritmos Basados en Grillas (Grid-Based Algorithms)
  • 1.5 Elección del algoritmo adecuado
  • 1.6 Objetivo de la Tesis
  • 1.7 Estructura de la Tesis
  • 2 Trabajos Relacionados
  • 3 Modelo Temporal
  • 3.1 Modelos temporales de datos
  • 3.1.1 Combinación y Eliminación de Información repetida
  • 3.2 Distintos esquemas de representación de datos temporales
  • 3.2.1 Tupla con marca de tiempo de Snodgrass
  • 3.2.2 Esquema acumulativo de Jensen
  • 3.2.3 Atributo con marca de tiempo de Gadia
  • 3.2.4 Atributo con Marca de Tiempo de McKenzie
  • 3.2.5 Tupla con marca de tiempo de Ben-Zvi
  • 3.3 Modelo de representación de datos para clustering temporal
  • 3.4 Intervalos de tiempo a analizar
  • 4 Implementación
  • 4.1 Generación del Archivo temporal
  • 4.2 Clustering temporal
  • 4.2.1 K-D-Median
  • 4.2.2 Implementación de k-D-Median
  • 4.2.3 Atributos Categóricos en K-D-Median
  • 4.2.4 Algoritmo k-D-Median Temporal
  • 4.2.5 Relación entre clusters de distintos tiempos
  • 4.2.6 Análisis de Resultados
  • 5 Experimentación
  • 5.1 Casos de prueba
  • 5.1.1 Consideraciones generales
  • 5.1.2 Caso de prueba 1
  • 5.1.3 Caso de prueba 2
  • 5.1.4 Caso de prueba 3
  • 5.1.5 Prueba de Performance
  • 6 Conclusiones
  • 6.1 Conclusiones
  • 6.2 Trabajo Futuro
  • Apéndices
  • A1 Diseño del Código
  • A1.1 Casos de Uso
  • A1.2 Detalle de Casos de Uso
  • A1.3 Estructura de Clases
  • A1.4 Nuevas Clases
  • A2 Código Fuente
  • A2.1 WEKA
  • A2.2 MATLAB
  • A3 Instructivo de Instalación y Manual de Usuario
  • A3.1 Instructivo de Instalación
  • Estructura del CD de instalación
  • A3.2 Manual de Usuario

Un modelo de

Clustering Temporal



Tesis de Grado
Ingeniería en Informática



Facultad de Ingeniería
Universidad de Buenos Aires




TESISTA: María Daniela Navas
Padrón 75.626
mnavas@mnavas.com.ar

DIRECTOR: Prof. Dr. Juan M. Ale



Octubre 2004

Resumen

Clustering consiste en particionar el conjunto de datos en colecciones de objetos de
manera que dentro de cada partición los objetos sean “similares” entre sí, y a su vez se
“diferencien” de los objetos contenidos en otras particiones. En la literatura han sido propuestos
muchos algoritmos para realizar el proceso de clustering, pero la mayoría de ellos tiene un
enfoque estático, por lo tanto, estas soluciones no pueden ser aplicadas correctamente para
datos más complejos, como colecciones de objetos espacio-temporales. En muchos casos, la
información guardada en las bases de datos tiene una naturaleza espacial dinámica: además de
tener datos espaciales, a menudo se asocian los mismos con información temporal, como marcas
de tiempo (time-stamp) ,manejo de versiones, fechas o rango de fechas.

En el presente trabajo se propone un método de Clustering Temporal que realiza el
proceso de clustering sólo teniendo en cuenta los atributos espaciales o “no temporales”, para
distintos momentos de tiempo (dato aportado por los atributos temporales). Esto nos permite ver
cómo varían los clusters durante el transcurso del tiempo, observar la trayectoria de los objetos, y
obtener distintas estadísticas sobre el movimiento de clusters y objetos, que no se podrían
obtener aplicando un algoritmo de clustering estándar.



Abstract

Clustering consists in partitioning a data group into object collections in a way that inside
each partition the objects are "similar" between them, and at the same time they could be
"differentiated" from the objects contained by another partitions. In the literature a lot of algorithms
have been proposed to make the clustering process, but most of them have a static point of view,
so they cannot be used correctly for more complex data, as spatial - temporal object collections. In
many situations, the information stored at data bases has a dynamic spatial structure, as time
stamps, version management, dates or date ranges.

In the present work a Temporal Clustering method is proposed which uses the clustering
method only taking into account the spatial or “no temporal” attributes, for different portions of time
(information given by the temporal attributes). This allows us to see how the clusters modify with
the time, determine the trajectory of the objects, and obtain different statistics about cluster and
object movements, which could not be obtained by using a standard clustering algorithm.


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 3 -





Indice








1 Introducción __________________________________________________ 5
1.1 Clustering 5
1.2 Clustering Temporal ____________________________________________ 5
1.3 Contribución__________________________________________________ 6
1.4 Algoritmos de Clustering ________________________________________ 6
1.4.1 Algoritmos de Particionamiento (Partitioning Algorithms) ________________________ 7
1.4.2 Algoritmos Jerárquicos (Hieralchical Algorithms) ______________________________ 7
1.4.3 Algoritmos Basados en Densidad (Density-Based Algorithms)____________________ 7
1.4.4 Algoritmos Basados en Grillas (Grid-Based Algorithms)_________________________ 8
1.5 Elección del algoritmo adecuado __________________________________ 8
1.6 Objetivo de la Tesis ____________________________________________ 9
1.7 Estructura de la Tesis __________________________________________ 9
2 Trabajos Relacionados ________________________________________ 11
3 Modelo Temporal _____________________________________________ 13
3.1 Modelos temporales de datos ___________________________________ 13
3.1.1 Combinación y Eliminación de Información repetida___________________________ 14
3.2 Distintos esquemas de representación de datos temporales ___________ 15
3.2.1 Tupla con marca de tiempo de Snodgrass __________________________________ 15
3.2.2 Esquema acumulativo de Jensen _________________________________________ 16
3.2.3 Atributo con marca de tiempo de Gadia ____________________________________ 16
3.2.4 Atributo con Marca de Tiempo de McKenzie_________________________________ 17
3.2.5 Tupla con marca de tiempo de Ben-Zvi_____________________________________ 17
3.3 Modelo de representación de datos para clustering temporal ___________ 18
3.4 Intervalos de tiempo a analizar __________________________________ 18
4 Implementación ______________________________________________ 23
4.1 Generación del Archivo temporal_________________________________ 23
4.2 Clustering temporal ___________________________________________ 25
4.2.1 K-D-Median __________________________________________________________ 25
4.2.2 Implementación de k-D-Median___________________________________________ 27
4.2.3 Atributos Categóricos en K-D-Median______________________________________ 32
4.2.4 Algoritmo k-D-Median Temporal __________________________________________ 34
4.2.5 Relación entre clusters de distintos tiempos _________________________________ 35
4.2.6 Análisis de Resultados _________________________________________________ 36
5 Experimentación _____________________________________________ 37
5.1 Casos de prueba _____________________________________________ 37
5.1.1 Consideraciones generales______________________________________________ 37
5.1.2 Caso de prueba 1 _____________________________________________________ 37
5.1.3 Caso de prueba 2 _____________________________________________________ 51
5.1.4 Caso de prueba 3 _____________________________________________________ 66
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 4 -
5.1.5 Prueba de Performance ________________________________________________ 81
6 Conclusiones ________________________________________________ 83
6.1 Conclusiones ________________________________________________ 83
6.2 Trabajo Futuro _______________________________________________ 83
Apéndices ______________________________________________________ 89
A1 Diseño del Código ____________________________________________ 89
A1.1 Casos de Uso ________________________________________________________ 89
A1.2 Detalle de Casos de Uso ________________________________________________ 90
A1.3 Estructura de Clases ___________________________________________________ 93
A1.4 Nuevas Clases________________________________________________________ 96
A2 Código Fuente _______________________________________________ 99
A2.1 WEKA ______________________________________________________________ 99
A2.2 MATLAB____________________________________________________________ 142
A3 Instructivo de Instalación y Manual de Usuario _____________________ 175
A3.1 Instructivo de Instalación _______________________________________________ 175
Estructura del CD de instalación _____________________________________________ 175
A3.2 Manual de Usuario____________________________________________________ 179































María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 5 -





1 Introducción








1.1 Clustering

Se denomina proceso de descubrimiento de conocimiento en bases de datos (Knowlegde
Discovery in Databases-KDD) al proceso de descubrir conocimiento interesante, como por ejemplo
patrones, asociaciones, cambios, anomalías y estructuras significativas, en grandes cantidades de
datos guardados en bases de datos u otros repositorios de información.
Data Mining se refiere a la aplicación de algoritmos para la extracción de patrones
utilizando los datos disponibles, o sea, que es un componente del proceso de Knowlegde
Discovery.
Clustering es una de las principales tareas en Data Mining y consiste en particionar el
conjunto de datos (dataset) en colecciones de objetos o instancias de manera que dentro de cada
partición los objetos sean “similares” entre sí, y a su vez se “diferencien” de los objetos contenidos
en otras particiones. Similitud y disimilitud son expresadas a través de funciones de distancia /
similitud y a las particiones resultantes se las denomina clusters.
Luego de haber particionado al grupo de datos en clusters, es interesante encontrar cuáles
son las características claves de cada grupo. Esto requiere la aplicación de otras técnicas como
análisis estadístico, clasificación o reglas de asociación, por lo tanto clustering es sólo un paso si el
objetivo de análisis es más amplio (Nanni, [20,21]).

1.2 Clustering Temporal

En la literatura han sido propuestos hasta el momento, muchos algoritmos para realizar el
proceso de clustering (Han et al., [14]). Sin embargo, hasta ahora, la mayoría de los resultados
conciernen a datos simples, compuestos por elementos representados como puntos individuales
en un espacio multidimensional (posiblemente con una combinación de dimensiones discretas y
continuas).
Las soluciones desarrolladas bajo estas restricciones no pueden ser aplicadas
correctamente para datos más complejos, como colecciones de objetos espacio-temporales. En
muchos casos, la información guardada en las bases de datos tiene una naturaleza espacial
dinámica: no solamente las bases tienen datos espaciales, sino que a menudo asocian los datos
espaciales con información temporal, como marcas de tiempo (time-stamp) o manejo de versiones,
e incluso en muchos casos contienen información temporal dada por una fecha o rango de fechas.
En estos casos algunas de las peculiaridades de los datos deben ser sacrificadas para
poder utilizar los procesos de clustering convencionales. Por lo tanto, se requieren soluciones
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 6 -
capaces de manejar las nuevas nociones de “distancias” que pueden desprenderse de datos tan
complejos.
Para resolver esto, algunas propuestas proponen utilizar nuevos conceptos de distancias y
métricas adaptadas a un contexto espacio-temporal (Nanni, [20,21]), esto permite agrupar en un
mismo cluster a objetos que tienen similitudes tanto en sus atributos espaciales como en sus
atributos temporales.

1.3 Contribución

En el presente trabajo se resuelve el problema desde otro enfoque (Navas et. al, [22]): se
propone un método que realiza el proceso de clustering sólo teniendo en cuenta los atributos
espaciales o “no temporales”, para distintos momentos de tiempo (dato aportado por los atributos
temporales). Esto nos permite ver cómo varían los clusters durante el transcurso del tiempo. Lo
que se hizo fue crear un modelo temporal que determina a qué tipo de datos se puede aplicar este
proceso de clustering, cómo se deben especificar los mismos, cómo se procesa la información y
cómo se muestran los resultados.
Este modelo se comporta como un framework o marco; es un “molde” que puede basarse
en cualquier algoritmo de clustering “convencional” (que no maneje datos temporales), para crear
el algoritmo temporal que provee todas las ventajas que se especifican en el presente trabajo, por
lo tanto se investigó qué algoritmo podía ser el más adecuado para este propósito.

1.4 Algoritmos de Clustering

Para elegir un algoritmo de clustering adecuado para una determinada aplicación deben
considerarse varios factores, según se indica en (Han et al, [14]). Los mismos son:

♦ Objetivo de la aplicación: El objetivo de la aplicación a menudo afecta la elección de un
algoritmo de clustering. Por ejemplo, si se desea encontrar la ubicación óptima de las
sucursales de una cadena de supermercados, el objetivo será encontrar la mínima
distancia entre los clientes y cada sucursal. En el caso de reconocimiento de imágenes, a
menudo es deseable hallar los clusters que se forman naturalmente, en donde los
clusters deberán tener cierta uniformidad de color, densidad, etc.
Los algoritmos de particionamiento (partitioning algorithms) como k-means o k-medoids,
son útiles para el primer caso, y tienden a descubrir clusters con forma esférica y tamaño
similar. En cambio para el segundo caso responden mejor los algoritmos basados en
densidad (density-based algorithms)


♦ Elección entre calidad y velocidad: Existe siempre un problema al elegir entre velocidad
de procesamiento y calidad de los clusters obtenidos. Un algoritmo adecuado debe
cumplir con estas dos características, pero a veces la cantidad de instancias a procesar
juega un papel importante en el tiempo de ejecución del algoritmo de clustering. Un
algoritmo que produce clusters de calidad, por lo general es incapaz de manejar grandes
cantidades de información. A su vez, cuando se trabaja con grandes volúmenes de datos
se realiza una especie de compresión sobre la información inicial, perdiendo así calidad.

♦ Características de los datos: Las características de los datos a los cuales se quiere
aplicar el clustering, también son un factor importante para la elección del método
adecuado.

o Tipos de datos de los atributos: La similitud entre dos objetos es medida según
la diferencia entre los valores de sus atributos. Cuando todos los atributos son
numéricos las medidas de distancia como Euclídea o Manhattan pueden ser
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 7 -
fácilmente computadas. En cambio, cuando los atributos son binarios,
categóricos u ordinales, este cálculo se complica. Por lo tanto, la mayoría de
los algoritmos se aplican sólo a datos numéricos.

o Dimensionalidad: la dimensionalidad se refiere al número de atributos de cada
objeto. Muchos algoritmos funcionan bien con pocos atributos, pero al
aumentar las dimensiones los resultados se degeneran. La degeneración
puede darse por la disminución de la velocidad o el empobrecimiento de la
calidad de los clusters.

o Cantidad de ruido en los datos: Algunos algoritmos son muy sensibles a ruido
o elementos aislados, no pudiendo funcionar correctamente ante la presencia
de los mismos.


A continuación se explican brevemente, los cuatro principales tipos de algoritmos de
clustering.

1.4.1 Algoritmos de Particionamiento (Partitioning Algorithms)

Dado un conjunto D de n objetos en un espacio de d dimensiones, y tomando como
parámetro de entrada el valor k, un algoritmo de particionamiento organiza los objetos dentro de k
clusters tal que sea minimizada la desviación total de cada objeto desde el centro de su cluster o
desde una distribución de clusters. La desviación de un punto puede ser computada en forma
diferente según el algoritmo, y es llamada generalmente función de similitud.
Ejemplos : k-means, k-medoids, EM (Expectation Maximization)

1.4.2 Algoritmos Jerárquicos (Hieralchical Algorithms)

Un método jerárquico crea una descomposición jerárquica de un conjunto de datos,
formando un dendrograma, un árbol que divide la base de datos recursivamente en conjuntos cada
vez más pequeños. El árbol puede ser formado de dos formas: de abajo hacia arriba (“botton-up”)
o de arriba hacia abajo (“top-down”).
En el caso “botton-up”, también llamado aglomerativo, se comienza con cada objeto
formando un grupo por separado. Los objetos o grupos se combinan sucesivamente según
determinadas medidas, hasta que todos los grupos se hayan unido en uno solo, o hasta que se
cumpla alguna condición de terminación.
En el caso “top-down”, también llamado divisivo, se comienza con todos los objetos en el
mismo cluster, y a medida que se va iterando, se dividen los grupos en subconjuntos más
pequeños según determinadas medidas, hasta que cada objeto esté en un cluster individual o
hasta que se cumplan las condiciones de terminación.
Ejemplos: AGNES (Aglomerative NESting), DIANA (Divisia ANAlysis), CURE (Clustering
Using Representatives), CHAMALEON, BIRCH (Balanced Iterative Reducing and Cluestering using
Hierarchical)

1.4.3 Algoritmos Basados en Densidad (Density-Based Algorithms)

La mayoría de los métodos de particionamiento, realizan el proceso de clustering en base
a la distancia entre dos objetos. Estos métodos pueden encontrar sólo clusters esféricos, y se les
dificulta hallar clusters de diversas figuras. Otros algoritmos de clustering han sido desarrollados en
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 8 -
base a la noción de “densidad”. Estos generalmente estiman clusters como regiones con gran
densidad de objetos, separados de regiones de baja densidad de objetos (estos elementos
aislados representan ruido). Este tipo de métodos es muy útil para filtrar ruido y encontrar clusters
de diversas formas.
Ejemplos: DBSCAN (Density-Based Spatial Clustering of Aplications with Noise), OPTICS
(Ordering Points To Identify the Clustering Structure), DENCLUE (DENsity-based CLUstEring)

1.4.4 Algoritmos Basados en Grillas (Grid-Based Algorithms)

Los métodos basados en densidad suelen tener grandes problemas cuando se trabaja con
bases de datos muy grandes. Para mejorar la efectividad del clustering, un método basado en
grillas usa una estructura de grilla de datos. El método divide el espacio en un número finito de
celdas, formando una grilla, en donde se realizan todas las operaciones del clustering.
La mayor ventaja de este método es su veloz procesamiento del tiempo, el cual
generalmente es independiente de la cantidad de objetos a procesar.
Ejemplos: STING (A STatistical INformation Grid), WaveCluster, CLIQUE, etc.


1.5 Elección del algoritmo adecuado

El objetivo del presente trabajo es implementar un nuevo método de clustering temporal el
cual está basado en algún algoritmo ya existente. Como se especificó con anterioridad, existen
numerosos algoritmos y la elección del adecuado depende del tipo de problema que se quiera
encarar. Por lo tanto, es necesario buscar un área determinada, en la cuál sea útil la información
que puede proveer este clustering temporal.
Se ha decidido utilizar bases de datos con información demográfica, por ejemplo, datos
que provee el INDEC (Instituto Nacional de Estadística y Censos), ya que sería muy útil poder
determinar como varían los resultados obtenidos en censos durante el transcurso de los años.
Estas bases de datos poseen la particularidad de ser muy grandes, por lo que se necesita
un algoritmo que sea lo suficientemente rápido para poder analizar grandes volúmenes de datos.
La información recolectada es representada por una cantidad mediana de atributos, que
pueden ser numéricos o nominales. La cantidad de ruido o de objetos aislados no se puede
determinar, pero puede estar presente.
Según la división de algoritmos de clustering explicada anteriormente, los algoritmos que
mejor se adaptan a este tipo de problema son los de particionamiento.
Comparando distintos algoritmos existentes dentro de este rubro (Estivill-Castro et. al,
[5,6,7,8,9]; Grabmeier et. al, [12]; Huang et. al, [15]; Ng et.al, [23]) se seleccionó un algoritmo
llamado k-D-median, presentado por sus autores (Estivill-Castro, et al. [10]) como un algoritmo de
clustering de propósito general rápido y robusto.
Lo que se hizo en el presente trabajo fue implementar un nuevo algoritmo en Java para
integrarlo al sistema WEKA, que realiza el formateo de los datos y el proceso de clustering en sí.
También se creó en Matlab una aplicación que permite analizar gráficamente los resultados del
clustering.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 9 -
1.6 Objetivo de la Tesis

El objetivo de esta Tesis de grado es:
Crear un modelo genérico de clustering temporal que permita realizar el proceso de
clustering teniendo en cuenta los atributos espaciales o “no temporales”, para distintos
momentos de tiempo.

Desarrollar un algoritmo que realice el clustering temporal, basándose en el modelo
indicado anteriormente.

Utilizar una herramienta gráfica para visualizar el resultado del clustering temporal.


1.7 Estructura de la Tesis

La presente tesis se divide en 6 capítulos y 3 apéndices. El Capítulo 1, como ya se pudo
apreciar, detalla una introducción al clustering en general y al clustering temporal en particular. El
Capítulo 2 describe trabajos realizados por otros autores que están relacionados con este tema. En
el Capítulo 3 se explica el modelo temporal de datos utilizado, y su adaptación para realizar el
clustering temporal. En el Capítulo 4 se describe cómo se implementó el algoritmo. En el Capítulo
5 se describe una serie de experimentos que muestran la utilidad, performance y escalabilidad del
algoritmo. Por último, el Capítulo 6 remarca las conclusiones.
El Apéndice 1 muestra el análisis y diseño que se realizó para llegar a la solución
implementada. El Apéndice 2 contiene el código fuente generado y el Apéndice 3 indica los pasos
necesarios a realizar para la instalación del software adjunto y el manual de usuario.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 10 -
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 11 -


2 Trabajos
Relacionados








En la bibliografía actual existen varios intentos para tratar los objetos temporales. Por
ejemplo, en (Roddick et. al, [30]) se propone tratar las coordenadas temporales como geográficas,
utilizando el espacio cartesiano. Pero prácticamente ninguno aplica estos conocimientos
específicamente al proceso de clustering. En (Adair et. al, [1]; Bittner et. al, [2]; Galic et. al, [11],
Hammoud et. al, [13]; Popescul et. al, [25]) se realizan distintos enfoques de clustering espacio-
temporal, pero algunos son muy específicos a un problema determinado, y otros no llegan a
proponer algún modelo o algoritmo interesante.
En (Nanni, [20,21]) se propone una familia de medidas de similitud definida sobre objetos
espacio-temporales, que se pueden utilizar con cualquier algoritmo de clustering para mejorar su
performance. Primero se propone una definición de lo que es una distancia espacio-temporal,
enfocándose en las propiedades de las métricas. Luego se analiza el comportamiento de
algoritmos de clustering al aplicar alguna distancia de las definidas en su esquema, y se proponen
optimizaciones a dichos algoritmos.
En (Han et al, [14]) se presenta un estudio sobre distintos tipos de algoritmos de clustering,
que se consultó para evaluar la mejor forma de implementar el presente trabajo.
La diferencia del presente trabajo con otros trabajos o algoritmos implementados es
justamente que no se trata sólo de un algoritmo, sino de un framework que se puede aplicar a
cualquier algoritmo de clustering convencional, para obtener información temporal sobre
prácticamente cualquier campo de estudio (dependiendo del algoritmo base).
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 12 -
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 13 -


3 Modelo
Temporal







3.1 Modelos temporales de datos

Cuando se piensa en la forma de representar valores que varían con el tiempo, la principal
pregunta es cómo asociar los hechos con el tiempo. Según (Jensen et.al.,[18]) existen numerosos
modelos de datos temporales que de alguna forma asocian los hechos con un tiempo válido. Para
entender los conceptos básicos para trabajar con bases de datos temporales, acudimos a (Chen
et.al [3]; Jensen et. al, [17]; Padmanabhan et. al, [24]; Povinelli et. al, [26,27]; Ramamritham et. al,
[28]; Xiong et. al, [31])
Enfocándose sólo en la semántica (Jensen et al.,[18]) determinaron que los modelos
existentes, incluso los desarrollados por ellos, eran demasiado complicados. Entonces crearon un
modelo muy simple, Modelo Conceptual Bitemporal de Datos (Bitemporal Conceptual Data Model
– BCDM), cuyo objetivo es capturar cuándo los hechos son válidos en la realidad (tiempo válido) y
cuaádo son almacenados en la base de datos (tiempo de transacción). La terminología
“conceptual” es usada sólo para enfatizar el uso del modelo en el diseño y como base de un
lenguaje de consultas.
El BCDM emplea el mismo modelo para los dos dominios de tiempo (válido y de
transacción): una secuencia finita de cronos. Un crono es la más corta duración de tiempo
soportada por una base de datos temporal, es una unidad de tiempo no descomponible, un sub -
intervalo de la línea de tiempo real, de duración fija. Puede estar medido en segundos, en días, en
años, etc, dependiendo de las necesidades particulares de los datos procesados. En términos
matemáticos, esta secuencia de cronos es representada por una secuencia finita de números
naturales.
Un intervalo de tiempo es definido como el tiempo entre dos instantes, un instante de inicio
y otro de fin. Un intervalo de tiempo es representado por una secuencia de cronos consecutivos,
donde cada crono representa todas las instancias que ocurren durante la duración del mismo.
También se puede representar una secuencia de cronos, simplemente por el par de cronos inicial y
final. La unión de estos intervalos se denomina elemento temporal.
En este modelo conceptual, una tupla (A
1
, A
2
, ...., A
n
| t
b
) consiste en un número de
atributos A
1
, A
2
, ...., A
n
, asociados con una marca de tiempo bitemporal t
b
.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 14 -

Nombre Departamento
asignado
T
Tomás Compras {(5,10),..., (5,15),...,(9,10),...,(9,15),
(10,5),...,(10,20),...(14,5),...(14,20),
(15,10),...,(15,15),....,(19,10),...,(19,15)}
Tomás Ventas {(UC,10),..., (UC,15)}
Diego Compras {(UC,25),..., (UC,30)}

Figura 3.1

Esta tabla muestra la marca de tiempo T como una secuencia de cronos bitemporales. Se
usan números enteros como componentes de las marcas de tiempo, cada entero representa una
fecha (por ejemplo, el entero 15 representa el día 15/01/04).
Cada par (c
t
, c
v
) representa un crono bitemporal donde c
t
es el tiempo de transacción y c
v

el tiempo válido.
Para la tupla (Tomás – Compras) las marcas de tiempo incluyen los cronos (5,10), (5,11)
hasta (5,15) y así sucesivamente. Esto significa que cuando el tiempo de transacción está entre 5
y 9, el tiempo válido está entre 10 y 15, lo mismo para los otros intervalos.
El valor especial UC (Until Changed – Hasta que cambie) , significa que esa tupla es
todavía válida en la base de datos.

3.1.1 Combinación y Eliminación de Información repetida

En el modelo conceptual BCDM se observa que existe una cierta flexibilidad en la
representación de las tuplas.
Existen dos transformaciones que pueden cambiar la forma de ver los datos sin afectar los
resultados de las consultas que se hacen a la base de datos (Jensen et al.,[18]).
La primera transformación se denomina Combinación. Significa que si dos tuplas, con los
valores de atributos explícitos iguales, están temporalmente superpuestas o son temporalmente
adyacentes, se pueden juntar en una sola tupla. Esta transformación permite reducir el número de
tuplas necesarias para representar una relación bitemporal, útil, por ejemplo, si se desea optimizar
el espacio físico de la base de datos.
Esta transformación se puede aplicar tanto para el tiempo válido como para el tiempo de
transacción.
A continuación se muestra gráficamente esta transformación. Cada rectángulo representa
un intervalo de tiempo. V es el dominio del tiempo Válido y T el de tiempo de transacción.
La Figura 3.2 muestra cómo los rectángulos se pueden combinar cuando los tiempos de
transacción son adyacentes (a) o los tiempos válidos son adyacentes (c).


V V V





T T T
( a ) ( b ) ( c )

Figura 3.2
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 15 -
Para introducir la otra transformación, antes se debe indicar que una relación tiene
información repetida, si contiene dos tuplas distintas con valores equivalentes, o sea que los
valores de sus atributos explícitos (no temporales) son idénticos, y tienen marcas de tiempo
superpuestas en el tiempo. Esta transformación es empleada para eliminar información temporal
redundante, a expensas de agregar tuplas extras. Lo que hace es transformar dos tuplas con
valores equivalentes con superposición temporal, en tres tuplas con valores equivalentes, en
donde no existe la superposición temporal.




V V V





T T T
( a ) ( b ) ( c )

Figura 3.3

En la Figura 3.3 se muestra un ejemplo de cómo esta transformación puede particionar las
regiones cubiertas por el tiempo válido o el de transacción.

3.2 Distintos esquemas de representación de datos temporales

Una relación bitemporal conceptual es estructuralmente simple; es un conjunto de hechos
asociados con un conjunto de cronos bitemporales. Pero este modelo conceptual es sólo a nivel
del diseño, precisamente por eso es conceptual. Para representar este modelo en una base de
datos real existen muchas formas distintas, enumeradas en (Jensen et al., [19]).
A continuación se enumeran algunos esquemas de representación. En los mismos se
utilizarán las siguientes notaciones:

• R para denotar un esquema de relación.
• A representa el conjunto de todos los atributos A
i
, 1 ≤ i ≤ n de la relación
• x, y , z se usa para las tuplas, y la notación x[A
i
] denota el A
i
-ésimo atributo de x.


3.2.1 Tupla con marca de tiempo de Snodgrass

En este esquema , se representa R de la siguiente forma:

R = (A
1
, A
2
, ... , A
n
, T
i
, T
f
, V
i
, V
f
)

Los atributos adicionales T
i
, T
f
, V
i
, V
f
son valores atómicos temporales conteniendo cronos
de inicio y fin del tiempo de transacción y cronos de inicio y fin del tiempo válido.

El ejemplo conceptual de la Figura 3.1 se representaría de la siguiente forma:


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 16 -
Nombre Departamento
asignado
Ti Tf Vi Vf
Tomás Compras 5 9 10 15
Tomás Compras 10 14 5 20
Tomás Ventas 20 UC 10 15
Diego Compras 20 UC 25 30

Figura 3.4


3.2.2 Esquema acumulativo de Jensen

La principal diferencia entre este esquema y el anterior es que las tuplas no pueden ser
modificadas, una vez que se agregaron a la base de datos no se puede modificar su contenido.
Sólo se pueden agregar más tuplas.
En este esquema se representa R de la siguiente forma:

R = (A
1
, . . ., A
n
, V
i
, V
f
, T, Op)

Donde T indica el tiempo de transacción en que la tupla es almacenada en la base de
datos. El atributo Op puede tomar el valor I (Insert - Insertar) o D (Delete - Eliminar), para cuando
se quiere representar el agregado o la eliminación de la tupla.
El ejemplo conceptual de la Figura 3.1 se representaría de la siguiente forma:

Nombre Departamento
asignado
Vi Vf T Op
Tomás Compras 10 15 5 I
Tomás Compras 10 15 10 D
Tomás Compras 5 20 10 I
Tomás Compras 5 20 15 D
Tomás Compras 10 15 15 I
Tomás Compras 10 15 20 D
Tomás Ventas 10 15 20 I
Diego Compras 25 30 20 I

Figura 3.5

3.2.3 Atributo con marca de tiempo de Gadia

En este esquema se representa R de la siguiente forma:

R = ( { ( [ T
i
, T
f
] x [ V
i
, V
f
] A
1
)}, . . . , {( [T
i
,T
f
] x [V
i
, V
f
] A
n
)} )

donde cada tupla está compuesta de n conjuntos. Cada elemento del conjunto tiene tres
partes: el intervalo de tiempo de transacción [ T
i
, T
f
], el intervalo de tiempo válido [ V
i
, V
f
] y el
valor de un atributo.
El ejemplo conceptual de la Figura 3.1 se representaría de la siguiente forma:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 17 -

Nombre Departamento asignado
[5,9] x [10,15] Tomás [5,9] x [10,15] Compras
[10,14] x [5,20] Tomás [10,14] x [5,20] Compras
[15,19] x [10,15] Tomás [15,19] x [10,15] Compras
[20,UC] x [10,15] Tomás [20,UC] x [10,15] Ventas
[20,UC] x [25,30] Diego [20,UC] x [25,30] Compras

Figura 3.6

3.2.4 Atributo con Marca de Tiempo de McKenzie

En este modelo una relación bitemporal es una secuencia de estados de tiempo válido
indexados por el tiempo de transacción.
En este esquema se representa R de la siguiente forma:

R = (T, VR) donde VR = (A
1
V
1
, . . . , A
n
V
n
)

El ejemplo conceptual de la Figura 31 se representaría de la siguiente forma:

T VR
0 vacío
5 { ( Tomás {10, ..., 15} , Compras {10,…,15} ) }
10 { ( Tomás {5, ..., 20} , Compras {5,…,20} ) }
15 { ( Tomás {1 0, ..., 15} , Compras {10,…,15} ) }
20 {( Tomás {10, ..., 15},Ventas {10,…,15} ) , ( Diego {25, ..., 30} , Compras {25,…,30} )}

Figura 3.7

3.2.5 Tupla con marca de tiempo de Ben-Zvi

En este modelo cada tupla de atributos explícitos tiene 5 atributos temporales. Aquí se
representa R de la siguiente forma:

R = (A
1
, . . . , A
n
, T
ie
, T
ir
, T
fe
, T
fr
, T
d
)

En la tupla, el valor del atributo T
ie
(inicio efectivo) es el tiempo cuando los atributos
explícitos comienzan a ser verdaderos. El valor T
ir
(inicio registro) indica cuando el valor T
ie
fue
almacenado. Similarmente, el valor T
fe
(fin efectivo) indica cuando la información almacenada deja
de ser verdadera y T
fr
(fin registro) contiene el tiempo cuando el valor T
fe
fue almacenado. El último
atributo implícito Td (deletion – eliminación) indica el tiempo cuando la información de la tupla fue
lógicamente borrada de la base de datos.
El símbolo “-“ en el campo Td indica que la tupla contiene información actual.
El ejemplo conceptual de la Figura 3.1 se representaría de la siguiente forma:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 18 -

Nombre Departamento
asignado
Tie Tir Tfe Tfr Td
Tomás Compras 10 5 15 5 10
Tomás Compras 5 10 20 10 15
Tomás Compras 10 15 15 15 20
Tomás Ventas 10 20 15 20 -
Diego Compras 2 20 30 20 -

Figura 3.8



3.3 Modelo de representación de datos para clustering temporal

El objetivo del clustering temporal es realizar el proceso de clustering sólo teniendo en
cuenta los atributos espaciales (utilizando algún algoritmo convencional), pero para distintos
momentos de tiempo (dato aportado por los atributos temporales). Esto nos permite ver cómo
varían los clusters durante el transcurso del tiempo.
Es preciso determinar cuál es el formato más adecuado que deben tener los datos de
entrada para obtener los mejores resultados al aplicar el algoritmo de clustering temporal.
Estos datos provienen de una base de datos temporal. Conceptualmente se puede
representar a los datos con el modelo BCDM de (Jensen et al.,[18]), pudiendo aplicarles las
transformaciones de combinación y eliminación de información repetida.
De los cinco esquemas físicos para representar los datos propuestos por (Jensen et al.,
[19]), se seleccionó la Tupla con marca de tiempo de Snodgrass para obtener la forma de
representar los datos a los que se les aplicará el clustering temporal.
Se utilizó el siguiente modelo:

R = (A
o
, A
1
, A
2
, ... , A
n
, V
i
, V
f
)

donde
• A
o
:es el atributo que identifica al objeto, es el que se utiliza para determinar cómo el objeto
cambia a través del tiempo.
• A
1
, A
2
, ... , A
n
: son los atributos explícitos del objeto, pueden ser categóricos o numéricos.
• V
i
, V
f
: es el tiempo válido de inicio y de fin. El intervalo durante el cual son verdaderos en
el mundo real los atributos mencionados.

Sólo se utiliza el tiempo válido porque es el que interesa al proceso de clustering, ya que
se estudia cómo varían los objetos en la realidad. En el caso específico que se quieran agrupar los
datos según el momento en que fueron almacenados en la base de datos, se deben reemplazar V
i
,
V
f
por los respectivos tiempos de transacción, pero sólo se trabaja con un dominio de tiempo.

3.4 Intervalos de tiempo a analizar

Un proceso de clustering temporal abarca cierto período de tiempo, por ejemplo, un año
calendario (desde Enero hasta Diciembre). Un intervalo es un subconjunto de ese período de
tiempo. El algoritmo de clustering divide el período total de tiempo en T subconjuntos o intervalos.
La duración de estos intervalos se calcula teniendo en cuenta el crono (que es la mínima unidad de
medida utilizada para este proceso). El crono lo determina la unidad con que están almacenados
los rangos de tiempo válido de las tuplas.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 19 -
Las medidas disponibles en principio, son: segundos, minutos, horas, días, meses y años.
Por ejemplo, en el caso anterior el crono a utilizar sería el “mes”. Entonces el período
completo se vería como 12 meses, y al dividir por T=12 se analizarían intervalos de 1 mes.
Es importante determinar el crono para lograr efectividad en las cuentas, ya que hacer la
cuenta del ejemplo en segundos implicaría números muy grandes que pueden producir un
desbordamiento de memoria. Otro caso: si el período total a observar es cuestión de segundos,
medirlo en años implicaría una pérdida de precisión enorme.
Una vez determinada la unidad de medida, el período total y la cantidad de intervalos que
se desean analizar nos enfrentamos a que los rangos de tiempo válido definidos para cada tupla
no necesariamente coinciden con los intervalos que se desean analizar. Es aquí donde se acudió a
los conceptos de combinación y eliminación de información repetida para obtener tuplas cuyos
rangos de tiempo válido coincidan totalmente con los intervalos a analizar.
Existen dos casos en los que será necesario aplicar alguna transformación a las tuplas:

1) Las tuplas cuyo rango de tiempo válido no está contenido íntegramente en un intervalo a
analizar se deberán particionar.

En la Figura 3.9 se muestra gráficamente cuál sería este caso.




Objeto1

Objeto2


T1 T2 Tiempo
(Intervalos a analizar)
Figura 3.9

El eje horizontal indica el tiempo. Con rojo están separados los intervalos de tiempo que se
desean analizar, o sea que en este caso se desea realizar el clustering para el intervalo T1 y
compararlo con el clustering para el intervalo T2.
Cada segmento azul representa una tupla del mismo objeto, pero para distintos rangos de
tiempo válido. Idem para cada segmento verde.
Como se puede observar, las tuplas del Objeto 1 están íntegramente en un intervalo de
tiempo, por lo que en estos casos no sería necesario aplicar ninguna transformación.
En cambio, la segunda tupla del Objeto 2, tiene un rango de tiempo válido que ocupa parte
de los dos intervalos a analizar. En esto caso lo que se hace es dividir la tupla en dos, cada una
con un rango de tiempo válido contenido en cada uno de los intervalos a analizar (transformación
similar a la de eliminación de información repetida).
El resultado de hacer esta transformación se observa en la Figura 3.10.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 20 -



Objeto1

Objeto2


T1 T2 Tiempo
(Intervalos a analizar)
Figura 3.10

La Figura 3.10 muestra que ya no existen tuplas cuyos rangos de tiempo estén
compartidos entre distintos intervalos a analizar. Pero este tampoco es el caso ideal, ya que
existen dos tuplas del Objeto 2 para el mismo intervalo de tiempo (T1) y es necesario contar sólo
con una que represente a ese intervalo.

2) Lo que se realiza en este caso es una transformación similar a la combinación explicada
anteriormente. Si todos los atributos explícitos (o sea, los no temporales), son iguales en
ambas tuplas, se transforman las mismas en una sola, donde los atributos explícitos son
los de cualquiera de las tuplas y cuyo rango de tiempo válido es la suma de los rangos de
las tuplas originales.

Para el caso en que las tuplas no posean los mismos atributos explícitos se calculará el
“promedio” de cada atributo, para obtener el valor de dicho atributo en la tupla resultante.

• Si los atributos son numéricos: el “promedio” es la mediana (median), que consiste en
ordenar todos los valores, para obtener el valor central (si la cantidad de valores es impar)
o el promedio de los valores centrales (si la cantidad es par).

• Si los atributos son categóricos: el “promedio” es la moda (mode) que es simplemente el
valor más frecuente. Si todos los valores tienen la misma frecuencia se tomará cualquiera
de dichos valores.

El resultado de combinar las tuplas se observa en la Figura 3.11. Ahora existe una única
tupla contenida exclusivamente en cada intervalo a analizar, por lo que se puede aplicar el proceso
de clustering temporal. Como se observa, no es necesario que el rango de tiempo válido tenga la
misma duración que el intervalo de tiempo a analizar, sólo basta con que esté contenido
íntegramente. También es importante aclarar que la combinación no necesariamente se realiza
entre dos tuplas, sino que puede ser entre cualquier cantidad.




Objeto1

Objeto2


T1 T2 Tiempo
(Intervalos a analizar)
Figura 3.11


Mientras mayor sea la cantidad de tuplas divididas o combinadas, la exactitud del proceso
de clustering va decayendo, ya que mediante estas operaciones se pierde un poco el sentido de la
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 21 -
realidad. Lo ideal en este caso es cambiar la longitud del intervalo de tiempo a analizar de forma
que se ajuste lo mejor posible a los rangos de tiempo válido de todas las tuplas. Para permitir este
análisis, cada vez que se combine o divida una tupla, se mostrará un informe de las
transformaciones realizadas, para poder corregirlas y minimizarlas.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 22 -
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 23 -





4 Implementación








La implementación del Clustering Temporal se divide en dos partes. Una aplicación
implementada en Java, denominada Weka (Ian et al,[16]), que es una herramienta para Data
Mining, en la que se agregaron funciones específicas para realizar el proceso de Clustering
Temporal. Y otra aplicación, implementada en Matlab, que se utiliza para analizar gráficamente los
resultados del proceso de clustering.

A su vez, el proceso de clustering temporal implementado en Java consta de 2 etapas:
• Generación del archivo temporal, donde se transforma un archivo de entrada en un
archivo que contemple el formato adecuado para procesarlo temporalmente.
• Clustering temporal, donde los datos de entrada se dividen en grupos o clusters, según
su unidad de tiempo.

4.1 Generación del Archivo temporal

El algoritmo de clustering temporal está implementado en WEKA, por lo que el archivo de
entrada al proceso de clustering (*.arff) debe cumplir con las siguientes pautas:

• Indicar el nombre de la relación, precedido por los caracteres @relation
• Listar nombre y tipo de datos de los atributos.
Los atributos pueden ser:
o Categóricos: son valores discretos.
Nominales: pueden ser descripciones, nombres, por ejemplo “Sexo”, que
puede ser Femenino o Masculino.
Ordinales: son categóricos, pero con cierto orden, por ejemplo: “junior,
semi senior, senior”
o Numéricos: reales o enteros. Por ejemplo Edad, Ingresos, etc.

Si el atributo es categórico, se deberán indicar todos los valores posibles del mismo.
• Listar los valores de los atributos separados por coma (,), precedidos por los caracteres
@data

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 24 -
Ejemplo de archivo arff:


@relation 'cpu'

@attribute vendor {adviser,amdahl,dec,microdata,prime,sperry,wang}
@attribute MYCT real
@attribute MMIN real
@attribute MMAX real
@attribute CACH real
@attribute CHMIN real
@attribute CHMAX real
@attribute class real

@data
adviser,125,256,6000,256,16,128,199
amdahl,29,8000,32000,32,8,32,253
amdahl,29,8000,32000,32,8,32,253
dec,29,8000,32000,32,8,32,253
wang,29,8000,16000,32,8,16,132
prime,26,8000,32000,64,8,32,290
microdata,23,16000,32000,64,16,32,381
sperry,23,16000,32000,64,16,32,381
dec,23,16000,64000,64,16,32,749

Figura 4.1

Para cumplir con las condiciones de archivo temporal, el archivo arff además debe poseer:
• Un atributo que indique Fecha de Inicio de validez del registro, la misma debe tener el
formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. Por ejemplo “2004-12-01
21:35:00”
• Un atributo que indique Fecha de Fin de validez del registro, la misma debe tener el
formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. Por ejemplo “2004-12-05
21:35:00”
• Un atributo que sea un ID único, que identifique al registro (puede haber más de un
registro para el mismo ID, aunque deben tener distintas fechas)
• Uno o más atributos (numéricos o categóricos) que se compararán para realizar el
clustering.


El orden de los atributos (temporales o no) puede ser cualquiera, pero debe ser el mismo
para todas las tuplas. Además, a fin de determinar cuál es el atributo identificatorio y cuáles son los
temporales, se pide que su orden se ingrese como parámetro del algoritmo de clustering temporal.
Otro parámetro fundamental para el algoritmo es la cantidad de intervalos que se desean
analizar.
A este archivo se le aplica un filtro que transforma los rangos de fechas en unidades
temporales (intervalos) según los parámetros especificados (cantidad de intervalos, crono, etc.).
Este filtro combina o separa los registros según sea necesario, cómo se indicó en la sección
anterior.


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 25 -
4.2 Clustering temporal

4.2.1 K-D-Median

La idea de todos los algoritmos de particionamiento es encontrar el punto mínimo de una
función FW, calculada como la sumatoria ponderada de las distancias de todos los individuos al
centroide. El método K-means, que utiliza la Distancia Euclídea al Cuadrado se enfoca en
minimizar la función:


=
=
n
i
j i i
KMeans
C s REP s Euclid C FW
1
2
]) , [ , ( . ) ( ω

Para el caso de los métodos basados en la distancia Euclídea (métodos de Mediana), la
función a minimizar es:

=
=
n
i
j i i C s REP s Euclid C FW
1
]) , [ , ( . ) ( ω


Donde:
• S = {s
1
,s
2
,....,s
n
} es un conjunto de n ítems en un espacio real D-dimensional.
• El peso ω
i
> 0 refleja la relevancia de la observación s
i
y

=
− =
D
i
i i y x y x Euclid
1
2
| | ) , (
• C = {c
1
,c
2
,....,c
k
)} es el conjunto de k centroides de los clusters.
• REP[s
i
,C] es el punto en C más cercano s
i


O sea que si buscamos los puntos representativos para el cluster Cj = {x
1
,x
2
,...,x
nj
}
debemos encontrar el mínimo para esta función:

∑ ∑
= =
− − = =
j j n
i
i
T
i i
n
i
i i x x x x x x Euclid x FW
1 1
) .( ) ( . ) , ( . ) ( ω ω

El gran problema de los métodos de mediana es que el gradiente de la función FW(x) no
está definido para x=x
i
, como se desprende de la siguiente fórmula:
( ) ( ) ( )
( ) ( ) ( ) ( ) ( )
∑ ∑
∑ ∑
= =
= =
− −
− − −
=
− −
− − −
=
|
|
¹
|

\
|
− + + − + − ∇ =
|
|
¹
|

\
|
− − ∇ = ∇
j j
j j
n
i i
T
i
i i i
i
n
i i
T
i
i i i
i
n
i
i i i
i
n
i
i
T
i i
x x x x
x x x x x x
x x x x
x x x x x x
x x x x x x x x x x x FW
1
dim dim 2 2 1 1
1
dim dim 2 2 1 1
1
2
dim dim
2
2 2
2
1 1
1
) .( ) (
,..., ,
.
) .( ) ( . 2
. 2 ,..., . 2 , . 2
.
... . ) .( ) ( . ) (
ω ω
ω ω

Como se observa de la última fórmula, para todos los puntos x = x
i
el divisor se hace 0, por
lo que el gradiente no está definido.
Este problema no se presenta en el algoritmo Kmeans, ya que la minimización de FW en
este caso es extremadamente sencilla, como se muestra en el siguiente desarrollo:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 26 -
( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )


∑ ∑
∑ ∑
=
=
= =
= =
= ⇔ = ∇ ⇒
− − − = − − −
=
|
|
¹
|

\
|
− + + − + − ∇ =
|
|
¹
|

\
|
− − ∇ = ∇
j
j
j j
j j
n
i
i
n
i
i
i
KMeans
n
i
i i i
i
n
i
i i i
i
n
i
i i i
i
n
i
i
T
i i
KMeans
x
x x FW
x x x x x x x x x x x x
x x x x x x x x x x x FW
1
1
min min
1
dim dim 2 2 1 1
1
dim dim 2 2 1 1
1
2
dim dim
2
2 2
2
1 1
1
.
0 ) (
,..., , . 2 . . 2 ,..., . 2 , . 2 .
... . ) .( ) .( ) (
ω
ω
ω ω
ω ω

Esta simplicidad posiciona al Kmeans como el algoritmo óptimo en cuanto a velocidad de
procesamiento. Sin embargo, como ya se expresó, el uso de la distancia Euclídea al cuadrado le
quita sentido físico a los resultados si la distribución de individuos no es simétrica. Además lo hace
altamente sensible a individuos aislados, ya que la contribución de éstos a la función FW es
cuadrática en lugar de lineal. La figura 4.2 presenta en forma gráfica esta diferencia entre los
resultados de ambos métodos:

Figura 4.2


Como se observa, en una distribución no simétrica (la de la figura se obtuvo multiplicando
dos distribuciones uniformes [0,1] y multiplicando por 10 el resultado) el centroide obtenido por
Kmeans deja de representar al cluster, ya que aumenta considerablemente su amplitud
influenciado por los individuos aislados entre 8 y 10. El método de Mediana, sin embargo, arrojó un
centroide cercano al valor (2,2), representando así tanto al conjunto de valores medios como a los
valores pequeños que forman el aglomerado entre 0 y 1.
Esta gran limitación del Kmeans nos llevó a considerar otros algoritmos que sacrifiquen un
poco la velocidad de cálculo pero que arrojen valores utilizando un método de mediana.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 27 -
El método propuesto, k-D-Median, especificado en (Estivill-Castro,V et. al, [10]) resulta ser
el indicado para este proceso, ya que obtiene resultados basados en la mediana haciendo cálculos
altamente eficientes que reducen el tiempo de ejecución a valores comparables con el KMeans.
Resumidamente el k-D-Median funciona de la siguiente forma para hallar el centroide de
un cluster:

• Se encuentra la mediana discreta: La mediana continua es el punto que minimiza
la distancia Euclídea entre todos los individuos. La mediana discreta (o
simplemente mediana) es el punto que está más cercano a la mediana continua.
• El método más directo para buscar la mediana sería evaluar la función FW en
todos los puntos, y determinar en que punto es mínima pero para clusters muy
grandes este proceso es ineficiente y se hace imposible de usar.
• El método propuesto en k-D-Median tiene en cuenta que la función FW es
convexa. Entonces, si se obtiene para cualquiera de sus individuos una recta
normal a la función FW, se garantiza que los puntos cuyo producto escalar con
esta recta es negativo estarán fuera del hiperplano tangente a FW en dicho punto y
la función evaluada en ellos será mayor que la del punto seleccionado, por lo que
pueden ser excluidos del análisis. En particular si se elige el punto más cercano a
la media (centro de masa de la distribución) se garantiza que se filtrará
aproximadamente el 50% de los puntos en cada iteración. El método se repite en
forma iterativa hasta reducir la población de individuos a 6 o menos. Por último se
evalúa la función FW en cada uno de estos puntos y se encuentra el centroide.

Obtención de la recta normal: En la mayoría de los casos la recta normal de un campo
escalar (función que va desde R
n
R
1
, como es el caso de FW) se obtiene en forma directa a
partir de su gradiente.

) ( ) ( fn fn N −∇ =
En nuestro caso, como el gradiente de FW no está definido para los puntos del cluster la
solución no es tan directa. Sin embargo se puede definir una función llamada gradiente extendido
de la siguiente forma:

¦
¦
¹
¦
¦
´
¦

¦
)
¦
`
¹
¦
¹
¦
´
¦



= ∇
¬
¬
) ( . 0 ,
) (
1
1 max
FW(x)
) (
m
m
m
E
x FW
x FW
x FW
j
j
C x
C x


if
if


donde ( )
m m
x FW
¬
es la función FW excluyendo al punto X
m
del conjunto de valores.
Se demuestra en (Estivill-Castro,V et.al,[10]) que el gradiente extendido ) (FW
E
∇ es
normal al hiperplano tangente a FW para cualquier punto x. Esta propiedad permite utilizarlo para
filtrar los individuos que están de un lado u otro del mismo.

4.2.2 Implementación de k-D-Median

Se ha implementado una versión simplificada de este método en MatLab para verificar la
utilidad del método, y se han obtenido resultados satisfactorios.
Se ha realizado la comparación de cuánto se tarda en encontrar un centroide entre un
grupo de individuos, calculando el valor de la función FW punto por punto (Algoritmo estándar) y
utilizando el algoritmo k-D-median descrito anteriormente.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 28 -
Los resultados obtenidos fueron los siguientes:


Figura 4.3

A continuación se muestra gráficamente cómo va avanzando el algoritmo k-D-median para
encontrar el centroide:

Comparación algortimos clustering
3
7
33
150
615
0,5 1 2 4 5
0
50
100
150
200
250
300
350
400
450
500
550
600
650
100 200 500 1000 2000
Individuos
T
i
e
m
p
o

(
s
e
g
)
Estándar
k-D-Median
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 29 -
Distribución Inicial: En la Figura 4.4 se observa la distribución inicial de individuos sobre
la cual se quiere encontrar el punto más representativo (centroide).
El punto rojo es el centroide que deberá ser elegido. Este punto se calculó manualmente
para corroborar los resultados.
El punto verde es el centroide encontrado utilizando el algoritmo k-means (como se
observa está más influenciado por los puntos aislados)

Figura 4.4


Primera iteración: En la Figura 4.5 se traza la recta normal a la función y se descartan
todos los puntos que se excluyen del hiperplano tangente (azules). En la Figura 4.6 y 4.7 se
muestra el resultado de la segunda y tercera iteración.

Última iteración: En la Figura 4.8 se muestra el resultado final. Luego de filtrar todos los
individuos hasta obtener 6 o menos se procede a calcular el mínimo manualmente (lo cual es
sencillo en tan pocos elementos)
El punto rojo es el centroide hallado, el cual coincide con el encontrado originalmente.














María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 30 -
Primera iteración:




Figura 4.5

Segunda Iteración:









Figura 4.6


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 31 -
Tercera Iteración:



Figura 4.7

Última Iteración:

Figura 4.8

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 32 -
4.2.3 Atributos Categóricos en K-D-Median
Si graficamos la función FW definida anteriormente para dos atributos numéricos, la misma
tiene el siguiente formato:





















Figura 4.9

Si se utilizan atributos categóricos la función FW pasa a estar definida como:

∑ ∑

= =
=
= ≠ + −
=
n
i AtNum j
AtCateg k
j j xi x
i C FW
1
ij) j ij j
2
x x si 0 , x x si 1 ( ) (
. ) ( ω

Esta función deja de ser convexa, ya que la distancia categórica es siempre 1 excepto para
x=x
i
, en la cual es 0. Un ejemplo de esta característica puede verse en la siguiente figura:



















Figura 4.10
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 33 -
Esta característica invalida el principio de funcionamiento del algoritmo K-D-Median, por lo
que hay que subsanar este impedimento para posibilitar el análisis de atributos categóricos. Hay
distintos trabajos que tratan de solucionar este conocido problema, uno de ellos es (Estivill-Castro,
[4]). Lo que se propone en este trabajo es reemplazar los atributos categóricos por un conjunto de
tuplas numéricas, de forma tal que la distancia entre dichas tuplas sea 1 si son distintas o 0 si son
iguales (esta es la forma en que se tratan los atributos categóricos).
Para encontrar el conjunto de puntos cuya distancia entre sí sea siempre 1, se procedió a
desarrollar un algoritmo que resuelva el conjunto de ecuaciones. Se observó que si la cantidad de
atributos diferentes es n, la cantidad de dimensiones necesarias es siempre n-1. Además, se
observó que la posición de cada punto depende sólo de los puntos anteriores, por lo que se pudo
calcular las posiciones en forma iterativa. A continuación se detalla resumidamente el proceso de
búsqueda de estos puntos:

• Para dos atributos, la obtención de los puntos es directa: (½) y (– ½).


Figura 4.11

• Para tres atributos, los dos primeros quedan ( ½,0) y (- ½,0), y el tercero se obtiene
a partir de un sistema de dos ecuaciones con dos incógnitas, resultando en
(0,
2
2 / 1 1− ).

Figura 4.12

• Para cuatro atributos, los tres primeros aumentan con ceros su tercer dimensiòn, y
el cuarto se completa con (0,
|
|
|
¹
|

\
|
|
|
¹
|

\
|





2
2 2
2 / 1 1 . 2
1
4
3
. 2
4
3
,
2 / 1 1 . 2
1
4
3
. 2
, 0 :

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 34 -

Figura 4.13


Repitiendo estos cálculos, se encuentra que para cada nueva dimensión se van generando
sistemas de ecuaciones, cada vez con más incógnitas. Sin embargo, se encontró que con un
sistema iterativo que vaya calculando cada dimensión a partir de sus anteriores, aparecen ciertas
reglas que nos permitieron desarrollar la siguiente matriz:
Siendo n los posibles valores de un atributo categórico, se generan n tuplas de dimensión
(n-1), de la siguiente forma:

Siendo a
ij
el valor de la matriz presente en la fila i, columna j.
La particularidad de los vectores así definidos es que la distancia entre dos de ellos es
siempre 1. Cada valor categórico entonces se reemplaza por uno de estos vectores, resultando así
un conjunto numérico de X cuya función de FW (puramente numérica) evaluada en cada punto
será igual a la función de FW (numérica y categórica) del dominio original. De esta manera se
puede obtener la mediana discreta por el método K-D-Median propuesto, y aplicar el resultado al
dominio original de valores.

4.2.4 Algoritmo k-D-Median Temporal

Este algoritmo ejecuta los siguientes pasos:

• Se reemplazan los atributos categóricos por atributos numéricos según la fórmula
anterior y se normalizan los valores numéricos (no así los categóricos, pues de la
forma en que se calcularon la distancia siempre será 0 o 1).
• Se dividen las instancias (o registros) del archivo de entrada, según su unidad
temporal (ya pasaron por el filtro principal).
• Se elige entre los individuos de cada unidad temporal (UT), tantos individuos como
clusters se desee obtener. Estos individuos serán los centroides originales.
[ ]
|
|
|
|
|
|
|
|
|
|
|
|
¹
|

\
|

− −




=
|
|
|
|
|
|
|
|
¹
|

\
|
− − −
− −
− −
− − −
∑ 2
) 2 (
2
) 2 )( 1 (
) 2 )( 1 (
2
) 3 )( 1 (
2
42
2
32
) 3 )( 1 ( 2 ) 1 (
2
42
2
32
32
2
32
2
11
4
3
2
1
2
1 ) ( 2
... 0
0 ... ... ... ... ...
0 0 ...
2
1 2
0
0 0 ... 0 1 0
0 0 ... 0 0
2
1
0 0 ... 0 0
2
1
...
n n n n
n n
n n
n n n x a
x
a a a
a a
a a
a
a
a
A
A
A
A
A
n
K
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 35 -
• Se calcula la distancia Euclídea de cada individuo respecto de los centroides. Dicho
individuo se asigna al cluster cuyo centroide esté más cercano (mínima distancia).
• Se toman los individuos de cada cluster, en cada UT, y se aplica el algoritmo k-D-
Median para obtener su nuevo centroide (mínimo de la función FW)
• Con los nuevos centroides se repiten los pasos 4 y 5 hasta que ningún individuo
cambie de cluster o los cambios sean recurrentes (por ej, un individuo que oscila entre
2 clusters)
• En este punto, se tiene la distribución final de cada cluster en cada UT. Ahora se
determina la relación entre los clusters entre distintos tiempos, según se explica en el
siguiente apartado.
• Por último, se genera un archivo con la distribución de los clusters obtenidos en cada
UT, sus centroides, e información adicional para calcular las estadísticas.

4.2.5 Relación entre clusters de distintos tiempos

Como se pudo observar, el algoritmo de clustering temporal aplica el algoritmo
convencional para cada intervalo de tiempo. De esto se obtiene una distribución de clusters en
cada intervalo, pero lo que no se sabe es si el cluster denominado “Cluster 1” en el primer intervalo
es el mismo “Cluster 1” en el segundo intervalo, porque el algoritmo da el número de orden de
cada cluster en forma totalmente aleatoria.













T1 T2

Figura 4.14
Por ejemplo, en la Figura 4.14 se puede observar que en el intervalo de tiempo T1,
el algoritmo armó ciertos clusters que numeró 1, 2 y 3. En el intervalo T2, el algoritmo armó
clusters similares. Intuitivamente se puede decir que el cluster 1 evolucionó en el tiempo en el
cluster 2, a pesar que se llaman diferentes. Lo mismo sucede con el cluster 2 y 3, y 3 y 1
respectivamente. Entonces, una función importante que debe cumplir el algoritmo de Clustering
Temporal, es determinar cuál es la evolución de los clusters, sin basarse en el nombre u orden que
se le dio.
Por lo tanto, para saber cómo se llamó a cada cluster en los distintos intervalos de tiempo,
hay que seguir la trayectoria del mismo.
Para hacer esto, primero se cuentan cuántos individuos pasaron de cada cluster en el
primer intervalo a cada cluster en el segundo intervalo. Luego se computan todas las
combinaciones posibles de pasar de un cluster a otro al cambiar de tiempo y se encuentra la
combinación que maximiza la cantidad de individuos que se quedaron en el mismo cluster. Este
análisis permite garantizar que se mantiene el número máximo de individuos que permanecen en
sus clusters originales.

1
2
3 2
3
1
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 36 -
4.2.6 Análisis de Resultados

La aplicación implementada en Matlab analiza los resultados obtenidos a partir del archivo
generado en la aplicación de clustering temporal. La misma posee las siguientes opciones:
• Cluster 2 D: Sólo se habilita si el archivo de entrada tiene 2 atributos. Se muestra
gráficamente la representación de todos los clusters en cada UT.
• Cluster 2 D Tiempo: Sólo se habilita si el archivo de entrada tiene 2 atributos. Se
muestra gráficamente la evolución de cada cluster a través de las distintas UT.
• Cluster 3 D: Sólo se habilita si el archivo de entrada tiene 3 atributos. Se muestra
gráficamente la representación de todos los clusters en cada UT.
• Cluster 3 D Tiempo: Sólo se habilita si el archivo de entrada tiene 3 atributos. Se
muestra gráficamente la evolución de cada cluster a través de las distintas UT.
• Análisis por Atributo: esta opción está habilitada siempre. Muestra atributo por atributo,
la evolución del mismo a través del tiempo, mediante un gráfico de líneas, y a su vez
compara el mismo atributo en los distintos clusters.
• Estadísticas: Este es un gráfico de barras, que muestra cuántos individuos cambiaron
de cluster en el pasaje de un tiempo al siguiente. Cluster Inicial muestra la cantidad de
individuos para cada cluster en un determinado tiempo, y Cluster Final indica la
cantidad de individuos que tienen esos clusters en el tiempo siguiente.
• Individuos Perdidos: Muestra en un gráfico de barras, los individuos que pertenecían a
algún cluster en un tiempo dado, y no pertenecen a ninguno en el tiempo siguiente
debido a que no se cuenta con información sobre ellos en ese período.

Cada pantalla permite editar los gráficos, agregar textos o etiquetas, ampliar o reducir las
imágenes, rotar las figuras e imprimir o guardar los resultados.


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 37 -





5 Experimentación








5.1 Casos de prueba

El INDEC, Instituto Nacional de Estadística y Censo realiza una encuesta semestral
denominada Encuesta Permanente de Hogares (EPH). Esta encuesta es un programa nacional e
intercensal que se desarrolla en INDEC desde 1972 y conjuntamente con las DIRECCIONES
PROVINCIALES DE ESTADISTICA (DPE) desde 1974. Tiene como fin relevar información
socioeconómica del país.
La forma de realizar la encuesta es la siguiente: se toma una muestra de cierta cantidad de
hogares, se les asigna un código único a cada uno, y eso es lo que forma lo que en el INDEC
denominan onda. En el período siguiente (se realiza 2 veces por año), se remueve el 25% de los
hogares de la muestra y se incorpora un 25% de hogares que todavía no se encuestaron. En el
tercer período se vuelve a remover un 25% de la población original, y así sucesivamente. Al
finalizar cuatro ciclos u ondas, un mismo hogar fue encuestado cuatro veces.
Para probar el algoritmo de Clustering Temporal, se tomaron distintas variables de distintos
muestreos. A continuación se detallan los juegos de datos utilizados para probar el algoritmo, los
resultados obtenidos con el software Weka y la visualización de los mismos a través de Matlab.

5.1.1 Consideraciones generales

• Cuando se detallan los atributos, se realiza una introducción sobre el tipo de datos.
Cuando se hace referencia a %Perdidos, se indica cual es el porcentaje de registros
sobre los cuales no se cuenta con información sobre esos atributos. En el archivo, que
un valor del atributo esté perdido (missing) se representa con un signo de pregunta (?)
• Cuando se muestran los resultados de Weka, los mismos se imprimen tal cual se
muestran en la pantalla de salida del programa (respetando formato y nombres en
inglés) para que sea más fácil la identificación de los ejemplos.
• Cuando se analizan los resultados con Matlab, se puede hacer un seguimiento de
atributo por atributo, pero sólo se mostrarán impresos aquellos que aporten algún dato
significativo al estudio del caso.


5.1.2 Caso de prueba 1

Nombre del archivo: INDEC_1996-1997
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 38 -
Cantidad de Registros: 2868
Cantidad de Atributos:12


Detalle de atributos

Nombre Tipo Detalle %Perdidos Valores
distintos
ID Nominal Código único que identifica a
la vivienda a través de las 4
ondas.

0% 717
Fecha Inicio Fecha 0% 4
Fecha Fin Fecha
Fechas de Inicio y Fin de
validez del registro. Al tomar
4 ondas los rangos de
fechas válidos son:
*01/01/1996 al 01/07/1996
*02/07/1996 al 31/12/1996
*01/01/1997 al 01/07/1997
*02/07/1997 al 31/12/1997


0% 4
Tipo Vivienda Nominal 1:Casa
2:Departamento
3:Vivienda en lugar de
trabajo
4:Inquilinato
5:Hotel o Pensión
6:Vivienda no destinada a
fines habitacionales.
7:Vivienda en villa
8:Otro

19% 6
Cant.
Habitaciones
Numérico Cantidad de habitaciones
que tiene la vivienda

19% 11
Agua Nominal Si tiene o no instalación de
agua.
1:SI
2:NO

19% 2
Electricidad Nominal Si tiene o no instalación de
electricidad.
1:SI
2:NO

19% 2
Baño Nominal Si tiene o no instalación de
baño
1:Tiene de uso exclusivo
2:Tiene de uso compartido
3:No tiene baño

19% 3
Tenencia
Vivienda
Nominal Régimen de tenencia de la
vivienda:
1:Propietario de la vivienda y
el terreno.
2:Propietario de la vivienda
solamente.
3:Inquilino de la vivienda.
4:Ocupante con relación de
20% 6
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 39 -
dependencia.
5:Ocupante Gratuito
8:Otros

Materiales
Vivienda
Nominal Tipo de materiales de la
vivienda (predominante de
paredes externas):
1:Mampostería(ladrillo,
bloques, paneles)
2:Madera
3:Metal o fibrocemento
(chapas, etc.)
4:Adobe
5:Chorizo, cartón o desechos
8:Otros


19% 6
Ingreso Familiar Numérico Monto de ingreso total
mensual del hogar.

15% 554
Ingreso Per
Capita
Numérico Monto de ingreso per cápita
mensual del hogar.

19% 705
Figura 5.1

Proceso de prueba

1) Se ejecuta el sistema WEKA. En la solapa de preproceso se carga el archivo
correspondiente.


2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros:
• Crono: Día (3)
• Número de Intervalos: 4
• Posición Fecha Fin:2
• Posición Fecha Inicio: 1
• Posición ID: 0

Al terminar de filtrar, las fechas de inicio y fin se reemplazan por una unidad temporal cuyo
valor está entre 0 y 4. Los rangos de fechas que corresponden a cada unidad temporal se guardan
en el archivo IntervalosDeTiempo.txt y son los siguientes:


Intervalo de tiempo perteneciente a la unidad temporal 1
Desde: Mon Jan 01 00:00:00 ART 1996 Hasta: Mon Jul 01 00:00:00 ART
1996

Intervalo de tiempo perteneciente a la unidad temporal 2
Desde: Tue Jul 02 00:00:00 ART 1996 Hasta: Tue Dec 31 00:00:00 ART
1996

Intervalo de tiempo perteneciente a la unidad temporal 3
Desde: Wed Jan 01 00:00:00 ART 1997 Hasta: Wed Jul 02 00:00:00 ART
1997

Intervalo de tiempo perteneciente a la unidad temporal 4
Desde: Thu Jul 03 00:00:00 ART 1997 Hasta: Thu Jan 01 00:00:00 ART
1998
Figura 5.2
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 40 -


Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal


3) En la solapa de Cluster, se elige el algoritmo Temporal_k_d_Median con los siguientes
parámetros:

• Número de clusters: 3
• Modo de clustering: Use Training Set

El resultado de la corrida después de 4 segundos es el siguiente:


=== Run information ===

Scheme: weka.clusterers.Temporal_k_D_Median -N 3
Relation: INDEC-1996-1997_Temporal
Instances: 2868
Attributes: 11
Temp
ID
TipoVivienda
CantHabitaciones
Agua
Electricidad
Banio
TenenciaVivienda
MaterialesVivienda
IngresoFamiliar
IngresoPerCapita
Test mode: evaluate on training data


=== Clustering model (full training set) ===


Temporal_k_D_Median=====

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-0178 1 3.0 1 1 1 1 1 1150.00 575.00
Cluster 2 0.0 3-96-1-0671 1 3.0 1 1 1 1 1 500.00 166.67
Cluster 3 0.0 3-96-1-0020 2 3.0 1 1 1 1 1 900.00 300.00
Cluster centroids for temporal unit 2:
Cluster 1 1.0 3-96-1-1137 1 2.0 1 1 1 1 1 500.00 166.67
Cluster 2 1.0 3-96-1-0559 1 3.0 1 1 1 1 1 810.00 202.50
Cluster 3 1.0 3-96-1-0692 2 3.0 1 1 1 1 1 1000.00 333.33
Cluster centroids for temporal unit 3:
Cluster 1 2.0 3-96-1-0646 1 3.0 1 1 1 3 1 700.00 175.00
Cluster 2 2.0 3-96-1-1030 1 3.0 1 1 1 1 1 800.00 266.67
Cluster 3 2.0 3-96-1-0523 2 3.0 1 1 1 1 1 900.00 300.00
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 41 -
Cluster centroids for temporal unit 4:
Cluster 1 3.0 3-96-1-0615 1 3.0 1 1 1 3 1 700.00 233.33
Cluster 2 3.0 3-96-1-1030 1 3.0 1 1 1 1 1 800.00 266.67
Cluster 3 3.0 3-96-1-0523 2 3.0 1 1 1 1 1 900.00 300.00




=== Evaluation on training set ===


Temporal_k_D_Median ======

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-0178 1 3.0 1 1 1 1 1 1150.00 575.00
Cluster 2 0.0 3-96-1-0671 1 3.0 1 1 1 1 1 500.00 166.67
Cluster 3 0.0 3-96-1-0020 2 3.0 1 1 1 1 1 900.00 300.00
Cluster centroids for temporal unit 2:
Cluster 1 1.0 3-96-1-1137 1 2.0 1 1 1 1 1 500.00 166.67
Cluster 2 1.0 3-96-1-0559 1 3.0 1 1 1 1 1 810.00 202.50
Cluster 3 1.0 3-96-1-0692 2 3.0 1 1 1 1 1 1000.00 333.33
Cluster centroids for temporal unit 3:
Cluster 1 2.0 3-96-1-0646 1 3.0 1 1 1 3 1 700.00 175.00
Cluster 2 2.0 3-96-1-1030 1 3.0 1 1 1 1 1 800.00 266.67
Cluster 3 2.0 3-96-1-0523 2 3.0 1 1 1 1 1 900.00 300.00
Cluster centroids for temporal unit 4:
Cluster 1 3.0 3-96-1-0615 1 3.0 1 1 1 3 1 700.00 233.33
Cluster 2 3.0 3-96-1-1030 1 3.0 1 1 1 1 1 800.00 266.67
Cluster 3 3.0 3-96-1-0523 2 3.0 1 1 1 1 1 900.00 300.00

Clustered Instances

0 2868 (100%)


Figura 5.3


Al finalizar este proceso, se ha creado en el directorio de ejecución de WEKA, el archivo
INDEC-1996-1997_Temporal_C3_T4.csv. C3 indica que se realizaron 3 clusters. T4 indica que se
trata de 4 unidades temporales.

4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo INDEC-1996-
1997_Temporal_C3_T4.csv.

Las opciones Gráficos 2D y Gráficos 3D están deshabilitadas ya que estamos trabajando
con un número mayor de atributos.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 42 -


Análisis por Atributo

Como ya se observa en las tablas de resultados, hay algunos atributos que se mantienen
constantes a lo largo de los 4 períodos.

TipoVivienda: Para el Cluster 1 y Cluster 2, el atributo se mantiene constante con valor =
1 (Casa) a lo largo del tiempo. Para el Cluster 3, también se mantiene constante pero con valor=2
(Departamento).

En el gráfico la evolución se observa como líneas rectas a través del tiempo.

































Figura 5.4

Los atributos Agua, Electricidad, Banio, y MaterialesVivienda también se mantienen
constantes con valor = 1 (Sí tienen agua, electricidad y baño de uso exclusivo, y el material de la
vivienda es principalmente de mampostería), por lo que los gráficos son similares al anterior.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 43 -
CantHabitaciones: La cantidad de habitaciones de la vivienda se mantiene prácticamente
constante durante los distintos períodos con valor = 3, salvo en el momento 2 del Cluster 1, que
baja a 2.



Figura 5.5



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 44 -
TenenciaVivienda: Se observa que hay un grupo de gente que es propietaria de la
vivienda y el terreno (valor = 1) y esto se mantiene durante los 4 períodos. Pero hay un grupo
(Cluster 1) que en los primeros dos períodos es propietaria de la vivienda y en los dos períodos
siguientes es inquilino (valor = 3). Esto coincide con el análisis anterior donde hay una variación en
la Cantidad de Habitaciones.

Figura 5.6


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 45 -
IngresoFamiliar: El grupo de individuos perteneciente al Cluster 1 comienza con un
ingreso alto (alrededor de $1200), luego se observa un pico mínimo de $500 (probablemente por
desempleo), para luego estabilizarse en $700. Esa depresión se corresponde con los cambios en
la Tenencia de la Vivienda y en la Cant. De Habitaciones.
Los individuos del Cluster 2 comienzan abajo ($500) para luego subir un poco y
estabilizarse.
Y por últimos los individuos del Cluster 3 se mantienen bastante estabilizados a través de
los períodos.


Figura 5.7



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 46 -
IngresoPerCapita: El ingreso Per Capita sigue una trayectoria similar que el Ingreso Total
Familiar como se puede observar en el gráfico.

Figura 5.8



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 47 -
Estadísticas

A continuación se muestran los gráficos de barras que representan como fue el
intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos:
El análisis indica que entre el Tiempo 1, 2 y 3 existen severos traspasos de individuos
entre los Clusters 1 y 2, que en el tiempo final se estabilizan. Esto indica que estos clusters
comienzan siendo muy similares pero paulatinamente comienzan a evidenciar diferencias de
Ingresos que los sitúan en dos posiciones diferentes.
Se observa también que los períodos finales el número de individuos del Cluster 1
(representante del sector de menores recursos) es considerablemente inferior al del Cluster 2 (de
recursos promedios).



Figura 5.9


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 48 -

Figura 5.10



Figura 5.11





María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 49 -
Individuos Perdidos

En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que
pasan de un cluster a otro, pero se agregan los que no pasaron a ningún cluster, o sea, que en ese
período de tiempo, no se contaba con información para ese individuo. El motivo puede ser
simplemente que no haya querido responder a la encuesta.
En este gráfico se observa que un gran número de individuos no tienen información en el
Tiempo 2, y sí la vuelve a tener en los tiempos siguientes. Esto puede explicar los violentos
traspasos de individuos del Cluster 1 hacia otros clusters, ya que las condiciones originales de esta
población variaron considerablemente.



Figura 5.12

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 50 -

Figura 5.13



Figura 5.14




María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 51 -
Performance

Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos. En el
siguiente gráfico se muestra el tiempo que demora el proceso en finalizar. Como se puede
observar, hay muy poca variación de tiempo a medida que aumenta la cantidad de clusters.















Figura 5.15


5.1.3 Caso de prueba 2

Nombre del archivo: INDEC_1996-1997_2D (Son los mismos individuos que el caso anterior,
pero se tomaron sólo 2 atributos para permitir otro tipo de análisis)
Cantidad de Registros: 2868
Cantidad de Atributos:5


Detalle de atributos

Nombre Tipo Detalle %Perdidos Valores
distintos
ID Nominal Código único que identifica a
la vivienda a través de las 4
ondas.

0% 717
Fecha Inicio Fecha 0% 4
Fecha Fin Fecha
Fechas de Inicio y Fin de
validez del registro. Al tomar
4 ondas los rangos de
fechas válidos son:
*01/01/1996 al 01/07/1996
*02/07/1996 al 31/12/1996
*01/01/1997 al 01/07/1997
*02/07/1997 al 31/12/1997


0% 4
Ingreso Familiar Numérico Monto de ingreso total
mensual del hogar.

15% 554
Ingreso Per
Capita
Numérico Monto de ingreso per cápita
mensual del hogar.

19% 705
Figura 5.16

Performance INDEC 1996-1997
0
2
4
6
8
1 2 3 4 5 6
Tiempo (segundos)
N
º

C
l
u
s
t
e
r
s
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 52 -
Proceso de prueba

1) Se ejecuta el sistema WEKA. En la solapa de preproceso se carga el archivo
correspondiente.


2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros:
• Chronon: Día (3)
• Número de Intervalos: 4
• Posición Fecha Fin:2
• Posición Fecha Inicio: 1
• Posición ID: 0

Al terminar de filtrar, las fechas de inicio y fin se reemplazan por una unidad temporal cuyo
valor está entre 0 y 4. Los rangos de fechas que corresponden a cada unidad temporal se guardan
en el archivo IntervalosDeTiempo.txt y son los siguientes:


Intervalo de tiempo perteneciente a la unidad temporal 1
Desde: Mon Jan 01 00:00:00 ART 1996 Hasta: Mon Jul 01 00:00:00 ART
1996

Intervalo de tiempo perteneciente a la unidad temporal 2
Desde: Tue Jul 02 00:00:00 ART 1996 Hasta: Tue Dec 31 00:00:00 ART
1996

Intervalo de tiempo perteneciente a la unidad temporal 3
Desde: Wed Jan 01 00:00:00 ART 1997 Hasta: Wed Jul 02 00:00:00 ART
1997

Intervalo de tiempo perteneciente a la unidad temporal 4
Desde: Thu Jul 03 00:00:00 ART 1997 Hasta: Thu Jan 01 00:00:00 ART
1998

Figura 5.17


Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal

3) En la solapa de Cluster, se elige el algoritmo Temporal_k_d_Median con los siguientes
parámetros:

• Número de clusters: 4
• Modo de clustering: Use Training Set

El resultado de la corrida después de 4 segundos es el siguiente:



=== Run information ===

Scheme: weka.clusterers.Temporal_k_D_Median -N 4
Relation: INDEC-1996-1997-2D-Temporal
Instances: 2868
Attributes: 4
Temp
ID
IngresoFamiliar
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 53 -
IngresoPerCapita
Test mode: evaluate on training data


=== Clustering model (full training set) ===


Temporal_k_D_Median=====

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-0001 0.00 0.00
Cluster 2 0.0 3-96-1-0669 732.00 244.00
Cluster 3 0.0 3-96-1-0560 1600.00 400.00
Cluster 4 0.0 3-96-1-0618 305.00 152.50
Cluster centroids for temporal unit 2:
Cluster 1 1.0 3-96-1-0196 145.00 72.50
Cluster 2 1.0 3-96-1-0105 800.00 200.00
Cluster 3 1.0 3-96-1-0432 1500.00 500.00
Cluster 4 1.0 3-96-1-1039 430.00 215.00
Cluster centroids for temporal unit 3:
Cluster 1 2.0 3-96-1-0594 200.00 50.00
Cluster 2 2.0 3-96-1-0002 720.00 180.00
Cluster 3 2.0 3-96-1-0695 1300.00 433.33
Cluster 4 2.0 3-96-1-0183 220.00 220.00
Cluster centroids for temporal unit 4:
Cluster 1 3.0 3-96-1-0871 300.00 75.00
Cluster 2 3.0 3-96-1-0091 640.00 213.33
Cluster 3 3.0 3-96-1-0785 1570.00 392.50
Cluster 4 3.0 3-96-1-0608 700.00 350.00




=== Evaluation on training set ===

Temporal_k_D_Median ======

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-0001 0.00 0.00
Cluster 2 0.0 3-96-1-0669 732.00 244.00
Cluster 3 0.0 3-96-1-0560 1600.00 400.00
Cluster 4 0.0 3-96-1-0618 305.00 152.50
Cluster centroids for temporal unit 2:
Cluster 1 1.0 3-96-1-0196 145.00 72.50
Cluster 2 1.0 3-96-1-0105 800.00 200.00
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 54 -
Cluster 3 1.0 3-96-1-0432 1500.00 500.00
Cluster 4 1.0 3-96-1-1039 430.00 215.00
Cluster centroids for temporal unit 3:
Cluster 1 2.0 3-96-1-0594 200.00 50.00
Cluster 2 2.0 3-96-1-0002 720.00 180.00
Cluster 3 2.0 3-96-1-0695 1300.00 433.33
Cluster 4 2.0 3-96-1-0183 220.00 220.00
Cluster centroids for temporal unit 4:
Cluster 1 3.0 3-96-1-0871 300.00 75.00
Cluster 2 3.0 3-96-1-0091 640.00 213.33
Cluster 3 3.0 3-96-1-0785 1570.00 392.50
Cluster 4 3.0 3-96-1-0608 700.00 350.00



Clustered Instances

0 2868 (100%)


Figura 5.18


Al finalizar este proceso, se ha creado en el directorio de ejecución de WEKA, el archivo
INDEC-1996-1997-2D_Temporal_C4_T4.csv. C4 indica que se realizaron 4 clusters. T4 indica que
se trata de 4 unidades temporales.

4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo INDEC-1996-
1997_Temporal_C3_T4.csv.

Las opciones de Gráficos 3D están deshabilitadas ya que estamos trabajando sólo con dos
atributos.


Gráficos 2D

Este gráfico muestra para cada período (Tiempo) cómo es la distribución de los individuos
según sus atributos. Cómo se trata de sólo dos atributos se puede realizar un gráfico
bidimensional.
Por ejemplo, se selecciona el Cluster 4 y se observa el comportamiento del mismo a través
de los distintos tiempos. En un primer momento abarca cierto número de individuos, cuyas
características son Ingreso familiar entre $100 y $500 e Ingreso Per Cápita entre $100 y $400,
mostrando además que en cada hogar habitan no más de 3 personas, y en la mayoría de los
casos sólo una o dos. En la Figura 5.20 se muestra este cluster ampliado para poder estudiarlo
con mayor detalle.






María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 55 -















Figura 5.19

















Figura 5.20
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 56 -

En el Tiempo 2 (6 meses después), se observa que el que el Ingreso Familiar del Cluster 4
aumenta (entre $200 y $650) haciéndose comparable con los valores del Cluster 2. Por esta
razón, si bien mantiene la mayoría de sus individuos, cede los de menor ingreso al Cluster 1, y
adopta muchos de los del Cluster 2. Se observa también que aunque sigue siendo indicador de las
familias chicas, el número máximo de integrantes no se limita a 3 sino a 4, indicando que algunas
de las familias tienen un nuevo integrante. En la ampliación del cuadro (Figura 5.22), se observan
las 4 rectas que representan el número de integrantes según la relación entre Ingreso Total y Per
Capita.




























Figura 5.21

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 57 -






























Figura 5.22

En el Tiempo 3 (Figura 5.23), el Cluster 4 no varía significativamente pero se observa una
variación del Cluster 2 que pasa a representar a las familias más numerosas y de Ingreso limitado.
Cómo resultado de esto el Cluster 4 pasa a ser representativo de las familias de pocos miembros y
de recursos limitados (en todo momento las familias de altos recursos están representadas por el
Cluster 3).
En el Tiempo 4 (Figura 5.24) ,se observa un importante crecimiento económico en el
Cluster 4, que sigue siendo un fiel representante de las familias chicas. Al hacerse el Ingreso
Familiar comparable con muchos individuos del Cluster 3, estos pasan a formar parte del Cluster 4.






María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 58 -


























Figura 5.23




























Figura 5.24

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 59 -
Gráfico 2D Tiempo

Este gráfico provee información similar al gráfico anterior pero vista desde otro punto de
vista, se observa en un solo gráfico la evolución en el tiempo de un solo cluster.
También hay que tener en cuenta que la escala entre un gráfico y otro cambia según los
valores que se deseen graficar.
Por ejemplo, para el caso del Cluster 4 analizado anteriormente el gráfico se muestra en la
figura siguiente. Complementando el análisis anterior, se observa un aumento inicial en el Ingreso
Familiar, seguido de un enfoque del cluster en las familias con menor número de individuos
(mayoritariamente entre 1 y 2 integrantes), para culminar con aumento sustancial en el Ingreso
Familiar.


Figura 5.25






María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 60 -
Análisis por Atributo

IngresoFamiliar: Tanto los gráficos del Atributo 1 como los del Atributo 2 muestran que el
Cluster 1 es representativo del sector de menor Ingreso Familiar, el Cluster 2 y el Cluster 4
representan al sector de Ingreso Familiar limitado y el Cluster 3 a los que perciben mayores
ingresos.
Las tendencias temporales son crecientes en los Clusters 1 y 4 y no varían
significativamente en los dos restantes.

Figura 5.26








María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 61 -
IngresoPerCapita: En este gráfico se observa que aunque el Ingreso Familiar es mayor
en el Cluster 2 que en el 4, al convertirse este paulatinamente en representante de las familias de
mayor número, el Ingreso Per Capita desciende hasta hacerse menor que en el Cluster 4.





Figura 5.27

Estadísticas

A continuación se muestran los gráficos de barras que representan cómo fue el
intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos:
Entre el Tiempo 1 y Tiempo 2 (Figura 5.28) se observa que el Cluster 4 capta gran parte
de los individuos del Cluster 2, corroborando el aumento económico indicado anteriormente.
Entre el Tiempo 2 y 3 (Figura 5.29) el cluster 4 no presenta grandes variaciones, pero se
observa el traspaso de individuos entre el Cluster 3 y el 4. Cómo ya se explicitó esto se
corresponde con que el Cluster 2 pasa a representar a las familias de ingreso limitado y mayor
número de integrantes.
Entre el Tiempo 3 y 4 (Figura 5.30), el mayor cambio se observa en el Cluster 4 que como
consecuencia de su crecimiento económico adopta un número importante de individuos del Cluster
3.




María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 62 -

Figura 5.28


Figura 5.29

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 63 -

Figura 5.30



Individuos Perdidos

En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que
pasan de un cluster a otro, pero se agregan los que no pasaron a ningún cluster, o sea, que en ese
período de tiempo, no se contaba con información para ese individuo. El motivo puede ser
simplemente que no haya querido responder a la encuesta.
En este análisis queda evidenciado que en el Tiempo 2 no se cuenta con información
sobre ciertos hogares, que en un principio formaban parte del Cluster 1.


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 64 -

Figura 5.31



Figura 5.32
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 65 -


Figura 5.33


Performance

Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos. En el
siguiente gráfico se muestra el tiempo que demora el proceso en finalizar. Como se puede
observar prácticamente no hay variación de tiempo a medida que aumenta el número de clusters,
incluso menos que cuando se trataba de un juego de datos con más atributos.















Figura 5.34


Performance INDEC 1996-1997 2D
0
2
4
6
1 2 3 4 5 6
Tiempo (segundos)
N
º

C
l
u
s
t
e
r
s
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 66 -
5.1.4 Caso de prueba 3

Nombre del archivo: PER_INDEC-2001-2002_3D (Este es otro juego de datos, referidos a las
personas, y sólo se tomaron 3 atributos para permitir un análisis tridimensional)
Cantidad de Registros: 4396
Cantidad de Atributos: 6


Detalle de atributos

Nombre Tipo Detalle %Perdidos Valores
distintos
ID Nominal Código único que identifica a
la vivienda a través de las 4
ondas.

0% 1099
Fecha Inicio Fecha 0% 4
Fecha Fin Fecha
Fechas de Inicio y Fin de
validez del registro. Al tomar
4 ondas los rangos de
fechas válidos son:
*01/01/1996 al 01/07/1996
*02/07/1996 al 31/12/1996
*01/01/1997 al 01/07/1997
*02/07/1997 al 31/12/1997


0% 4
Edad Numérico Edad del miembro del hogar
entrevistado

1% 94
Total Horas
Trabajadas X
Semana
Numérico Cantidad de horas totales
que el individuo trabaja por
semana.
0% 139
Ingreso Total Numérico Ingreso Total Mensual del
Individuo

0% 252
Figura 5.35


Proceso de prueba

1) Se ejecuta el sistema WEKA. En la solapa de preproceso se carga el archivo
correspondiente.


2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros:
• Chronon: Día (3)
• Número de Intervalos: 4
• Posición Fecha Fin:2
• Posición Fecha Inicio: 1
• Posición ID: 0

Al terminar de filtrar, las fechas de inicio y fin se reemplazan por una unidad temporal cuyo
valor está entre 0 y 4. Los rangos de fechas que corresponden a cada unidad temporal se guardan
en el archivo IntervalosDeTiempo.txt y son los siguientes:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 67 -


Intervalo de tiempo perteneciente a la unidad temporal 1
Desde: Mon Jan 01 00:00:00 ART 2001 Hasta: Mon Jul 01 00:00:00 ART
2001

Intervalo de tiempo perteneciente a la unidad temporal 2
Desde: Tue Jul 02 00:00:00 ART 2001 Hasta: Tue Dec 31 00:00:00 ART
2001

Intervalo de tiempo perteneciente a la unidad temporal 3
Desde: Wed Jan 01 00:00:00 ART 2002 Hasta: Wed Jul 02 00:00:00 ART
2002

Intervalo de tiempo perteneciente a la unidad temporal 4
Desde: Thu Jul 03 00:00:00 ART 2002 Hasta: Thu Jan 01 00:00:00 ART
2002

Figura 5.36


Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal

3) En la solapa de Cluster, se elige el algoritmo Temporal_k_d_Median con los siguientes
parámetros:

• Número de clusters: 5
• Modo de clustering: Use Training Set

El resultado de la corrida después de 4 segundos es el siguiente:



=== Run information ===

Scheme: weka.clusterers.Temporal_k_D_Median -N 5
Relation: PER_INDEC-2001-2002-Temporal
Instances: 4396
Attributes: 5
Temp
ID
Edad
TotalHorasTrabXSemana
IngresoTotal
Test mode: evaluate on training data


=== Clustering model (full training set) ===

Temporal_k_D_Median======

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-08761 39.00 0.00 200.00
Cluster 2 0.0 2-01-1-09791 42.00 45.00 500.00
Cluster 3 0.0 2-01-1-08672 24.00 0.00 0.00
Cluster 4 0.0 2-01-1-01552 66.00 0.00 150.00
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 68 -
Cluster 5 0.0 2-01-1-05552 11.00 0.00 0.00
Cluster centroids for temporal unit 2:
Cluster 1 1.0 2-01-1-09652 42.00 0.00 0.00
Cluster 2 1.0 2-01-1-08351 41.00 48.00 1000.00
Cluster 3 1.0 2-01-1-09573 22.00 0.00 0.00
Cluster 4 1.0 2-01-1-07781 69.00 0.00 200.00
Cluster 5 1.0 2-01-1-06064 10.00 0.00 0.00
Cluster centroids for temporal unit 3:
Cluster 1 2.0 2-01-1-09371 44.00 0.00 0.00
Cluster 2 2.0 2-01-1-08351 41.00 48.00 1000.00
Cluster 3 2.0 2-01-1-06054 21.00 0.00 0.00
Cluster 4 2.0 2-01-1-07021 70.00 0.00 174.00
Cluster 5 2.0 2-01-1-06065 8.00 0.00 0.00
Cluster centroids for temporal unit 4:
Cluster 1 3.0 2-01-1-10061 45.00 0.00 150.00
Cluster 2 3.0 2-01-1-07791 42.00 45.00 800.00
Cluster 3 3.0 2-01-1-06843 20.00 0.00 0.00
Cluster 4 3.0 2-01-1-10811 70.00 0.00 200.00
Cluster 5 3.0 2-01-1-03803 9.00 0.00 0.00





=== Evaluation on training set ===


Temporal_k_D_Median======

Cluster centroids for temporal unit 1:
Cluster 1 0.0 3-96-1-08761 39.00 0.00 200.00
Cluster 2 0.0 2-01-1-09791 42.00 45.00 500.00
Cluster 3 0.0 2-01-1-08672 24.00 0.00 0.00
Cluster 4 0.0 2-01-1-01552 66.00 0.00 150.00
Cluster 5 0.0 2-01-1-05552 11.00 0.00 0.00
Cluster centroids for temporal unit 2:
Cluster 1 1.0 2-01-1-09652 42.00 0.00 0.00
Cluster 2 1.0 2-01-1-08351 41.00 48.00 1000.00
Cluster 3 1.0 2-01-1-09573 22.00 0.00 0.00
Cluster 4 1.0 2-01-1-07781 69.00 0.00 200.00
Cluster 5 1.0 2-01-1-06064 10.00 0.00 0.00
Cluster centroids for temporal unit 3:
Cluster 1 2.0 2-01-1-09371 44.00 0.00 0.00
Cluster 2 2.0 2-01-1-08351 41.00 48.00 1000.00
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 69 -
Cluster 3 2.0 2-01-1-06054 21.00 0.00 0.00
Cluster 4 2.0 2-01-1-07021 70.00 0.00 174.00
Cluster 5 2.0 2-01-1-06065 8.00 0.00 0.00
Cluster centroids for temporal unit 4:
Cluster 1 3.0 2-01-1-10061 45.00 0.00 150.00
Cluster 2 3.0 2-01-1-07791 42.00 45.00 800.00
Cluster 3 3.0 2-01-1-06843 20.00 0.00 0.00
Cluster 4 3.0 2-01-1-10811 70.00 0.00 200.00
Cluster 5 3.0 2-01-1-03803 9.00 0.00 0.00


Clustered Instances

0 4396 (100%)


Figura 5.37

Al finalizar este proceso, se ha creado en el directorio de ejecución de WEKA, el archivo
PER_INDEC-2001-2002-3D_Temporal_C5_T4.csv. C5 indica que se realizaron 5 clusters. T4
indica que se trata de 4 unidades temporales.

4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo PER_INDEC-
2001-2002-3D_Temporal_C5_T4.csv
Las opciones de Gráficos 2D están deshabilitadas ya que estamos trabajando con tres
atributos.



Gráficos 3D

Este gráfico muestra para cada período (Tiempo) cómo es la distribución de los individuos
según sus atributos. Como se trata de sólo tres atributos se puede realizar un gráfico
tridimensional.
En el gráfico 5.38 (primer semestre del 2001) las estadísticas muestran una alarmante
cantidad de desocupados. Por esa razón, 4 de los 5 clusters se ordenaron en la franja de Cantidad
de horas trabajadas = 0, dividiéndose en distintas franjas de edades. El Cluster 5 abarca los
individuos de hasta 20 años. Se observa que en su gran mayoría ninguno trabaja ni percibe
sueldo, excepto un pequeñísimo grupo cercano a los 20 años que trabaja hasta 50 horas
semanales, y percibe sueldos bajos. El Cluster 3 abarca los individuos entre 20 y 30 años que
trabajan hasta 50 horas semanales. El Cluster 1 abarca los individuos entre 30 y 40 años que
trabajan muy pocas horas, mayoritariamente 0. Este cluster es altamente representativo del grupo
de los desocupados. El Cluster 4 abarca todos los individuos mayores a 40 años que trabajan muy
pocas horas (desocupados y jubilados) y por último el Cluster 2 se distribuye en forma esférica
entre todos los individuos que trabajan la mayor cantidad de horas. Este cluster representa
claramente al promedio de la población que trabaja entre 40 y 100 horas semanales. Es de notar
que el centroide se ubicó a los 42 años y 45 horas semanales, con un ingreso promedio de $500.
Sin embargo el cluster abarca personas entre 20 y 65 años, y con horas trabajadas entre 10 y 120.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 70 -

Figura 5.38

En la Figura 5.39 (segundo semestre del 2001), los clusters mantuvieron sus posiciones
pero se observan leves mejoras en las horas trabajadas y en los sueldos percibidos. El Cluster 2
evolucionó hacia mayor cantidad de horas trabajadas y mayor sueldo (el centroide está en 48 hs y
sueldo cercano a $1000), cediendo los individuos de menor cantidad de horas trabajadas a los
clusters 1, 3 y 4, que pasaron de tener 0 horas trabajadas a tener hasta 25 horas. Se observa
además que el Cluster 4 (individuos de edad avanzada) percibe ingresos superiores al período
anterior. Por último el cluster 5 (individuos de hasta 18 años) no refleja ninguna variante.


Figura 5.39
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 71 -
En la Figura 5.40 (Tiempo 3: Primer semestre de 2002) se repite la tendencia anterior. Los
clusters 1, 3 y 4 ganan espacio en las horas trabajadas llegando hasta la franja de 40 horas. Es de
notar, sin embargo, que los centroides de los tres clusters siguen estando en las 0 horas
trabajadas, indicando que sus individuos representativos son desocupados.



Figura 5.40


Por último, en el segundo semestre del 2002 (Figura 5.41), las variaciones son muy leves,
destacándose únicamente el descenso en promedio de los ingresos percibidos del Cluster 2,
(aproximadamente $800), y el aumento de los ingresos del Cluster 1 (su centroide evolucionó de 0
a aproximadamente $150). Cómo, sin embargo, la cantidad de horas trabajadas sigue siendo 0,
este aumento indica la presencia de Planes Trabajar o Planes Jefes y Jefas de Hogar.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 72 -

Figura 5.41





Gráfico 3D Tiempo

Este gráfico provee información similar al gráfico anterior pero vista desde otro punto de
vista, se observa en un solo gráfico la evolución en el tiempo de un solo cluster.
También hay que tener en cuenta que la escala entre un gráfico y otro cambia según los
valores que se deseen graficar.
En la figura siguiente se muestra en un solo gráfico el análisis que se hizo anteriormente
paso por paso. Por ejemplo, para el Cluster 2, vemos que se presentaron pequeñas oscilaciones
pero el cluster en general se mantuvo bastante constante.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 73 -

Figura 5.42

En la Figura 5.43 se observa la trayectoria del Cluster 4. Acá se puede observar que hay
un gran número de individuos cuyos ingresos son 0 o un valor muy bajo y la edad es mayor a 45
años, por lo que se agruparon dentro un mismo cluster que representa a los desocupados.


Figura 5.43

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 74 -
Análisis por Atributo

Edad: En este gráfico se observa que se agrupa en un mismo cluster a los individuos que
tienen Edad similar. Se observa que por tratarse de variaciones muy leves de tiempo los centroides
no se modifican considerablemente.




Figura 5.44




María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 75 -
Horas Trabajadas: Aquí se puede observar que excepto el Cluster 2, todos tienen sus
centroides en 0 horas trabajadas. Este análisis se complementa con el del Grafico3D. Y es un
indicador explícito de la desocupación que se vivió en la época analizada.




Figura 5.45

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 76 -
Ingreso Mensual: El análisis de este atributo también concuerda con los otros dos. Los
individuos del Cluster 5 (Menores de 20) no tienen Ingresos, los del Cluster 4 (entre 50 y 95 años)
tienen un Ingreso Bajo (seguramente se trata de jubilación o pensión ya que no cuentan con Horas
Trabajadas) y el resto de los clusters cuentan con Ingresos acorde a sus características. El Cluster
2 representante del grupo de individuos con mayor horas trabajadas muestra una evolución de
$500 a $1000 entre el primer y segundo período para luego mantenerse en ese valor y tener una
leve disminución el cuarto período. El caso más grave es el del Cluster 1 (individuos entre 30 y 50
años que no trabajan), que muestra un descenso a $0 en el segundo y tercer período, para luego
estabilizarse en un valor cercano a $150, posiblemente por Planes otorgados ya que las horas
trabajadas siguen siendo 0.



Figura 5.46

t



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 77 -
Estadísticas

A continuación se muestran los gráficos de barras que representan como fue el
intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos:
En los 4 períodos se observa que la gran mayoría de los individuos se mantienen en sus
clusters, sin embargo los pequeños cambios muestran una tendencia creciente en el Cluster 1
(individuos entre 30 y 50 años en situación de desocupación). El Cluster 2 se mantiene constante
hasta el tercer período, registrando un leve aumento de individuos en el traspaso al último período.
Ya que este cluster es representativo de las personas que trabajan, este aumento indica una
tendencia positiva de la situación laboral.



Figura 5.47

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 78 -

Figura 5.48


Figura 5.49



Individuos Perdidos

En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que
pasan de un cluster a otro, pero se agregan los que no pasaron a ningún cluster, o sea, que en ese
período de tiempo, no se contaba con información para ese individuo. El motivo puede ser
simplemente que no hay querido responder a la encuesta, o puede ser algo más complejo como
mudanza o fallecimiento.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 79 -
En el período 1 había una pequeña cantidad de individuos sobre los que no se contaba
información, que en el Período 2 pasaron a formar parte de los clusters 2 y 3.
Asimismo, en el primer período había individuos en los clusters 2 y 4, sobre los que en el
segundo período no se contaba información.
Un comportamiento similar se observa durante los otros períodos, pero ya para el último
Tiempo, no existe ningún individuo sin información.

Figura 5.50


Figura 5.51

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 80 -

Figura 5.52


Performance

Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos. En el
siguiente gráfico se muestra el tiempo que demora el proceso en finalizar. Como se puede
observar prácticamente no hay variación de tiempo a medida que aumenta el número de clusters,
sí se nota un pequeño aumento en el tiempo comparando con el juego de datos INDEC 1996-1997
ya que se trata del doble de registros.















Figura 5.53



Performance PER_INDEC 2001-2002 3D
4.5
5
5.5
6
6.5
1 2 3 4 5 6
Tiempo (segundos)
N
º

C
l
u
s
t
e
r
s
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 81 -
5.1.5 Prueba de Performance

A continuación se detallan los juegos de datos utilizados para probar la performance del
algoritmo de Clustering Temporal:

Dataset Instancias Atributos
At.
Nominales
At.
Numéricos
Valores
Desconocidos
Unidades
Temporales
Cholesterol1 1212 16 9 5 Si
4
Cholesterol2 2424 16 9 5 Si 4
Cholesterol3 9696 16 9 5 Si 4
Cholesterol4 19392 16 9 5 Si 4
Cholesterol5 37784 16 9 5 Si 4
Cholesterol6 65536 16 9 5 Si 4
Eucalyptus1 1150 22 6 16 Si 5
Eucalyptus2 2300 22 6 16 Si 5
Eucalyptus3 9200 22 6 16 Si 5
Eucalyptus4 18400 22 6 16 Si 5
Eucalyptus5 36800 22 6 16 Si 5
Eucalyptus6 65500 22 6 16 Si 5
Figura 5.54

Los resultados que se describen a continuación, se obtuvieron luego de ejecutar el sistema
WEKA en una PC con procesador Pentium III 733 Mhz, con 256 Mb de memoria RAM.
Las pruebas consistieron en aplicar el algoritmo Temporal_k-D-Median, a los juegos de
datos y observar el tiempo transcurrido hasta la finalización del mismo. El algoritmo se ejecutó para
formar distintas cantidades de clusters. En particular, se crearon 2,3,4,5,6 y 7 clusters, y los
tiempos del algoritmo no variaron considerablemente entre un número de clusters y otro, por lo que
a continuación se transcribe el promedio de los tiempos obtenidos. Al utilizar distintas cantidades
de individuos, sí se observó una variación de la duración del procesamiento.
También se aplicó el algoritmo k-D-Median (algoritmo no temporal) a cada una de las
unidades temporales, para observar las ventajas de ejecutar el algoritmo temporal en forma
completa. Por un lado, la suma de los tiempos si se ejecuta por separado, es similar o incluso
mayor al tiempo que se demora en ejecutar el algoritmo temporal, pero lo más importante, con el
Clustering Temporal se puede obtener la relación de los clusters a través de los distintos tiempos,
y se pueden conocer estadísticas o trayectorias de los individuos.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 82 -

Figura 5.55



























Performance del Clustering Temporal
0
5
10
15
20
25
30
35
40
45
50
1000 11000 21000 31000 41000 51000 61000
Data Sets
T
i
e
m
p
o

(
s
e
g
u
n
d
o
s
)
Cholesterol
Eucalyptus
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 83 -





6 Conclusiones









6.1 Conclusiones

El método de Clustering Temporal propuesto en la presente tesis, realiza el proceso de
clustering en forma convencional (agrupa los individuos teniendo en cuenta sólo los atributos
espaciales o “no temporales” de los mismos) para distintos momentos de tiempo. O sea, que a
través de los atributos temporales de una base de datos es posible relacionar los clusters en los
distintos tiempos.
Esto nos permite observar la trayectoria de los objetos, ver cómo varían los clusters
durante el transcurso del tiempo, y obtener distintas estadísticas sobre el movimiento de clusters y
objetos. La aplicación de este algoritmo a datos temporales brinda información muy difícil de
obtener aplicando sólo un algoritmo de clustering convencional.
Además de la información que brinda, una importante ventaja del método propuesto es que
funciona como un molde o framework: se basa en un algoritmo de clustering convencional, y a esto
le agrega toda la funcionalidad necesaria para obtener la información temporal. Cómo el algoritmo
de clustering a utilizar depende de la aplicación que se le quiera dar, este método permite utilizar
cualquier otro algoritmo convencional, y poder asimismo obtener información relevante.
Los resultados que se obtuvieron en la experimentación analizando datos del INDEC son
muy útiles. Se pudo hacer un análisis exhaustivo de los hogares y de los miembros de los hogares,
ver distintas estadísticas de los atributos, ver la evolución en el tiempo de esas variables, y todo
eso con un mínimo esfuerzo y tiempo.
La forma gráfica de ver los resultados también es importante, ya que es más fácil encontrar
información: patrones de comportamiento, evolución, etc. Analizando los resultados numéricos
también se podría llegar a estas conclusiones pero sería mucho más complicado.
El análisis de performance también fue positivo, ya que se hicieron pruebas con mucha
cantidad de registros, y los tiempos siguieron siendo muy satisfactorios.

6.2 Trabajo Futuro

La propuesta que se hace en este trabajo permite seguir investigando sobre el tema. En
particular hay dos puntos fundamentales en los cuales enfocarse:

a) Adaptación del algoritmo para clustering de grandes bases de datos temporales.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 84 -
• Realizar el clustering de bases de datos muy grandes (millones de registros) ha
emergido cómo una desafiante investigación. Ya existen algunos algoritmos que
se han enfocado en el tema. Los procesos de clustering necesitan hacer múltiples
recorridos sobre los datos para alcanzar convergencia y como en el caso de
grandes bases de datos no se pueden tener todos los datos a la vez en memoria,
se hace necesario hacer más lecturas del disco, lo cual es inmensamente costoso
a nivel tiempo.

El objetivo, entonces, es cómo acceder a los datos, sin que eso ocupe demasiado
tiempo.
Algunos métodos se basan en identificar regiones de datos que sean
comprensibles y que se puedan mantener en memoria, y otras que pueden ser
descartadas; otros utilizan índices temporales, pero todos se enfocan en el manejo
más eficiente de memoria.

El plan en nuestro caso, sería investigar qué procedimientos serían útiles tanto
para adaptar el algoritmo interno (k-d-Median en este caso) tanto como para
adaptar el proceso temporal.

b) Desarrollo de herramientas de visualización que faciliten el análisis de los resultados
obtenidos.

• En los últimos tiempos muchos paquetes de software han sido creados para
facilitar la tarea de visualización de componentes gráficos, desde síntesis de
sonido, estadísticas, investigaciones médicas, o cualquier otra aplicación que
necesite mostrar resultados de una forma más intuitiva y amigable. La mayoría de
estos paquetes hacen extensivo el uso de metáforas gráficas, abstracción de
objetos y utilización de colores reduciendo la cantidad de elementos a mostrar,
simplificando el análisis y brindando un detalle más exhaustivo de información.
Sería útil aplicar estos conceptos para la visualización de los resultados del
Clustering Temporal.

• Como los resultados que se muestran en el Clustering Temporal evolucionan en el
tiempo, otro concepto útil para utilizar sería el de Series Temporales. Una serie
temporal permite realizar análisis de una o muchas variables a la vez, se puede
explorar un modelo estacionario o no estacionario, se pueden realizar
estimaciones y predecir valores futuros.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 85 -




Bibliografía









[1] Adair, K. & Argo, P., Classification of Behavior using Unsupervised Temporal Neural Networks.
In Proceedings of the IEEE International Conference on Systems, Man, and Cybernetics (SMC'98) (pp.
2584-2589). Año 1998.

[2] Bittner, T., Rough sets in spatio-temporal data mining. In Proceedings of International Workshop
on Temporal, Spatial and Spatio-Temporal Data Mining, TSDM2000, Lyon, France. Lecture Notes
in Artificial Intelligence, Vol. 2007, Año 2001.

[3] Chen, C. & Kong, J. & Zaniolo, C., Design and Implementation of a Temporal Extension of SQL.
19th International Conference on Data Engineering, 5-8 Marzo 2003, Bangalore, India (ICDE 2003)

[4] Estivill-Castro, V. Computational Geometry Provides Techniques for Approximately Solving the
p-Median Problem, 5 Enero 2001.

[5] Estivill-Castro, V. Convex Group Clustering of Large Geo-referenced Data Sets. The Pacifc
Institute for the Mathematical Sciences, The University of British Columbia, Canada, Vancouver,
Canada, Año 1999.

[6] Estivill-Castro, V. & Houle, M., Robust Distance-Based Clustering with Application to Spatial
Data Mining, Algorithmica, 30, 216-242, Springer-Verlag, Año 2001.

[7] Estivill-Castro, V. & Lee, I., Fast Spatial Clustering with Different Metrics and in the Presence of
Obstacles. 9th ACM International Symposium on Advances in Geographic Information Systems
(ACM-GIS 2001). Atlanta, GA, USA November 9-10, 2001. Walid G. Aref (editor) ACM-Press, pp
142-147, Año 2001.

[8] Estivill-Castro, V. & Murray, A. , Hybrid Optimization for Clustering in Data Mining, Pacific Rim
International Conference on Artificial Intelligence, pp 424-434, Año 2000.

[9] Estivill-Castro, V. & Murray, A., Spatial Clustering for Data Mining with Genetic Algorithms,
Proceedings of the International ICSC Symposium on Engineering of Intelligent Systems, EIS-98.
February 11 - 13, 1998, Tenerife, Spain. Printed Edition, Alpaydin, E. (editor), Vol. 1, pp 317-323.

[10] Estivill-Castro, V. & Yang, J. A Fast and Robust General Purpose Clustering Algorithm, Pacific
Rim International Conference on Artificial Intelligence, pp 208-218, Año 2000.

[11] Galic, S. & Loncaric, S., Cardiac image segmentation using spatio-temporal clustering. In
Proceedings of SPIE Medical Imaging, San Diego, USA,pp. 1199-1206, Año 2001.

[12] Grabmeier, G. & Rudolph, A. Techniques of Cluster Algorithms in Data Mining, Data Mining
and Knowledge Discover, 6, 303-360, Año 2002.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 86 -

[13] Hammoud, R. & Chen, L. & Fontaine, D., An extensible Spatial-Temporal Model for Semantic
Video Segmentation. First International Forum on Multimedia and Image Processing, Anchorage,
Alaska, Mayo 1998.

[14] Han, J. & Kamber, M. & Tung, A. Spatial Clustering Methods in Data Mining: A Survey, H. J.
Miller and J. Han (eds.), Geographic Data Mining and Knowledge Discovery, NY: Taylor and
Francis, Año 2001.

[15] Huang, Z., A Fast Clustering Algorithm to Cluster Very Large Categorical Data Sets in Data
Mining, Research Issues on Data Mining and Knowledge Discovery, Año 1997.

[16] Ian, H. & Witten, I. & Frank, E. Data Mining: Practical machine learning tools with Java
implementations, Morgan Kaufmann, San Francisco, Año 2000.

[17] Jensen, C.S. & Cliffor, J. & Gadia, S.K. & Segev, A. & Snodgrass, R.T., A Glossary of
Temporal Databases Concepts, SIGMOD Record, Vol.21, No.3, Septiembre 1992.

[18] Jensen, C.S. & Snodgrass, R.T., Semantics of Time-Varying Information, 2000, Information
Systems, Vol. 21, No. 4, pp. 311-352, Año 1996.

[19] Jensen, C.S. & Soo, M.D. & Snodgrass, R.T., Unifying Temporal Data Models, Information
Systems, v.19 n.7, pp. 513-547, Octubre 1994.

[20] Nanni, M. Distances for Spatio-Temporal Clustering, Proceedings of Sistemi Evoluti per Basi di
Dati (SEBD'02), Junio 2002.

[21] Nanni, M. Clustering methods for spatio-temporal data. PhD Thesis. Dipartimento di
Informatica, Università di Pisa, Año 2002.

[22] Navas, M.D. & Ale, J.M, Un modelo de Clustering Temporal. Proceedings de X Congreso
Argentino de Ciencias de la Computación (CACIC). Octubre 2004.

[23] Ng, R. T. & Han, J. ,Efficient and Effective Clustering Methods for Spatial Data Mining, 20th
International Conference on Very Large Data Bases, September 12--15, 1994, Santiago, Chile
proceedings, Morgan Kaufmann Publishers, pp 144-155, Año 1994.

[24] Padmanabhan, B. & Tuzhilin, A., Pattern Discovery in Temporal Databases: A Temporal Logic
Approach. In Proceedings of the 2nd International Conference on Knowledge Discovery and Data
Mining, Agosto 1996.

[25] Popescul, A. & Flake, G. & Lawrence, S. & Ungar, L. & Lee, C., Clustering and Identifying
Temporal Trends in Document Databases. In Proceedings of the IEEE Advances in Digital Libraries
2000 (ADL 2000), pp. 173, Mayo 22-24, 2000.

[26] Povinelli, R. J. & Feng, X., Data Mining of Nonstationary Time Series Using Multiple Temporal
Patterns, Artificial Neural Networks in Engineering, Proceedings, pp 511-516, Año 1999.

[27] Povinelli, R. J. & Feng, X., Temporal Pattern Identification of Time Series Data using Pattern
Wavelets and Genetic Algorithms, Artificial Neural Networks in Engineering, Proceedings, pp 691-
696, Año 1998.

[28] Ramamritham, K. & Sivasankaran, R. & Stankovic, J. & Towsley, D. & Xiong, M., Integrating
Temporal, Real-Time and Active Databases. SIGMOD Record, Vol. 25, No. 1, pp. 8-12, Marzo
1996.

[29] Roddick, J.F. & Hornsby, K. & Spiliopoulou, M. Yet Another Bibliography of Temporal, Spatial
and Spatio-Temporal Data Mining Research, Proc. SIGKDD Temporal Data Mining Workshop, San
Francisco, CA. Unnikrishnan, K. P. and Uthurusamy, R., Eds., ACM. 167-175, Año 2001.

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 87 -
[30] Roddick, J.F. & Lees, B. Paradigms For Spatial and Spatio-Temporal Data Mining, H.G. Miller
and J. Han (eds), Geographic Data Mining and Knowledge Discovery. London: Taylor & Francis,
2001.

[31] Xiong, M. & Sivasankaran, R. & Stankovic, J. & Ramamritham, K. & Towsley, D., Scheduling
Access to Temporal Data in Real-Time Databases. In A. Bestavros, K.-J. Lin, and S.H. Son,
editors, Real-Time Systems: Issues and Applications, chapter 11, pp. 167--191. Kluwer
International, Año 1997.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 88 -
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 89 -




Apéndices






A1 Diseño del Código

A1.1 Casos de Uso

Para interpretar cuál es el objetivo de nuestra aplicación, en la Figura A1.1 se observa un
diagrama de casos de uso. Este diagrama indica las interacciones básicas entre el usuario y el
sistema. El usuario, en nuestro caso, es la persona encargada de realizar el proceso de data
mining. Las acciones que realiza son “Preparar Datos”, “Procesar Clustering Temporal” y “Analizar
Resultados”. En el detalle de los casos de uso, se puede apreciar con más claridad cuál es la
funcionalidad básica de cada caso.





























Figura A1.1
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 90 -
A1.2 Detalle de Casos de Uso

Caso de Uso: Preparar Datos
Breve explicación: Toma los datos de una base de datos temporal, especificados en un
formato determinado, y los asigna a Unidades Temporales según sus rangos de validez.
Precondiciones:
• El archivo de entrada debe cumplir con el formato de los archivos arff (Ver Detalle en
Documentación)
• Además, el archivo debe poseer:
• Un atributo que indique Fecha de Inicio de validez del registro, la misma debe
tener el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. Por ejemplo
“2004-12-01 21:35:00”
• Un atributo que indique Fecha de Fin de validez del registro, la misma debe tener
el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. Por ejemplo “2004-12-
05 21:35:00”
• Un atributo que sea un ID único, que identifique al registro (puede haber mas de
un registro para el mismo ID)
• Uno o más atributos (numéricos o categóricos) que se compararán para realizar el
clustering.

Acciones del actor Acciones del Sistema
1) Cargar un archivo válido al sistema
2) Especificar parámetros: crono, cant. de
unidades temporales

3) Iniciar Filtrado
4) Determinar la diferencia entre la primera
fecha de inicio y la última fecha de fin.
5) Determinar el tamaño de cada intervalo
dividiendo la diferencia anterior por la cantidad
de unidades temporales deseadas.
6) Determinar los rangos de fechas que
componen cada intervalo.
7) Recorrer el conjunto de registros, verificar
dentro de que intervalo es válido (comparando
Fecha de Inicio y de Fin con los rangos del
intervalo), y asignarle dicho intervalo.
8) Ordenar los registros por Id y por Unidad
Temporal (intervalo).
* Si existe más de un registro por Id y por
Intervalo, combinarlos en un solo registro (si el
atributo es numérico, realizar promedio, si es
categórico, utilizar moda)

* Si en un determinado Intervalo, no hay dato
para un Id, crear un registro “vacío”.

9) Devolver el archivo de entrada, pero en lugar
de los atributos Fecha Inicio y Fecha Fin, incluir
la Unidad Temporal.
10) Guardar el Nuevo archivo.
PostCondiones:
Archivo arff con la siguiente estructura:
• Unidad temporal
• ID
• Atributos explícitos
Este archivo tiene la misma cantidad de registros para cada Unidad Temporal (UT), cada
registro con su ID único igual en cada UT, y cada UT ordenada alfabéticamente por ID.


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 91 -
Caso de Uso: Procesar Clustering Temporal
Breve explicación: Toma los datos preprocesados y los agrupa según similitudes en sus
atributos.
Precondiciones:
• El archivo de entrada debe cumplir con el formato de los archivos arff (Ver Detalle en
Documentación)
• Además, el archivo debe poseer:
• Un atributo numérico que indique la Unidad Temporal (UT)
• Un atributo que sea un ID único, que identifique al registro. En cada UT debe ser
el mismo
• Uno o más atributos (numéricos o categóricos) que se compararán para realizar el
clustering.

Acciones del actor Acciones del Sistema
1) Cargar un archivo válido al sistema
2) Especificar parámetros: Cant. de clusters
3) Ejecutar proceso de clustering
4) Transformar los atributos nominales en
numéricos utilizando el método de la
Documentación.
5) Elegir al azar tantos centroides como clusters
se deseen, para cada UT.
6) Dividir los individuos según método k-d-Median
(Ver Documentación)
7) Recalcular los centroides de los nuevos
clusters
8) Repetir pasos 6 al 8 hasta que no haya más
cambios y los clusters sean definitivos.
9) Calcular cuantos individuos pasaron de un
cluster a otro y determinar el orden de los clusters
en cada tiempo.
10) Armar archivo de salida con información
sobre cada registro.
11) Mostrar en pantalla la distribución de
centroides.
PostCondiones:
Archivo .csv (comma separated values) con la siguiente estructura:
• Detalle de los atributos explícitos de cada registro.
• Número de cluster y UT a los que pertenece ese registro
• Flag que indica si ese registro es un centroide o no (y en caso de qué sea de qué
cluster).

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 92 -

Caso de Uso: Analizar Resultados
Breve explicación: Toma el archivo de salida del proceso de clustering y brinda diferentes
gráficos para analizar los resultados obtenidos.
Precondiciones:
• Archivo .csv (comma separated values) con la siguiente estructura:
• Detalle de los atributos explícitos de cada registro.
• Número de cluster y UT a los que pertenece ese registro
• Flag que indica si ese registro es un centroide o no(y en caso de qué sea, de
qué cluster)

Acciones del actor Acciones del Sistema
1) Cargar archivo de resultados *.csv
2) Leer información del archivo y configurar
opciones del programa. Por default están todas
deshabilitadas.
* Si tiene 2 atributos, habilitar Gráficos 2D y
Gráficos 2 D Tiempo
* Si tiene 3 atributos, habilitar Gráficos 3D y
Gráficos 3 D Tiempo
* Las opciones: Análisis por Atributo,
Estadísticas de Individuos e Individuos Perdidos
habilitarlas siempre.
3) Seleccionar alguna de las opciones
disponibles.

4) Mostrar en pantalla el gráfico
correspondiente:
* Gráficos 2 D: distribución de las 2 variables en
el plano, diferenciando los distintos clusters.
* Gráficos 2 D Tiempo: distribución de un
mismo cluster a través de los distintos tiempos.
* Gráficos 3 D: distribución de las 3 variables en
el hiperplano, diferenciando los distintos
clusters.
* Gráficos 3 D Tiempo: distribución de un
mismo cluster a través de los distintos tiempos.
* Análisis por atributo: trayectoria que sigue el
centroide de cada cluster a través de los
distintos tiempos.
* Estadísticas de Individuos: Gráfico de barras
que indica cuántos individuos pasaron entre un
cluster y otro al cambiar de tiempo.
* Individuos perdidos: Gráfico de barras que
indica cuántos individuos no tienen información
en un determinado tiempo.
PostCondiones:



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 93 -
A1.3 Estructura de Clases

La implementación del modelo propuesto consistió en agregar el algoritmo de Clustering
Temporal al sistema Weka. Como éste es un programa que ya está en funcionamiento, hubo que
respetar la arquitectura del mismo.
Weka está programado en Java, y tiene una estructura de clases, que se agrupan en
paquetes. En las Figuras A1.2 y A1.3 se muestran las clases más representativas que pertenecen
a la parte de Weka que nos interesa analizar. En cada clase, se detallan algunos atributos y
métodos, para dar una idea de la función de la misma dentro del sistema. Las flechas indican
herencia, esto es que una clase hija hereda el funcionamiento de su clase padre, y a su vez le
puede agregar nuevas funcionalidades.
La clase principal se denomina Explorador (Explorer), y es la que maneja las clases que
representan a cada una de las solapas del programa: Preproceso, Clasificación, Clustering,
Asociaciones y Visualización.
En el gráfico se puede ver cómo las clases “Panel de Preproceso” (PreprocessPanel),
“Panel de Clasificación” (ClasifierPanel) y “Panel de Clustering” (ClustererPanel) son hijas de la
clase Explorador.
De la clase “Panel de Preproceso” se desprende la clase Filtro, que es la clase genérica de
la cuál heredan distintos filtros específicos. La función de un filtro es transformar las instancias del
juego de datos, según distintos criterios: sacar o agregar atributos, modificar valores, etc. Por
ejemplo, uno de los filtros más usados es AtributoPerdido (FilterMissingValues), que reemplaza los
valores desconocidos de un atributo por un valor válido, de acuerdo a ciertas reglas.
De la clase “Panel de Clustering” se desprende la clase Clusterer, que es la madre de
todas las clases que realizan un proceso de clustering, por ejemplo K-Means.





María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004
F
i
g
u
r
a

A
1
.
2

D
i
a
g
r
a
m
a

d
e

C
l
a
s
e
s





































María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 95 -
F
i
g
u
r
a

A
1
.
3

C
o
n
t
i
n
u
a
c
i
ó
n

D
i
a
g
r
a
m
a

d
e

C
l
a
s
e
s





































María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004


- 96 -
A1.4 Nuevas Clases

En las Figuras A1.4 y A1.5 se observa el mismo diagrama de clases, pero con color se
agregaron las clases implementadas para realizar el proceso de Clustering Temporal. Las
mismas son: CrearUnidadTemporal y AtributoNumérico, que heredan de la clase Filtro, y
Temporal k-d-Median que hereda de la clase Clusterer.
A continuación se indican algunas peculiaridades de cada clase:

CrearUnidadTemporal: Formatea los datos de entrada para poder procesarlos con el
Clustering Temporal.
Los métodos más representativos son EncontrarIntervalos(), que divide el intervalo de
tiempo en subintervalos según los parámetros establecidos y MergeInstances() que luego que
a cada instancia se le asigna la Unidad Temporal correspondiente, chequea si es necesario
combinarlas o crear instancias vacías.

AtributoNumérico: Este filtro no se aplica por sí solo, sino que es llamado desde el
proceso de Clustering Temporal. Su función es transformar los atributos nominales en
numéricos para poder procesarlos con el método k-d-median.
El método más representativo es ExpansionAtributos(), que justamente realiza esta
transformación.

Temporal k-d-Median: Realiza el proceso de Clustering Temporal. Los métodos más
representativos son:
buildClusterer() es el que divide el conjunto de todas las instancias en sus respectivos
clusters. Desde este método se llama a otros que también son importantes:
distance() : calcula la distancia Euclídea entre 2 puntos.
Centroide_K_D_Median(): esté método es muy particular ya que es la implementación
del algoritmo k-d-Median. Se le pasa como parámetro todos los individuos de un cluster, y
devuelve el centroide. Si se desea cambiar este algoritmo base, habría que cambiar este
método.
ArmarCombinacion(): se utiliza luego de procesado el clustering, para encontrar la
relación entre los clusters de los distintos tiempos.



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004


- 97 -
F
i
g
u
r
a

A
1
.
4

D
i
a
g
r
a
m
a

d
e

C
l
a
s
e
s



N
u
e
v
o
s

F
i
l
t
r
o
s





































María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 98 -
F
i
g
u
r
a

A
1
.
5

D
i
a
g
r
a
m
a

d
e

C
l
a
s
e
s



N
u
e
v
o

M
é
t
o
d
o

d
e

C
l
u
s
t
e
r
i
n
g



































María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004


- 99 -
A2 Código Fuente

A2.1 WEKA

CreateTemporalUnits.class

/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
* CreateTemporalUnits.java
* Octubre 2004 María Daniela Navas
*
*/


package weka.filters.unsupervised.attribute;

import weka.filters.*;
import java.io.*;
import java.util.*;
import weka.core.*;
import java.lang.*;

/**
* Este filtro transforma las fechas de inicio y fin en una unidad temporal.<p>
*
*
* @author María Daniela Navas (mnavas@mnavas.com.ar)
* @version $Revision: 1.0 $
*/
public class CreateTemporalUnits extends Filter implements UnsupervisedFilter,
StreamableFilter, OptionHandler {


// Números de intervalos a dividir
protected int m_NumIntervalos=12;


//Acá se guardan los cortes de los intervalos
long [][] m_Intervalos;

protected int m_Chronon=3;
//Detalle de los m_Chronon:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 100 -
// 1: Año
// 2: Mes
// 3: Día
// 4: Hora
// 5; Minuto
// 6: Segundo



protected int m_PosFechaIni=0;
protected int m_PosFechaFin=1;
protected int m_PosId=2;
protected Instances m_Instances; //se usa porque hay que hacer varios procesos sobre el
conjunto de datos


/**
* Devuelve una enumeración de todos los parametros posibles
*
*/
public Enumeration listOptions() {

Vector newVector = new Vector(5);

newVector.addElement(new Option(
"\tEspecifique el número de intervalos en que se dividirá el conjunto de datos",
"T", 1, "-T <num>"));

newVector.addElement(new Option(
"\tIndique cuál es la mínima unidad de tiempo (chronon)\n"+
"\tValores posibles: 1(Año)- 2(Mes)- 3(Dia)- 4(Hora)- 5(Minuto)- 6(Segundo).",
"C", 1, "-C <num>"));

newVector.addElement(new Option(
"\tIndique cuál es la posición de la Fecha Inicial\n",
"I", 1, "-I <col>"));

newVector.addElement(new Option(
"\tIndique cuál es la posición de la Fecha Final\n",
"F", 1, "-F <col>"));

newVector.addElement(new Option(
"\tIndique cuál es la posición del Atributo Identificador\n",
"A", 1, "-A <col>"));


return newVector.elements();
}


/**
* Parsea los valores de los parametros: <p>
*
* -T Especifique el número de intervalos en que se dividirá el conjunto de datos",
* -C Indique cuál es la mínima unidad de tiempo (chronon)
* Valores posibles: 1(Año)- 2(Mes)- 3(Dia)- 4(Hora)- 5(Minuto)- 6(Segundo).
*
* -I Indique cuál es la posición de la Fecha Inicial
* -F Indique cuál es la posición de la Fecha Final
* -A Indique cuál es la posición del Atributo Identificador
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 101 -
*
*/
public void setOptions(String[] options) throws Exception {


//Setea el número de intervalos, por default 12
String Intervalos = Utils.getOption('T', options);
if (Intervalos.length() != 0) {
setNumIntervalos(Integer.parseInt(Intervalos));
} else {
setNumIntervalos(10);
}

//Setea el chronon, por default 3 (Día)
String chronon = Utils.getOption('C', options);
if (chronon.length() != 0) {
setChronon(Integer.parseInt(Intervalos));
} else {
setChronon(3);
}

//Setea la posicion de fecha inicial, por default 0
String fecha = Utils.getOption('I', options);
if (fecha.length() != 0) {
setPosFechaIni(Integer.parseInt(fecha)-1);
} else {
setPosFechaIni(0);
}

//Setea la posicion de fecha inicial, por default 1
fecha = Utils.getOption('F', options);
if (fecha.length() != 0) {
setPosFechaFin(Integer.parseInt(fecha)-1);
} else {
setPosFechaFin(1);
}

//Setea la posicion de fecha inicial, por default 2
String id = Utils.getOption('A', options);
if (id.length() != 0) {
setPosId(Integer.parseInt(id)-1);
} else {
setPosId(2);
}

if (getInputFormat() != null) {
setInputFormat(getInputFormat());
}
}

/**
* Devuelve el seteo de los parametros
*
*/
public String [] getOptions() {

String [] options = new String [5];
int current = 0;

options[current++] = "-T " + getNumIntervalos();
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 102 -

options[current++] = "-C " + getChronon();

options[current++] = "-I " + getPosFechaIni();

options[current++] = "-F " + getPosFechaFin();

options[current++] = "-A " + getPosId();


while (current < options.length) {
options[current++] = "";
}
return options;
}


/**
* Setea el formato de las instancias de entrada
*
*/
public boolean setInputFormat(Instances instanceInfo) throws Exception {

int borrarF=0;
int borrarId=0;
//Los dos atributos de fecha se transformarán en 1 solo numerico
super.setInputFormat(instanceInfo);

// Se crea el buffer de salida
Instances outputFormat = new Instances(instanceInfo, 0);

//Antes de borrar copio el atributo del ID
Attribute nuevoAtributoId = instanceInfo.attribute(m_PosId);

//Borro los atributos que indicaban fecha
//Al borrar CADA atributo, se reordena la estructura!!! por eso los valores no son los mismos
outputFormat.deleteAttributeAt(m_PosFechaIni);
if (m_PosFechaFin > m_PosFechaIni){
borrarF = m_PosFechaFin -1; //corro un valor para la izquierda, si es menor no hago nada
}
if (m_PosId > m_PosFechaIni){
borrarId = m_PosId -1; //corro un valor para la izquierda, si es menor no hago nada
}

outputFormat.deleteAttributeAt(borrarF);
if (borrarId > borrarF){
borrarId = borrarId -1; //corro un valor para la izquierda, si es menor no hago nada
}

outputFormat.deleteAttributeAt(borrarId);

//Creo un nuevo Atributo en la posición 0, para la UT
Attribute nuevoAtributoT = new Attribute("Temp");
//Inserto el nuevo atributo numérico
outputFormat.insertAttributeAt(nuevoAtributoT,0);

//Inserto el nuevo atributo numérico
outputFormat.insertAttributeAt(nuevoAtributoId,1);


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 103 -
//Ahora creo los invervalos
EncontrarIntervalos(instanceInfo);

setOutputFormat(outputFormat);

//Inicializo m_Instances
m_Instances = new Instances(outputFormat,0);
return true;
}



/**
* Toma una instancia para filtrarla.
*
* @return true si la instancia filtrada puede ser cargada en output()
*/
public boolean input(Instance instance) {

if (getInputFormat() == null) {
throw new IllegalStateException("No input instance format defined");
}
if (m_NewBatch) {
resetQueue();
m_NewBatch = false;
}

bufferInput(instance);
return false;
}


/**
* Indica si el proceso batch ha terminado de filtrar
*
* @return true si hay instancias pendientes de filtrar
*/
public boolean batchFinished() {

if (getInputFormat() == null) {
throw new IllegalStateException("No input instance format defined");
}

// Convierte las instancias de entrada pendientes
for(int i = 0; i < getInputFormat().numInstances(); i++) {
convertInstance(getInputFormat().instance(i));
}

//Ya tengo las unidades temporales, ahora las ordeno y junto si es necesario
MergeInstances(m_Instances);

m_NewBatch = true;
return (numPendingOutput() != 0);
}

/**
* Devuelve un string describiendo el filtro.
*
*/
public String globalInfo() {
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 104 -

return "Filtro que transforma los atributos de fechas en valores discretos.";
}


/**
* Devuelve el tip text para esta propiedad
*
*/
public String NumIntervalosTipText() {

return "Número de intervalos de tiempo a analizar." ;
}

/**
* Devuelve la propiedad
*
*/
public int getNumIntervalos() {

return m_NumIntervalos;
}

/**
* Setea la propiedad
*
*/
public void setNumIntervalos(int numIntervalos) {

m_NumIntervalos = numIntervalos;
}


/**
* Devuelve el tip text para esta propiedad
*
*/
public String ChrononTipText() {

return "Mínima unidad de tiempo a tener en cuenta." ;
}

/**
* Devuelve la propiedad
*
*/
public int getChronon() {

return m_Chronon;
}

/**
* Setea la propiedad
*
*/
public void setChronon(int Chronon) {

m_Chronon = Chronon;
}
/**
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 105 -
* Devuelve el tip text para esta propiedad
*
*/
public String PosFechaIniTipText() {

return "Posición dentro del rango de atributos, de la fecha de validez inicial del registro." ;
}

/**
* Devuelve la propiedad
*
*/
public int getPosFechaIni() {

return m_PosFechaIni;
}

/**
* Setea la propiedad
*/
public void setPosFechaIni(int PosFechaIni) {

m_PosFechaIni = PosFechaIni;
}

/**
* Devuelve el tip text para esta propiedad
*
*/
public String PosFechaFinTipText() {

return "Posición dentro del rango de atributos, de la fecha de validez final del registro." ;
}

/**
* Devuelve la propiedad
*/
public int getPosFechaFin() {

return m_PosFechaFin;
}

/**
* Setea la propiedad
*/
public void setPosFechaFin(int PosFechaFin) {

m_PosFechaFin = PosFechaFin;
}

/**
* Devuelve el tip text para esta propiedad
*/
public String PosIdTipText() {

return "Posición dentro del rango de atributos, del atributo identificatorio del registro." ;
}

/**
* Devuelve la propiedad
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 106 -
*
*/
public int getPosId() {

return m_PosId;
}

/**
* Setea la propiedad
*/
public void setPosId(int PosId) {

m_PosId = PosId;
}

/**
* Encuentra los puntos de corte para la fecha inicio y fecha fin
*
*/
protected void EncontrarIntervalos(Instances instances) throws Exception {

//Inicializo las variables
m_Intervalos = new long [m_NumIntervalos][2]; //esto guarda los cortes de los intervalos
long PrimerFechaInicio;
long UltimaFechaFin;


//Si ordeno por fecha de inicio, el primer registro tiene la primer fecha de inicio y fin
instances.sort(m_PosFechaIni);
PrimerFechaInicio = (long) instances.instance(0).value(m_PosFechaIni);

//Si ordeno por fecha de fin, el ultimo registro tiene la ultima fecha de inicio y fin
instances.sort(m_PosFechaFin);
UltimaFechaFin = (long) instances.instance(instances.numInstances()-
1).value(m_PosFechaFin);

//Calculo el tamaño del intervalo
double TamanioIntervalo = (UltimaFechaFin - PrimerFechaInicio) / m_NumIntervalos;

//Armo el vector de unidades temporales y lo imprimo en un txt
OutputStream Salida = new FileOutputStream("IntervalosDeTiempo.txt");
String linea = null;
long DesdeI = PrimerFechaInicio;
long HastaI = 0;
Date Desde = new Date();
Date Hasta = new Date();
int Anio;
int Mes;
int Dia;
int Hora;
int Minuto;
int Segundo;

if ((m_NumIntervalos > 0) && (TamanioIntervalo > 0)) {

for (int i=0; i < m_NumIntervalos; i++){

switch (m_Chronon){
// 1 segundo = 1.000 milisegundo
// 1 minuto = 60.000 milisegundos
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 107 -
// 1 hora = 3.600.000 mili
//1 día = 86.400.000 milisegundos
//1 mes = 2.592.000.000 mili
//1 año = 31.536.000.000

case 1: //año
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + (long) 3.1536E10;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);

Anio = Desde.getYear();
Desde = new Date(Anio,1,1);

Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Hasta = new Date(Anio,1,1);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();
break;

case 2: //mes
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + (long) 2.6784E9;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);

Anio = Desde.getYear();
Mes = Desde.getMonth();
Desde = new Date(Anio,Mes,1);

//Recorto el HastaI
Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Mes = Hasta.getMonth();
Hasta = new Date(Anio,Mes,1);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();
break;

case 3: //dia
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + 86400000;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 108 -

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);

Anio = Desde.getYear();
Mes = Desde.getMonth();
Dia = Desde.getDate();
Desde = new Date(Anio,Mes,Dia);

Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Mes = Hasta.getMonth();
Dia = Hasta.getDate();
Hasta = new Date(Anio,Mes,Dia);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();

break;

case 4: //hora
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + 3600000;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);

Anio = Desde.getYear();
Mes = Desde.getMonth();
Dia = Desde.getDate();
Hora = Desde.getHours();
Desde = new Date(Anio,Mes,Dia,Hora,1);

Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Mes = Hasta.getMonth();
Dia = Hasta.getDate();
Hora = Hasta.getHours();
Hasta = new Date(Anio,Mes,Dia,Hora,1);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();
break;

case 5: //minuto
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + 60000;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 109 -

Anio = Desde.getYear();
Mes = Desde.getMonth();
Dia = Desde.getDate();
Hora = Desde.getHours();
Minuto = Desde.getMinutes();
Desde = new Date(Anio,Mes,Dia,Hora,Minuto);

Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Mes = Hasta.getMonth();
Dia = Hasta.getDate();
Hora = Hasta.getHours();
Minuto = Hasta.getMinutes();
Hasta = new Date(Anio,Mes,Dia,Hora,Minuto);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();
break;

case 6: //segundo
//Calculo el valor del intervalo
if (i!=0) { //en el primer intervalo el desde es distinto
DesdeI = HastaI + 1000;
}
HastaI = (long) (DesdeI + TamanioIntervalo) ;

//Utilizo solo las unidades que corresponden
Desde =new Date(DesdeI);

Anio = Desde.getYear();
Mes = Desde.getMonth();
Dia = Desde.getDate();
Hora = Desde.getHours();
Minuto = Desde.getMinutes();
Segundo = Desde.getSeconds();
Desde = new Date(Anio,Mes,Dia,Hora,Minuto,Segundo);

Hasta =new Date(HastaI);

Anio = Hasta.getYear();
Mes = Hasta.getMonth();
Dia = Hasta.getDate();
Hora = Hasta.getHours();
Minuto = Hasta.getMinutes();
Segundo = Hasta.getSeconds();
Hasta = new Date(Anio,Mes,Dia,Hora,Minuto,Segundo);

//Vuelvo a pasar a long los valores recortados a la unidad correspondiente
DesdeI = Desde.getTime();
HastaI = Hasta.getTime();
break;
}//switch

//Archivo
linea = "\n\nIntervalo de tiempo perteneciente a la unidad temporal " + (i+1);
Salida.write(linea.getBytes());

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 110 -
//Lo guardo en el vector
m_Intervalos[i][0] = DesdeI;
m_Intervalos[i][1] = HastaI;

linea = "\n Desde: " + Desde.toString();
Salida.write(linea.getBytes());
linea = " Hasta: " + Hasta.toString();
Salida.write(linea.getBytes());
}//for
}
Salida.close();

}


/**
* Convierte una instancia y la agrega al final de la cola de salida
*/
protected void convertInstance(Instance instance) {

//la instancia se puede convertir en tantas instancias como números de intervalos haya
double [][] vals = new double [m_NumIntervalos][outputFormatPeek().numAttributes()];
long FechaIni;
long FechaFin;
long Int0;
long Int1;

int t;
int i;
int at=2; //a partir de aca van los atributos "normales"


// Copia y convierte los atributos
for(i = 0; i < getInputFormat().numAttributes(); i++) {
//En la fecha inicio hago el cálculo y lo asigno al nuevo atributo Temp
if (i==m_PosFechaIni){
FechaIni = (long) instance.value(i);
FechaFin = (long) instance.value(m_PosFechaFin);

//Me fijo si hay un intervalo en el que esté integramente contenido
for (t=0; t < m_NumIntervalos; t++){
Int0 = m_Intervalos[t][0];
Int1 = m_Intervalos[t][1];
vals[t][0]= -1; //inicializo en este valor para saber si se le asigno un tiempo o no

if (FechaIni >= Int0 && FechaFin <= Int1){
vals[t][0]= t;
}else if (FechaIni >= Int0 && FechaIni <= Int1 && FechaFin > Int1){
vals[t][0]= t;
}else if (FechaIni < Int0 && FechaFin > Int1){
vals[t][0]= t;
}else if (FechaIni < Int0 && FechaFin >= Int0 && FechaFin <= Int1){
vals[t][0]= t;
}
}//for t
}//if
else if (i==m_PosId){
for (t=0; t < m_NumIntervalos; t++){
//para todos los t tiene el mismo ID
vals[t][1] = instance.value(i);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 111 -
}//for
}
else if (i != m_PosFechaFin){
for (t=0; t < m_NumIntervalos; t++){
//para todos los t tiene el mismo ID
vals[t][at] = instance.value(i);
}//for
at++;
}//fin if

}//for


Instance inst = null;
for (t=0; t < m_NumIntervalos; t++){
if (vals[t][0] != -1){
if (instance instanceof SparseInstance) {
inst = new SparseInstance(instance.weight(), vals[t]);
} else {
inst = new Instance(instance.weight(), vals[t]);
}
copyStringValues(inst, false, instance.dataset(), getInputStringIndex(),
getOutputFormat(), getOutputStringIndex());
inst.setDataset(getOutputFormat());
m_Instances.add(inst);
}
}
}//fin metodo

/**
* Divido las instancias segun su UT
*/
protected void MergeInstances(Instances instances) {

//Divido las instancias segun su UT
Instances [] m_VectorInstances;
Instances [] m_VectorInstancesFinal;
int m_NumTemporalUnits;
int t,i,a;
double [] vals;

//La cantidad de unidades temporales es la cantidad de valores distintos que tiene el atributo 0
m_NumTemporalUnits = instances.numDistinctValues(0);

m_VectorInstances = new Instances [m_NumTemporalUnits];
m_VectorInstancesFinal = new Instances [m_NumTemporalUnits];
for (t=0; t < m_NumTemporalUnits ; t++) {
m_VectorInstances[t] = new Instances(instances,0);
m_VectorInstancesFinal[t] = new Instances(instances,0);
}

// Según el atributo 0 de la instancia en cuestión, agrego el atributo
// al vector de instancias en la posición que corresponda
int pos;
for (i = 0; i < instances.numInstances(); i++) {
pos = (int)instances.instance(i).value(0);
m_VectorInstances[pos].add( instances.instance(i));
}

//Ahora ordeno por el Id, cada posicion temporal
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 112 -
for (t=0; t < m_NumTemporalUnits ; t++) {
m_VectorInstances[t].sort(1);
i=0;
while (i < m_VectorInstances[t].numInstances()-1) {
//si las UT son iguales y los ID son iguales, hago un merge
if ((m_VectorInstances[t].instance(i).value(0) ==
m_VectorInstances[t].instance(i+1).value(0)) &&
(m_VectorInstances[t].instance(i).value(1) ==
m_VectorInstances[t].instance(i+1).value(1))) {
//merge
m_VectorInstances[t].instance(i).mergeInstance(m_VectorInstances[t].instance(i+1));
//borro la instancia i +1
m_VectorInstances[t].delete(i+1);
}else {
i++; //Solo incremento la i si no borre nada (al borrar, pierdo una posicion)
}
}//while

}//for t


//Ahora agrego intancias VACIAS, en los tiempos que faltan, para que todos los tiempos tengan
las
//mismas instancias y esten ordenadas
//Recorro cada grupo guardando el id mas chico.
double IdMenor = Double.MAX_VALUE;
boolean converged = false;
Instance NuevaInstancia;
boolean creoInstancia = false;
int instancias_creadas =0;
int [] Agregados = new int[m_NumTemporalUnits];
i=0;

while (!converged) {

//Recorro la misma instancia en todos los tiempos y guardo el menor valor
for (t=0; t < m_NumTemporalUnits ; t++) {
if ( (i - Agregados[t]) < m_VectorInstances[t].numInstances()){
if (m_VectorInstances[t].instance(i - Agregados[t]).value(1) < IdMenor ){
IdMenor = m_VectorInstances[t].instance(i - Agregados[t]).value(1);
}//if
}
}//for

//Ahora vuelvo a recorrer todos los tiempos
//Si coincide el ID con el menor, no hago nada, sino inserto una instancia vacia en ese tiempo
con ese ID
//En ese caso no incremento el i (lo chequeo de nuevo para ver si esta todo ok
for (t=0; t < m_NumTemporalUnits ; t++) {
if ( (i - Agregados[t]) < m_VectorInstances[t].numInstances()){
NuevaInstancia = m_VectorInstances[t].instance(i - Agregados[t]);
creoInstancia = false;
}else {//si el i no existe creo una nueva instancia
//Creo una instancia con el mismo Id y Tiempo, pero vacìa
vals = new double[m_VectorInstances[t].numAttributes()];
vals[0] = t;
vals[1] = IdMenor;
for (a=2; a < m_VectorInstances[t].numAttributes() ; a++) {
vals[2] = 0;
}
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 113 -
NuevaInstancia = new Instance(1.0,vals);
for (a=2; a < m_VectorInstances[t].numAttributes() ; a++) {
NuevaInstancia.setMissing(a);
}//for a
creoInstancia = true;
instancias_creadas ++;
Agregados[t]++;
}//else

//Ahora comparo si son iguales los valores, si acabo de agregar la instancia va a coincidir
//asì que la agrego directamente
if (NuevaInstancia.value(1) == IdMenor ){
m_VectorInstancesFinal[t].add(NuevaInstancia);
}else {
if (!creoInstancia){ //si no habia creado una instancia vacia la creo ahora
//Creo una instancia con el mismo Id y Tiempo, pero vacìa
vals = new double[m_VectorInstances[t].numAttributes()];
vals[0] = t;
vals[1] = IdMenor;
NuevaInstancia = new Instance(1.0,vals);
for (a=2; a < m_VectorInstances[t].numAttributes() ; a++) {
NuevaInstancia.setMissing(a);
}//for a
instancias_creadas ++;
Agregados[t]++;
}//if
m_VectorInstancesFinal[t].add(NuevaInstancia);
}
}//for

if (instancias_creadas < m_NumTemporalUnits){
converged = false;
instancias_creadas =0;
i++;
IdMenor = Double.MAX_VALUE;
}else if (instancias_creadas == m_NumTemporalUnits){
//si cree todas las instancias, quiere decir que llegué al final
converged = true;
//Tengo que borrar las m_NumTemporalUnits ultimas instancias
for (t=0; t < m_NumTemporalUnits ; t++) {
m_VectorInstancesFinal[t].delete(m_VectorInstancesFinal[t].numInstances() -1);
}
}

}//while

//Al final las agrego a la cola con push
for (t=0; t < m_NumTemporalUnits ; t++) {
for (i = 0; i < m_VectorInstancesFinal[t].numInstances(); i++) {
push(m_VectorInstancesFinal[t].instance(i));
}
}


}//fin metodo

public static void main(String [] argv) {

}
}
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 114 -
AtributosNumericos.class

/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


/****
* AtributosNumericos.java
* Octubre 2004 Maria Daniela Navas
*
****/

package weka.filters.unsupervised.attribute;

import weka.filters.*;
import java.io.*;
import java.util.*;
import weka.core.*;

/**
* Un filtro de instancias que normaliza los valores y tranforma los atributos
* nominales en numéricos, para utilizar con algoritmos que solo permitan atributos numéricos
*
* No necesita parámetros externos
*
* @author Maria Daniela Navas (mnavas@mnavas.com.ar)
* @version $Revision: 1.00 $
*/
public class AtributosNumericos extends Filter implements UnsupervisedFilter,
StreamableFilter, OptionHandler{

/** Guarda que columnas copiar */
protected Range m_CopyCols = new Range();

/**
* Guarda los indices de los atributos seleccionados
*/
protected int [] m_SelectedAttributes;

/**
* Contiene los indices de los atributos string de las instancias de entrada
*/
protected int [] m_InputStringIndex;

/**
* Matriz en donde se manejan las instancias
*/
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 115 -
protected double [][] MatrizInstancias;

/**
* para indicar la posicion de la matriz instancias
*/
private int pos=0;

//para normalizar los atributos numéricos
private double [] m_Min;
private double [] m_Max;


/**
* Devuelve una enumeracion de los parametros de entrada
*/
public Enumeration listOptions() {

Vector newVector = new Vector(1);

newVector.addElement(new Option(
"\tEspecifica una lista de columnas para incluir en el filtro. First y last son validos,\n"
+"\tindices. (default none)",
"R", 1, "-R <indice1,indice2-indice4,...>"));
newVector.addElement(new Option(
"\tInvierte selección (incluye las columnas no especificadas)",
"V", 0, "-V"));

return newVector.elements();
}

/**
* Parsea la lista de opciones
*
* -R index1,index2-index4,...<br>
* Especifica una lista de columnas para incluir en el filtro. First y last son validos
* (default none)<p>
*
* -V<br>
* nvierte selección (incluye las columnas no especificadas)
*
*/
public void setOptions(String[] options) throws Exception {

String copyList = Utils.getOption('R', options);
if (copyList.length() != 0) {
setAttributeIndices(copyList);
}
setInvertSelection(Utils.getFlag('V', options));

if (getInputFormat() != null) {
setInputFormat(getInputFormat());
}
}

/**
* Devuelve el seteo actual del filtro
*/
public String [] getOptions() {

String [] options = new String [3];
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 116 -
int current = 0;

if (getInvertSelection()) {
options[current++] = "-V";
}
if (!getAttributeIndices().equals("")) {
options[current++] = "-R"; options[current++] = getAttributeIndices();
}

while (current < options.length) {
options[current++] = "";
}
return options;
}

/**
* Setea el formato de las instancias de entrada
*
*/
public boolean setInputFormat(Instances instanceInfo) throws Exception {

super.setInputFormat(instanceInfo);

//vuelvo a cero la posición
pos=0;

int CantValores;
int dimensionActual=0;
double [][] MatrizExpansion;
double [][] MatrizAuxiliar;
int Seleccionado =0;
int SeleccionadoCorrido =0;
int [] m_SelectedAttributesCorridos;
int at;
int current;

// En output voy a guardar la salida
Instances outputFormat = new Instances(instanceInfo,0);

m_CopyCols.setUpper(instanceInfo.numAttributes() - 1);
m_SelectedAttributes = m_CopyCols.getSelection();
int inStrCopiedLen = 0;
int [] inStrCopied = new int[m_SelectedAttributes.length];

//******** NORMALIZACION *********++
//normalizo los atributos numéricos originales
m_Min = new double [instanceInfo.numAttributes()];
m_Max = new double [instanceInfo.numAttributes()];
for (int i = 0; i < instanceInfo.numAttributes(); i++) {
m_Min[i] = m_Max[i] = Double.NaN;
}

for (int i = 0; i < instanceInfo.numInstances(); i++) {
updateMinMax(instanceInfo.instance(i),instanceInfo.numAttributes());
}


//******* Calculo la dimensión que va a tener la nueva matriz.
int dimension=0;
int dimensionSeleccionados=0;
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 117 -
for (int i= 0 ; i< instanceInfo.numAttributes(); i++){
if (i == m_SelectedAttributes[Seleccionado]){
Seleccionado ++;
if (instanceInfo.attribute(i).type()==Attribute.NOMINAL){
//Si es nominal, sumo la cantidad de valores distintos que tiene
dimension = dimension + instanceInfo.numDistinctValues(instanceInfo.attribute(i)) -1;
dimensionSeleccionados = dimensionSeleccionados +
instanceInfo.numDistinctValues(instanceInfo.attribute(i)) -1;
}
else{ //si es numerico
dimension = dimension + 1;
dimensionSeleccionados = dimensionSeleccionados + 1;
}
}else{ //si no fue seleccionado
dimension = dimension +1;
}
}//for i

//Va a tener el valor que corresponda en las columnas seleccionadas y 0 en las otras
MatrizInstancias = new double [instanceInfo.numInstances()][dimension];

m_SelectedAttributesCorridos = new int[dimensionSeleccionados];


Seleccionado=0;
SeleccionadoCorrido=0;
//recorro los atributos, si es nominal, tengo que hacer la operación, sino copio directamente
for (at= 0 ; at < instanceInfo.numAttributes(); at++){
//Si el atributo está seleccionado -
if (at == m_SelectedAttributes[Seleccionado]){
current = m_SelectedAttributes[Seleccionado];
Seleccionado ++; //lo incremento para que la próxima sea el próximo seleccionado con el
que comparo

if(instanceInfo.attribute(current).type()== Attribute.NOMINAL){

CantValores = instanceInfo.numDistinctValues(instanceInfo.attribute(current));

//CantValores = cantidad distinta de valores que tiene ese atributo
//Creo una matriz del tamaño de CantValores x CantValores -1
MatrizExpansion = new double [CantValores][CantValores-1];
MatrizExpansion = ExpansionAtributos(CantValores);

MatrizAuxiliar = new double [instanceInfo.numInstances()][CantValores-1];
for (int j=0; j < instanceInfo.numInstances(); j++){
//si el atributo era missing, los valores de reemplazo deben ser missing
if (!instanceInfo.instance(j).isMissingValue(instanceInfo.instance(j).value(current))) {
for( int k=0; k < CantValores -1; k++){
MatrizAuxiliar [j][k] =
MatrizExpansion[(int)instanceInfo.instance(j).value(current)][k];
}//for k
}else{ //si el valor era missing
for( int k=0; k < CantValores -1; k++){
MatrizAuxiliar [j][k] = Double.NaN;
}//for k
}

}//for j


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 118 -
//Agrego los encabezados de los nuevos atributos
for (int i =0; i < CantValores -1; i++){

Attribute nuevoAtributo = new Attribute("Atributo Numerico " + i + " de " +
instanceInfo.attribute(current).name());
//Inserto el nuevo atributo numérico
outputFormat.insertAttributeAt(nuevoAtributo,dimensionActual + i);


for (int j =0; j < instanceInfo.numInstances(); j ++){
for( int k= dimensionActual; k < dimensionActual +CantValores -1; k++){
MatrizInstancias [j][k]= MatrizAuxiliar[j][k - dimensionActual];
}//for k
}//for j

//ahora se corrió la posición de los seleccionados, es seleccionado -1 porque ya lo
incrementé
m_SelectedAttributesCorridos[SeleccionadoCorrido] = dimensionActual +i;
SeleccionadoCorrido++;

}
//Sumo las dimensiones correspondientes
dimensionActual = dimensionActual + CantValores - 1;


//después de insertar los nuevos atributos, borro el anterior
outputFormat.deleteAttributeAt(dimensionActual);
}
if(instanceInfo.attribute(current).type()== Attribute.NUMERIC){

Attribute nuevoAtributo = instanceInfo.attribute(current);
//Acá inserta el atributo vacío
outputFormat.insertAttributeAt((Attribute) nuevoAtributo.copy(), dimensionActual);

for (int j=0; j < instanceInfo.numInstances(); j++){
//En lugar de guardar el valor numerico ya lo guardo normalizado
MatrizInstancias [j][dimensionActual]=
norm(instanceInfo.instance(j).value(current),current);
}//for j

//Si es numerico el atributo no cambia ya
m_SelectedAttributesCorridos [SeleccionadoCorrido]=dimensionActual;
SeleccionadoCorrido++;

//Sumo las dimensiones correspondientes
dimensionActual = dimensionActual + 1;

//después de insertar los nuevos atributos, borro el anterior
outputFormat.deleteAttributeAt(dimensionActual);

}

if(instanceInfo.attribute(current).type()== Attribute.STRING){
inStrCopied[inStrCopiedLen++] = current;
}

}else{ //las instancias quedan tal cual, sumo una dimensión más
dimensionActual = dimensionActual +1;
}

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 119 -
}
//lo dejo por compatibilidad
int [] origIndex = getInputStringIndex();
m_InputStringIndex = new int [origIndex.length + inStrCopiedLen];
System.arraycopy(origIndex, 0, m_InputStringIndex, 0, origIndex.length);
System.arraycopy(inStrCopied, 0, m_InputStringIndex, origIndex.length,
inStrCopiedLen);

//reasigno los seleccionados
m_SelectedAttributes = new int [dimensionSeleccionados];
System.arraycopy(m_SelectedAttributesCorridos, 0, m_SelectedAttributes, 0,
m_SelectedAttributesCorridos.length);

setOutputFormat(outputFormat);
return true;
}

/****
*
* Transforma los Atributos Categoricos a numericos con distancia = 1 entre todos los elementos
*
****/
private double [][] ExpansionAtributos(int CantValores) {

double [][] Matriz = new double[CantValores][CantValores -1];
Matriz [0][0] = 0.5;
Matriz [1][0] = - Matriz[0][0];
if (CantValores > 2){
Matriz[2][1] = Math.sqrt(1 - (Matriz [0][0] * Matriz [0][0]));
for (int i = 3; i < CantValores; i++){
for (int j = 1; j < i - 2; j++){
Matriz [i][j] = Matriz [i-1][j];
}
double aux = 0;
for (int j = 3; j < i; j++){
aux = aux + Matriz [j][j-2] * Matriz [j][j-2];
}
Matriz[i][i-2]=(2*((Matriz[2][1]*Matriz[2][1]) - aux)-1)/(2* Matriz[i-1][i-2]);
Matriz[i][i-1]= Math.sqrt((Matriz [i-1][i-2] * Matriz [i-1][i-2])- (Matriz[i][i-2]*Matriz[i][i-2]));
}

}
return Matriz;
}

/**
* Modifica el mínimo y máximo valor de cada atributo
*/
private void updateMinMax(Instance instance, int numAttributes) {

for (int j = 0;j < numAttributes; j++) {
if (!instance.isMissing(j)) {
if (Double.isNaN(m_Min[j])) {
m_Min[j] = instance.value(j);
m_Max[j] = instance.value(j);
} else {
if (instance.value(j) < m_Min[j]) {
m_Min[j] = instance.value(j);
} else {
if (instance.value(j) > m_Max[j]) {
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 120 -
m_Max[j] = instance.value(j);
}
}
}
}
}
}

/**
* Normaliza un valor dado
*
*/
private double norm(double x, int i) {

if (Double.isNaN(m_Min[i]) || Utils.eq(m_Max[i],m_Min[i])) {
return 0;
} else {
return x / (m_Max[i] - m_Min[i]);
}
}

/**
* Filtra la instancia
*/
public boolean input(Instance instance) {

if (getInputFormat() == null) {
throw new IllegalStateException("No input instance format defined");
}
if (m_NewBatch) {
resetQueue();
m_NewBatch = false;
}

int Seleccionado = 0;
double[] vals = new double[outputFormatPeek().numAttributes()];

//Asigno los valores correspondientes de la matriz de instancias
for (int i =0; i < outputFormatPeek().numAttributes(); i++){
if (i == m_SelectedAttributes[Seleccionado]){
Seleccionado++;
vals[i] = MatrizInstancias[pos][i];
}else{
vals[i] = instance.value(i);
}
}
pos = pos +1;

Instance inst = null;
if (instance instanceof SparseInstance) {
inst = new SparseInstance(instance.weight(), vals);
} else {
inst = new Instance(instance.weight(), vals);
}
copyStringValues(inst, false, instance.dataset(), m_InputStringIndex,
getOutputFormat(), getOutputStringIndex());
inst.setDataset(getOutputFormat());
push(inst);
return true;
}
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 121 -


/**
* Seteo el formato de salida
*/

public void setOutputFormat(Instances outputFormat) {

if (outputFormat != null) {
super.setOutputFormat(outputFormat);
outputFormatPeek().setRelationName(outputFormat.relationName());
}
}
/**
* Devuelve un string describiendo el filtro
*
*/
public String globalInfo() {

return "Un filtro de instancias que normaliza los valores numéricos "
+ "y tranforma los atributos nominales en numéricos, "
+ "para utilizar con algoritmos que solo permitan atributos numéricos";
}

/**
* Devuelve el tip text de esta propiedad
*/
public String invertSelectionTipText() {
return "Sets copy selected vs unselected action."
+ " If set to false, only the specified attributes will be copied;"
+ " If set to true, non-specified attributes will be copied.";
}

/**
* Toma el valor de esta propiedad
*/
public boolean getInvertSelection() {

return m_CopyCols.getInvert();
}

/**
* Setea el valor de la propiedad
*/
public void setInvertSelection(boolean invert) {

m_CopyCols.setInvert(invert);
}

/**
* Toma el valor de la propiedad
*/
public String getAttributeIndices() {

return m_CopyCols.getRanges();
}

/**
* Devuelve el tip text de esta propiedad
*/
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 122 -
public String attributeIndicesTipText() {
return "Specify range of attributes to act on."
+ " This is a comma separated list of attribute indices, with"
+ " \"first\" and \"last\" valid values. Specify an inclusive"
+ " range with \"-\". E.g: \"first-3,5,6-10,last\".";
}

/**
* Setea cuales atributos serán copiados y cuales no
*/
public void setAttributeIndices(String rangeList) throws Exception {

m_CopyCols.setRanges(rangeList);
}

/**
* Setea los indices
*/
public void setAttributeIndicesArray(int [] attributes) throws Exception {

setAttributeIndices(Range.indicesToRangeList(attributes));
}


public static void main(String [] argv) {


}
}


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 123 -
Temporal k-d-Median.class

/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
* Temporal_k_D_Median.java
* Octubre 2004 María Daniela Navas
*
*/
package weka.clusterers;

import java.io.*;
import java.util.*;
import java.lang.*;
import weka.core.*;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.ReplaceMissingValues;
import weka.filters.unsupervised.attribute.AtributosNumericos;

/**
* Temporal k_D_Median clustering class.
*
* Opciones válidas:<p>
*
* -N <numero de clusterss> <br>
* Especifica el número de clusters a generar. <p>
*
* @author María Daniela Navas (mnavas@mnavas.com.ar)
* @version $Revision: 1.0 $
* @see Clusterer
* @see OptionHandler
*/
public class Temporal_k_D_Median extends Clusterer implements OptionHandler {

/**
* Instancias del juego de datos
*/
private Instances m_instances;

/**
* Archivo donde se guardan los resultados
*/
private String m_NombreArchivo;

/**
* Atributos luego de filtrados por AtributosNumericos
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 124 -
*/
private AtributosNumericos m_AtributosNumericos;

/**
* Número de clusters a generar
*/
private int m_NumClusters = 2;

/**
* Número de Unidades Temporales
*/
private int m_NumTemporalUnits = 2;

//Matriz para guardar las instancias en cada unidad de tiempo
private Instances [] m_VectorInstances;
private Instances [] m_VectorInstancesSinFiltro;


/*Matriz para guardar los centroides*/
private Instances [] m_VectorClusterCentroids;
private Instances [] m_VectorClusterCentroidsInterno; //Este es el de los cálculos intermedios


//Matriz de CLusters asignados
private int [][] m_MatrixClusterAssignments;


/**
* Devuelve un string con la informacion
*/
public String globalInfo() {
return "Cluster data using the temporal k-D-Median algorithm";
}

/**
* Genera los clusters
*/
public void buildClusterer(Instances data) throws Exception {

//Variables generales
int t;
int c;
int i;
int j;
int a;
//Matriz donde guardo los pasajes de cluster para un tiempo dado
//2da dimension: cluster origen
//3era dimension : cluster destino
double [][] m_MatrixFinal;
//Vector que guardará que nro de cluster corresponde de un tiempo a otro
int [] m_VectorCambioCluster;
int [][][][] m_MatrixInestabilidad;

if (data.checkForStringAttributes()) {
throw new Exception("No se pueden manejar atributos String!");
}


//Verifico que el primer atributo se llame Temp (significa que ya pasó por el filtro
//CreateTemporalUnits
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 125 -
if (!data.attribute(0).name().equals("Temp")) {
throw new Exception("Antes de realizar el cluster debe aplicar el filtro
CreateTemporalUnits");
}else if (!data.attribute(1).name().equals("ID")){
throw new Exception("Antes de realizar el cluster debe aplicar el filtro CreateTemporalUnits");
}

//La cantidad de unidades temporales es la cantidad de valores distintos que tiene el atributo 0
m_NumTemporalUnits = data.numDistinctValues(0);

m_NombreArchivo = data.relationName() + "_C" + m_NumClusters + "_T" +
m_NumTemporalUnits;

//Inicializo los vectores de instancias sin filtro
m_VectorInstancesSinFiltro = new Instances [m_NumTemporalUnits];
for (t=0; t < m_NumTemporalUnits ; t++) {
m_VectorInstancesSinFiltro[t] = new Instances(data,0);
}

//Lleno el m_VectorInstancesSinFiltro con las instancias antes de pasarlas por el filtro numerico
int pos;
for (i = 0; i < data.numInstances(); i++) {
pos = (int)data.instance(i).value(0);
m_VectorInstancesSinFiltro[pos].add( data.instance(i));
}

m_AtributosNumericos = new AtributosNumericos();
String [] options = new String[3];
//Invierto la seleccion
options[0] = "-V";
//rango de atributos
options[1] = "-R";
options[2] = "1,2";
//rango de atributos que EXCLUYO (porque invertì la selecciòn)
//m_AtributosNumericos.setAttributeIndices("1,2");
m_AtributosNumericos.setOptions(options);
m_AtributosNumericos.setInputFormat(data);
m_instances = Filter.useFilter(data, m_AtributosNumericos);


m_VectorInstances = new Instances [m_NumTemporalUnits];
for (t=0; t < m_NumTemporalUnits ; t++) {
m_VectorInstances[t] = new Instances(m_instances,0);
}

/* Según el atributo 0 de la instancia en cuestión, agrego el atributo
al vector de instancias en la posición que corresponda*/
for (i = 0; i < m_instances.numInstances(); i++) {
pos = (int)m_instances.instance(i).value(0);
m_VectorInstances[pos].add( m_instances.instance(i));
}

//Vector para manejar los centroides para cada cluster de cada unidad temporal
m_VectorClusterCentroidsInterno = new Instances [m_NumTemporalUnits];
//Matriz donde para cada instancia, para cada unidad temporal, guardo el cluster asignado
m_MatrixClusterAssignments = new int[m_NumTemporalUnits][];

for (t= 0; t < m_NumTemporalUnits;t++) {
m_VectorClusterCentroidsInterno[t] = new Instances(m_VectorInstances[t],m_NumClusters);
m_MatrixClusterAssignments[t] = new int[m_VectorInstances[t].numInstances()];
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 126 -
}

//Uso como semilla la fecha actual
Date Fecha = new Date();
long m_Seed= Fecha.getTime();
Random Random0 = new Random(m_Seed);
int instIndex;
boolean HayRepetidos=false;
//Acá guardo los indices que voy eligiendo, para evitar que haya repetidos
int [] VectorIndices;

//Centroides iniciales
//Asigno al azar los centroides del primer tiempo
VectorIndices = new int [m_NumClusters];
for (i = 0; i < m_NumClusters; i++) {
instIndex = Math.abs(Random0.nextInt()) % m_VectorInstances[0].numInstances();
for (j=0; j < m_NumClusters; j++){
if (VectorIndices[j]== instIndex){
HayRepetidos = true;
break;
}
}//for
//Controlo también que no tenga ninguno de sus atributos missing (en ninguno de los tiempos
if (!HayRepetidos){
for(t=0; t < m_NumTemporalUnits; t++){
for(a=2; a < m_VectorInstances[t].numAttributes(); a++){
if
(m_VectorInstances[t].instance(instIndex).isMissingValue(m_VectorInstances[t].instance(instIndex
).value(a))){
HayRepetidos = true;
break;
}
} //for c
}//for t
}//if
while (HayRepetidos){
//vuelvo a generar un indice
instIndex = Math.abs(Random0.nextInt()) % m_VectorInstances[0].numInstances();

//vuelvo a preguntar
HayRepetidos = false;
for (j=0; j < m_NumClusters; j++){
if (VectorIndices[j]== instIndex){
HayRepetidos = true;
break;
}
}//for
//Controlo también que no tenga ninguno de sus atributos missing (en ninguno de los
tiempos
if (!HayRepetidos){
for(t=0; t < m_NumTemporalUnits; t++){
for(a=2; a < m_VectorInstances[t].numAttributes(); a++){
if
(m_VectorInstances[t].instance(instIndex).isMissingValue(m_VectorInstances[t].instance(instIndex
).value(a))){
HayRepetidos = true;
break;
}
} //for c
}//for t
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 127 -
}//if

}//while

//Agrego el centroide
m_VectorClusterCentroidsInterno[0].add(m_VectorInstances[0].instance(instIndex));
//Lo agrego a los indices
VectorIndices[i] = instIndex;
}//for i


//*** COMIENZO EL PROCESO DE CLUSTERING TEMPORAL
//Variables utilizadas
boolean converged;
boolean inestabilidad;
Instance toCluster;
int newC;
Instances tempI[];
double vals[];


for ( t = 0; t < m_NumTemporalUnits; t++) {
converged = false;
inestabilidad = false;
while (!converged && !inestabilidad) {
//reasigno las instancias
converged = true;
inestabilidad = true;

//Inicializo la matriz de Inestabilidad
//Si alguna instancia pasa mas 3 veces del mismo cluster al mismo cluster, quiere decir que
ya no converge
//y se queda ahí. Tengo que parar el algoritmo
m_MatrixInestabilidad = new
int[m_NumTemporalUnits][m_VectorInstances[t].numInstances()][m_NumClusters][m_NumCluster
s];

for (j = 0; j < m_VectorInstances[t].numInstances(); j++) {
toCluster = m_VectorInstances[t].instance(j);
newC = clusterProcessedInstance(toCluster,t);
if (newC != m_MatrixClusterAssignments[t][j]) {
converged = false;

//Controlo la inestabilidad
m_MatrixInestabilidad[t][j][m_MatrixClusterAssignments[t][j]][newC]++;
//Si alguna instancia pasa mas 3 veces del mismo cluster al mismo cluster, quiere decir
que ya no converge
//y se queda ahí. Tengo que parar el algoritmo
if (m_MatrixInestabilidad[t][j][m_MatrixClusterAssignments[t][j]][newC] > 3){
inestabilidad = false;
}
}//if
m_MatrixClusterAssignments[t][j] = newC;
}//for



m_VectorClusterCentroidsInterno[t] = new Instances(m_VectorInstances[t],m_NumClusters);

/*Tengo un tempI por cada dimension temporal - esto acumula los clusters*/
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 128 -
tempI = new Instances[m_NumClusters];
for (c = 0; c < m_NumClusters; c++) {
tempI[c] = new Instances(m_VectorInstances[t], 0);
}
for (j = 0; j < m_VectorInstances[t].numInstances(); j++) {
tempI[m_MatrixClusterAssignments[t][j]].add(m_VectorInstances[t].instance(j));
}

for (c= 0; c < m_NumClusters; c++) {
vals = new double[m_VectorInstances[t].numAttributes()];
vals= Centroide_K_D_Median(tempI[c]);
m_VectorClusterCentroidsInterno[t].add(new Instance(1.0, vals));
}//for c

}//while

//Las semillas del tiempo siguiente, son los centroides del tiempo anterior
if (t < (m_NumTemporalUnits -1)){
for (c=0; c < m_NumClusters; c++){
m_VectorClusterCentroidsInterno[t+1].add
(m_VectorInstances[t].instance((int)m_VectorClusterCentroidsInterno[t].instance(c).value(1)));
}//for c
}//if

}//for t


//Una vez que tengo la matriz con las asignaciones, creo la matriz final, con la cant de
individuos que pasaron de un cluster a otro
int orig;
int dest;
int ClusterAnt;
int ClusterActual;
double CantMax=-1;
int PosMax=0;
double Resultado=0;
double Total =0;
m_VectorClusterCentroids = new Instances [m_NumTemporalUnits];
int [][] m_MatrixComb;

//Armo las combinaciones posibles de intercambio de clusters.
//Lo hago acà para hacerlo una sola vez
m_MatrixComb = new int [factorial(m_NumClusters)][m_NumClusters];
m_MatrixComb = ArmarCombinacion(m_MatrixComb,m_NumClusters);

for (t= 0; t < m_NumTemporalUnits - 1; t++){

//la creo cada vez para inicializarla
m_MatrixFinal = new double[m_NumClusters][m_NumClusters];

//Calculo de a un cambio de tiempo a la vez
for (j= 0; j < m_VectorInstances[t].numInstances();j++){
orig = m_MatrixClusterAssignments[t][j];
dest = m_MatrixClusterAssignments[t+1][j];
m_MatrixFinal[orig][dest] = m_MatrixFinal[orig][dest] + 1;
}

//Normalizo la matriz final para que todos los valores estén en igualdad de condiciones
for (i=0; i < m_NumClusters; i++){
//Sumo el total
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 129 -
for (j=0; j < m_NumClusters; j++){
Total = Total + m_MatrixFinal[i][j];
}//for j
//Reemplazo esa fila
for (j=0; j < m_NumClusters; j++){
m_MatrixFinal[i][j] = m_MatrixFinal[i][j] / Total;
}//for j
Total =0;
}//for i


m_VectorCambioCluster = new int [m_NumClusters];

for (i=0; i < factorial(m_NumClusters); i++){
for (j=0; j < m_NumClusters; j ++ ){
Resultado = Resultado + m_MatrixFinal[m_MatrixComb[i][j]][j];
}//for j
if (Resultado > CantMax){
CantMax = Resultado;
PosMax = i;
}
Resultado =0;
}//for i

for (i=0; i < m_NumClusters; i++){
m_VectorCambioCluster[i] = m_MatrixComb[PosMax][i];
}//for i

//Cambio las asignaciones y los centroides correspondientes al siguiente tiempo (El tiempo 0
está correcto)
if (t==0){
m_VectorClusterCentroids[t] = new
Instances(m_VectorInstancesSinFiltro[t],m_NumClusters);
for (c=0; c < m_NumClusters; c++){
//En lugar de agregar la instancia despues del filtro ,agrego la que corresponde antes
del filtro
for (i= 0; i < m_VectorInstancesSinFiltro[t].numInstances(); i++){
//Comparo los ID de las instancias
if (m_VectorClusterCentroidsInterno[t].instance(c).value(1)==
m_VectorInstancesSinFiltro[t].instance(i).value(1)){
m_VectorClusterCentroids[t].add(m_VectorInstancesSinFiltro[t].instance(i));
}//if
}//for
}//for
}


//Ahora sumo de a una unidad temporal
//Recorro las instancias, para cambiar los clusters correspondientes
//NuevoCluster =0;
for (j=0; j < m_VectorInstances[t+1].numInstances(); j++){
ClusterAnt = m_MatrixClusterAssignments[t+1][j];
ClusterActual = m_VectorCambioCluster[ClusterAnt];
m_MatrixClusterAssignments[t+1][j]= ClusterActual;
}//for j

int posicion=0;
m_VectorClusterCentroids[t+1] = new
Instances(m_VectorInstancesSinFiltro[t+1],m_NumClusters);
for (c=0; c < m_NumClusters; c++){
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 130 -
//Busco entre la matriz de cambio cluster, cual es el destino = c
for(i=0; i < m_NumClusters; i++){
if (m_VectorCambioCluster[i] == c){
posicion = i;
}
}//for i
//En lugar de agregar la instancia despues del filtro ,agrego la que corresponde antes del
filtro
for (i= 0; i < m_VectorInstancesSinFiltro[t].numInstances(); i++){
//Comparo los ID de las instancias
if (m_VectorClusterCentroidsInterno[t+1].instance(posicion).value(1)==
m_VectorInstancesSinFiltro[t].instance(i).value(1)){
m_VectorClusterCentroids[t+1].add(m_VectorInstancesSinFiltro[t+1].instance(i));
}//if
}//for
}//for

}



//Guardo la matriz en un excel:
OutputStream Salida = new FileOutputStream(m_NombreArchivo + ".csv");
String linea = null;
String cluster = null;
boolean missing;
//El primer renglón de lineas tine CantInstancias, NumAtributos,NumClusters, NumUT
linea = m_VectorInstancesSinFiltro[0].numInstances() + "," +
(m_VectorInstancesSinFiltro[0].numAttributes()-2)+ "," + m_NumClusters + "," +
m_NumTemporalUnits;
Salida.write(linea.getBytes());

for (t= 0; t < m_NumTemporalUnits ; t++){
for (i= 0; i < m_VectorInstancesSinFiltro[t].numInstances(); i++){
linea ="";
cluster = "";
//solo imprimo los atributos distintos de Temp y Id
missing = true;
for (j= 2; j < m_VectorInstancesSinFiltro[t].numAttributes(); j++){
if
(!m_VectorInstancesSinFiltro[t].instance(i).isMissingValue(m_VectorInstancesSinFiltro[t].instance(i
).value(j))){
missing = false;
}
//diferencio si es missing o no
if (linea != ""){
if
(!m_VectorInstancesSinFiltro[t].instance(i).isMissingValue(m_VectorInstancesSinFiltro[t].instance(i
).value(j))){
linea = linea + "," + m_VectorInstancesSinFiltro[t].instance(i).toString(j);
}else{
linea = linea + "," + m_VectorInstancesSinFiltro[t].instance(i).value(j);
}
}else{
if
(!m_VectorInstancesSinFiltro[t].instance(i).isMissingValue(m_VectorInstancesSinFiltro[t].instance(i
).value(j))){
linea = "\n" + m_VectorInstancesSinFiltro[t].instance(i).toString(j);
}else{
linea = "\n" + m_VectorInstancesSinFiltro[t].instance(i).value(j);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 131 -
}
}
}
//Cuando copié todos los atributos, agrego el cluster correpondiente
//Si es missing, agrego un -2
if (missing) {
linea = linea + ",-2";
}else{
linea = linea + "," + m_MatrixClusterAssignments[t][i] ;
}
//Agrego la unidad temporal
linea = linea + "," + t;
//Si es el centroide de algún cluster lo agrego, sino asigno -1
for (c=0; c < m_NumClusters; c++){
//Comparo los ID de las instancias
if (m_VectorClusterCentroids[t].instance(c).value(1)==
m_VectorInstancesSinFiltro[t].instance(i).value(1)){
cluster = "," + c;
} else if (cluster==""){
cluster = ",-1";
}
}//for c
linea = linea + cluster;
Salida.write(linea.getBytes());
}//for i

}
Salida.close();



}

/*
*Proceso cada instancia pasada como parametro
*/
private int clusterProcessedInstance(Instance instance, int t) {
double minDist = Integer.MAX_VALUE;
double dist=0;
int i;

int bestCluster = 0;
for (i = 0; i < m_NumClusters; i++) {
dist = distance(instance, m_VectorClusterCentroidsInterno[t].instance(i));
if (dist < minDist) {
minDist = dist;
bestCluster = i;
}
}
return bestCluster;
}


public int clusterInstance(Instance instance) throws Exception {
return 0; //esto no hace nada, tiene que estar por compatibilidad con la clase padre!!
}

/**
* Calcula la distancia entre 2 instancias
*/
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 132 -

private double distance(Instance first, Instance second) {
double distance = 0;
double diff=Double.MAX_VALUE;
int i;

for (i=2; i < m_VectorInstances[0].numAttributes(); i++){
if ((!first.isMissingValue(first.value(i))) &&
(!second.isMissingValue(first.value(i)))){ //ninguno es Missing
diff = difference2(first.value(i), second.value(i));

}else{ //si hay alguno o los dos missing, devuelvo un nro muy grande
diff=Double.MAX_VALUE;
}
distance += diff * diff;
}//for



return Math.sqrt(distance);
}

/**
* Calcula la diferencia entre 2 valores
*/
private double difference2(double val1, double val2) {
double diff= Double.MAX_VALUE;
if (Instance.isMissingValue(val1) ||Instance.isMissingValue(val2)){ //si alguno es missing,
devuelvo un nro grande
diff = Double.MAX_VALUE;
}else{
diff= val1 - val2;
}
return diff;

}


/**
* Returns the number of clusters.
*
* @return the number of clusters generated for a training dataset.
* @exception Exception if number of clusters could not be returned
* successfully
*/
public int numberOfClusters() throws Exception {
return m_NumClusters;
}

/**
* Describe las opciones posibles. <p>
**/
public Enumeration listOptions () {
Vector newVector = new Vector(1);

newVector.addElement(new Option("\tnumber of clusters. (default = 2)."
, "N", 1, "-N <num>"));

return newVector.elements();
}
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 133 -

/**
* Devuelve el tip text para esta propiedad
*/
public String numClustersTipText() {
return "set number of clusters";
}

/**
* setea el número de clusters a generar
*/
public void setNumClusters(int n) {
m_NumClusters = n;
}

/**
* Devuelve el numero de clusters
*/
public int getNumClusters() {
return m_NumClusters;
}

/**
* Parsea la lista de opciones
**/
public void setOptions (String[] options)
throws Exception {

String optionString = Utils.getOption('N', options);

if (optionString.length() != 0) {
setNumClusters(Integer.parseInt(optionString));
}

}

/**
* Devuelve las opciones elegidas
*/
public String[] getOptions () {
String[] options = new String[2];
int current = 0;

options[current++] = "-N";
options[current++] = "" + getNumClusters();
while (current < options.length) {
options[current++] = "";
}

return options;
}

/**
* Devuelve un string describiendo el resultado del clustering
*/
public String toString() {
StringBuffer temp = new StringBuffer();

temp.append("\nTemporal_k_D_Median\n======\n");

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 134 -
for (int t = 0; t < m_NumTemporalUnits;t++) {
temp.append("\n\nCluster centroids for temporal unit "+(t+1)+":\n");

for (int i = 0; i < m_NumClusters; i++) {
temp.append("\nCluster "+(i+1)+"\n\t");
for (int j = 0; j < m_VectorClusterCentroids[t].numAttributes(); j++) {
if (m_VectorClusterCentroids[t].attribute(j).isNominal()) {
temp.append(" "+m_VectorClusterCentroids[t].attribute(j).
value((int)m_VectorClusterCentroids[t].instance(i).value(j)));
} else {
temp.append(" "+m_VectorClusterCentroids[t].instance(i).value(j));
}
}
temp.append("\n\n");
}
}
return temp.toString();
}

/******
* Encuentra el centroide de un grupo de individuos con el método k-d-Median
* SI SE DESEA ENCONTRAR EL CENTROIDE CON OTRO METODO, SE DEBE
REEMPLAZAR ESTA
* FUNCION !!!!
*/
private double [] Centroide_K_D_Median(Instances IndividuosOriginal) {

//Cantidad de individuos que tiene originalmente el vector Instances
int CantIndividuosOriginal = IndividuosOriginal.numInstances();

//Cantidad de Atributos que tiene una instancia
int CantAtributos = IndividuosOriginal.numAttributes();
//Cantidad de individuos que se irán filtrando en las iteraciones, original
//mente son todos
int CantIndividuos = CantIndividuosOriginal;

//Cantidad de individuos que se comparan para realizar los cálculos
int CantFiltros = 1;

//Individuos que resultarán de cada filtro, originalmente todos
Instances Individuos = new Instances(IndividuosOriginal);

//Valor que da fin al algoritmo iterativo
int Definicion = CantIndividuosOriginal;

//Vector que guardará los indices de los individuos seleccionados
int [] IndiceSeleccionados = new int [CantIndividuosOriginal];
for(int i=0; i< CantIndividuosOriginal; i++){
IndiceSeleccionados[i]=i;
}

// Inestabilidad: Si el sistema deja de filtrar luego de tres iteraciones
//se da por terminado.
int Inestabilidad=0;

//Defino el k-means de los individuos que no fueron filtrados
Instance xmeans = new Instance(IndividuosOriginal.numAttributes());
int []Indice;
int []IndiceOriginal;

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 135 -
//Variables generales
int i,j,k; //los voy a usar en los for
double [] aux;
double [] dist;
double MaximoAuxiliar;
int ContadorAuxiliar;
int [] IndiceIndividuo;
double ValorAuxiliar;
Instances Individuo;
double [] ValoresGravity;
double ValorGravityXmeans;
Instances IndividuosAux;
double [][] Gradiente;
double distAux;
double val1;
double val2;
double norma;
double aux2;
double [][] Filtro;
double [] VectorDiferencia;
Instances NuevosIndividuos;
int [] NuevoIndice;
int CantAnterior;
Instance OptimoFinal;
double [] ValoresFW;
double MinFW;
int IndiceMinFW;

//Comienza el proceso de iteración

while ((Definicion > 6) & (Inestabilidad < 1)) {

// Buscar Vector XMeans - Media para cada atributo
aux = new double[CantAtributos];
//los valores 0 y 1 no importan ya que no se comparan
aux[0]=0;
aux[1]=0;
for (i = 2; i < CantAtributos; i++) {
aux[i] = Individuos.meanOrMode(i);
}//for

//creo una instancia con los valores de los atributos
xmeans = new Instance(1.0, aux);

//%%%Encontrar los "CantFiltros" individuos mas cercanos a XMeans

//Genero un vector de doubles para guardar las distancias de los
//individuos a xmeans
dist = new double[CantIndividuos];

for (i=0; i < CantIndividuos; i++) {
dist[i] = distance(xmeans, Individuos.instance(i));
}

//Me fijo cuál es la máxima distancia
MaximoAuxiliar=0;
ContadorAuxiliar=0;
for (i=0; i< CantIndividuos;i++){
if (MaximoAuxiliar < dist[i]){
MaximoAuxiliar = dist[i];
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 136 -
ContadorAuxiliar = i;
}
}

//Busco los "CantFiltros" mínimos del vector distancia
//Recorro el vector "CantFiltros" veces, y en cada iteración encuentro
//el mínimo valor y lo anulo(con el valor máximo) para que en la siguiente
//vuelta el mínimo sea el siguiente valor
IndiceIndividuo= new int[CantFiltros];
ValorAuxiliar =0;
for (j=0; j<CantFiltros;j++){
ValorAuxiliar = MaximoAuxiliar;
for (i=0; i < CantIndividuos; i++) {
if (dist[i] < ValorAuxiliar) {
ValorAuxiliar = dist[i];
ContadorAuxiliar = i;
}
} //for i
IndiceIndividuo[j]=ContadorAuxiliar;
dist[ContadorAuxiliar]=MaximoAuxiliar;
}//for j

//Individuo son los "CantFiltros" más cercano a xmeans en este paso
Individuo = new Instances(Individuos,CantFiltros);
for (i=0;i<CantFiltros;i++){
Individuo.add(Individuos.instance(IndiceIndividuo[i]));
IndiceIndividuo[i] = IndiceSeleccionados[IndiceIndividuo[i]];
}

//% Calculo los Valores de FW para los individuos seleccionados y para xmeans
ValoresGravity = new double[CantFiltros];
for(i=0;i<CantFiltros; i++){
ValoresGravity[i]=0;
for (j=0; j < CantIndividuosOriginal; j++){
ValoresGravity[i] = ValoresGravity[i] +
distance(IndividuosOriginal.instance(IndiceIndividuo[i]),IndividuosOriginal.instance(j));
}//for j
}//for i

ValorGravityXmeans =0;
for (j=0; j < CantIndividuosOriginal; j++){
ValorGravityXmeans = ValorGravityXmeans +
distance(xmeans,IndividuosOriginal.instance(j));
}

ValorAuxiliar =0;
for (i=0; i < CantFiltros; i++){
if(ValorGravityXmeans > ValoresGravity[i]){
ValorAuxiliar = 1;
}
}

IndividuosAux = new Instances(Individuos,CantFiltros);
if (ValorAuxiliar==1){
ValorAuxiliar = ValoresGravity[0];
ContadorAuxiliar =0;
for (i =1; i <CantFiltros ; i++){
if(ValorAuxiliar < ValoresGravity[i]){
ValorAuxiliar = ValoresGravity[i];
ContadorAuxiliar=i;
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 137 -
}
}//for
for (i=0; i < CantFiltros; i++){
if (i == ContadorAuxiliar){
IndividuosAux.add(xmeans);
IndiceIndividuo[i] = -1; //para anularlo
}else{
IndividuosAux.add(Individuo.instance(i));
}
}
Individuo = new Instances(IndividuosAux);
}//if

// Encontrar el Gradiente Extendido para los Individuos Seleccionados
Gradiente = new double[CantFiltros][CantAtributos];
for (j=0; j< CantFiltros; j++){
for ( k=0; k < CantAtributos;k++){
Gradiente[j][k]=0;
}
}
for (j=0; j< CantFiltros; j++){
for ( i=0; i < CantIndividuosOriginal;i++){
distAux = distance(Individuo.instance(j),IndividuosOriginal.instance(i));
if (distAux > 0){
for ( k=2; k < CantAtributos;k++){
//esto es lo que debería irGradiente[j] = Gradiente [j] + (Individuo.attribute(j) -
RestoIndividuosOriginal.instance(i).attribute(j))/distAux;
//pero no puedo restar los atributos, por si son categoricos

//Val1 y Val22 son los valores de los atributos a restar pasados a formato interno
val1 = Individuo.instance(j).valueSparse(k);
val2 = IndividuosOriginal.instance(i).valueSparse(k);

Gradiente[j][k] = Gradiente [j][k] + difference2(val1,val2)/distAux;
}//for k
}//if
}//for i

norma = 0;
for ( k = 2; k < CantAtributos; k++){
norma = norma + (Gradiente[j][k] * Gradiente[j][k]);
}
norma = Math.sqrt(norma);
aux2 = 1 - 1 / norma;
if (aux2 > 0 ){
for ( k = 2; k < CantAtributos; k++){
Gradiente[j][k] = aux2 * Gradiente[j][k];
}//for
}
else{
for ( k = 2; k < CantAtributos; k++){
Gradiente[j][k] = 0;
}//for k
}//else
}//for j

// Calcular las Zonas de Filtrado:
Filtro = new double [CantIndividuos][CantFiltros];
VectorDiferencia = new double [CantAtributos];

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 138 -
for (i=0; i < CantFiltros; i++){
for ( j= 0 ; j < CantIndividuos; j++){
for ( k=2; k < CantAtributos ; k ++){
//Val1 y Val22 son los valores de los atributos a restar pasados a formato interno
val1 = Individuos.instance(j).valueSparse(k);
val2 = Individuo.instance(i).valueSparse(k);
VectorDiferencia[k]=difference2(val1,val2);
}//for k
Filtro[j][i]=0;
for ( k=2; k < CantAtributos ; k ++){
Filtro[j][i] = Filtro[j][i] - VectorDiferencia[k] * Gradiente[i][k];
}//for k
}//for j
}//for i



// Encuentro los Individuos que no fueron Filtrados.........
NuevosIndividuos = new Instances(Individuos,0);
NuevoIndice = new int[CantIndividuos];
ContadorAuxiliar = 0;

for (i=0; i<CantIndividuos; i++){
ValorAuxiliar=1;
for (j=0; j<CantFiltros; j++){
if (Filtro[i][j]<0){
ValorAuxiliar =0;
}
}//for j

if (ValorAuxiliar==1){
NuevosIndividuos.add(Individuos.instance(i));
NuevoIndice[ContadorAuxiliar]=IndiceSeleccionados[i];
ContadorAuxiliar++;
}
}//for i

//Reasigno los valores
CantAnterior= CantIndividuos;
CantIndividuos = ContadorAuxiliar;

//%%% Si durante 3 ciclos no se filtra ningún individuo, se sale del algoritmo iterativo.
if(CantIndividuos==CantAnterior){
Inestabilidad=Inestabilidad+1;
}
else{
Inestabilidad=0;
}

//reasigno IndiceSeleccionados
IndiceSeleccionados = new int [ContadorAuxiliar];
//reasigno los individuos
Individuos = new Instances(NuevosIndividuos, ContadorAuxiliar);

for (i=0;i<ContadorAuxiliar;i++){
IndiceSeleccionados[i] = NuevoIndice[i];
Individuos.add(NuevosIndividuos.instance(i));

}

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 139 -
Definicion=CantIndividuos;

}//while


if (Inestabilidad < 1){
//%%%%% Busco a mano los valores de FW para los individuos que quedaron....
ValoresFW = new double [CantIndividuos];
for (i=0; i< CantIndividuos;i++){
ValoresFW[i]=0;
for (j=0; j < CantIndividuosOriginal;j++){
ValoresFW[i] = ValoresFW[i] +
distance(Individuos.instance(i),IndividuosOriginal.instance(j));
}
}

//%%% optimofinal: Valor de menor FW (obtenido manualmente
//%%% luego del proceso de filtrado).
MinFW = ValoresFW[0];
IndiceMinFW = 0;
for (i=1; i < CantIndividuos; i++){
if (ValoresFW[i] < MinFW ){
MinFW = ValoresFW[i];
IndiceMinFW = i;
}
}//for
OptimoFinal = new Instance(Individuos.instance(IndiceMinFW));
}
else{ //si Inestabilidad es mayor o igual a 1

dist = new double[CantIndividuos];

for (i=0; i < CantIndividuos; i++) {
dist[i] = distance(xmeans, Individuos.instance(i));
}


//Busco los "CantFiltros" mínimos del vector distancia
//Recorro el vector "CantFiltros" veces, y en cada iteración encuentro
//el mínimo valor y lo anulo(con el valor máximo) para que en la siguiente
//vuelta el mínimo sea el siguiente valor
MaximoAuxiliar=0;
ContadorAuxiliar=0;
for (i=0; i< CantIndividuos;i++){
if (MaximoAuxiliar < dist[i]){
MaximoAuxiliar = dist[i];
ContadorAuxiliar = i;
}
}

ValorAuxiliar =MaximoAuxiliar;
for (i=0; i < CantIndividuos; i++) {
if (dist[i] < ValorAuxiliar) {
ValorAuxiliar = dist[i];
ContadorAuxiliar = i;
}
} //for i

//no lo uso int IndiceFinal = IndiceSeleccionados[ContadorAuxiliar];
OptimoFinal = new Instance(Individuos.instance(ContadorAuxiliar)); //hay un solo elemento
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 140 -



}//else
return OptimoFinal.toDoubleArray();

}

/**
*Factorial de un numero
*/
private int factorial(int x) {
int fact=0;
if (x == 0)
{ fact =1;}
else if (x == 1)
{fact = 1;}
else
{fact = x * factorial (x-1);}
return fact;
}

/*
*Arma una matriz con la combinatoria de posibilidades de una matriz de NxN,
*donde N es el número de clusters.
*/
private int [][] ArmarCombinacion(int [][] Matriz, int tamanio) {

int valor;
int [][] MatrizNueva;
int i, j,c,d;
if (tamanio ==2){
Matriz[0][0]=0;
Matriz[0][1]=1;
Matriz[1][0]=1;
Matriz[1][1]=0;
}else {
valor = factorial(tamanio-1);
for (i=0; i < tamanio; i++){
for (j=0; j < valor; j++){
Matriz[(i*valor) + j][i] = tamanio -1;
}//for j
MatrizNueva = new int [valor][tamanio -1];
MatrizNueva = ArmarCombinacion (MatrizNueva,tamanio-1);
for (c=0; c <valor;c++){
for(d=0; d < tamanio; d++){
if (d < i){
Matriz[(i*valor) + c][d] = MatrizNueva[c][d];
}else if (d > i){
Matriz[(i*valor) + c][d] = MatrizNueva[c][d-1];
}

}//for d

}//for c

}//for i

}//else
return Matriz;
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 141 -

}


public static void main (String[] argv) {
try {
System.out.println(ClusterEvaluation.
evaluateClusterer(new Temporal_k_D_Median(), argv));
}
catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 142 -
A2.2 MATLAB

Análisis Resultados.m

function varargout = AnalisisResultados(varargin)
% RESULTADOS Application M-file for AnalisisResultados.fig
% FIG = RESULTADOS launch AnalisisResultados GUI.
% RESULTADOS('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 15-May-2004 12:42:02

if nargin == 0 % LAUNCH GUI

fig = openfig(mfilename,'reuse');

% Generate a structure of handles to pass to callbacks, and store it.
handles = guihandles(fig);
guidata(fig, handles);

%Para mostrar el Logo
[a,b,c] = imread('clustering.ico');
% Augment colormap for background color (white).
b2 = [b; 1 1 1];
% Create new image for display.
d = ones(size(a)) * (length(b2) - 1);
% Use the AND mask to mix the background and
% foreground data on the new image
d(c == 0) = a(c == 0);
% Display new image
imshow(uint8(d), b2)
axis off;

if nargout > 0
varargout{1} = fig;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 143 -
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

function varargout = cmdAbrir_Callback(h, eventdata, handles, varargin)
[fname,pname] = uigetfile('*.csv','Seleccione el archivo a utilizar');

%Creo las variables y las guardo como globales
MatrizCompleta=csvread([pname,fname]);
handles.MatrizCompleta = MatrizCompleta;

Individuos=MatrizCompleta(1,1);
handles.Individuos = Individuos;

Atributos=MatrizCompleta(1,2);
handles.Atributos = Atributos;

CantClusters=MatrizCompleta(1,3);
handles.CantClusters = CantClusters;

IntervalosTiempo=MatrizCompleta(1,4);
handles.IntervalosTiempo = IntervalosTiempo;

guidata(handles.Figura,handles);

%Habilito o deshabilito los botones segun corresponda
set(handles.txtNombreArchivo,'string',fname);
if(Atributos==2)
set(handles.cmdGraficos2D,'Enable','on');
set(handles.cmdGraficos2DTiempo,'Enable','on');
set(handles.cmdGraficos3D,'Enable','off');
set(handles.cmdGraficos3DTiempo,'Enable','off');
end

if(Atributos==3)
set(handles.cmdGraficos3D,'Enable','on');
set(handles.cmdGraficos3DTiempo,'Enable','on');
set(handles.cmdGraficos2D,'Enable','off');
set(handles.cmdGraficos2DTiempo,'Enable','off');
end

set(handles.cmdAtributo,'Enable','on');
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 144 -
set(handles.cmdPerdidos,'Enable','on');
set(handles.cmdIndividuos,'Enable','on');


function varargout = cmdGraficos2D_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = GRAFICOS2D;


function varargout = cmdGraficos3D_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = GRAFICOS3D;

function varargout = cmdGraficos2DTiempo_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = GRAFICOS2DTiempo;

function varargout = cmdGraficos3DTiempo_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = GRAFICOS3DTiempo;


function varargout = cmdAtributo_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = ATRIBUTOS;


function varargout = cmdIndividuos_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = ESTADISTICAS;


function varargout = cmdPerdidos_Callback(h, eventdata, handles, varargin)

setappdata(handles.Figura,'handles',handles);
fig = PERDIDOS;

function varargout = txtNombreArchivo_Callback(h, eventdata, handles, varargin)


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 145 -
Graficos2D.m

function varargout = Graficos2D(varargin)
% GRAFICOS2D Application M-file for Graficos2D.fig
% FIG = GRAFICOS2D launch Graficos2D GUI.
% GRAFICOS2D('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 12-May-2004 22:35:32

if nargin == 0 % LAUNCH GUI

fig2 = openfig(mfilename,'reuse');
set(fig2,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles2 = guihandles(fig2);

handlesAnt = getappdata(1,'handles');
handles2.MatrizCompleta = handlesAnt.MatrizCompleta;
handles2.Individuos = handlesAnt.Individuos;
handles2.Atributos = handlesAnt.Atributos;
handles2.CantClusters = handlesAnt.CantClusters;
handles2.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles2.i=0;
guidata(fig2, handles2);

if nargout > 0
varargout{1} = fig2;
end



elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 146 -
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.



% --------------------------------------------------------------------
function varargout = cmdTiempoSiguiente_Callback(h, eventdata, handles2, varargin)

set(handles2.txtMensaje,'Visible','off');
i = handles2.i +1;
set (handles2.txtTiempo,'String',i);


for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2)
matriz = [matriz; handles2.MatrizCompleta(k,[1:handles2.Atributos])];
end
end

%tengo que excluir los que vienen con -2
for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2)
colores = [colores; handles2.MatrizCompleta(k,3)];
end
end

matriz1=handles2.MatrizCompleta([(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)],5);

for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2) %si es -2 lo excluyo
if (handles2.MatrizCompleta(k,5)==-1) %si es -1 no es centroide
medidas = [medidas;10];
else % si no es -1 es centroide, y lo dibujo mas grande
medidas = [medidas;50];
end
end
end


auxiliar1=find(matriz1==-1);

%Dibujo primero los centroides
matriz2 = [];
colores2=[];
auxiliar2 = find(matriz1 ~= -1);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 147 -
for k=1:handles2.CantClusters
matriz2 = [matriz2; handles2.MatrizCompleta((1+(i-1)*handles2.Individuos) +
auxiliar2(k),[1:handles2.Atributos])];
colores2 = [colores2; handles2.MatrizCompleta((1+(i-1)*handles2.Individuos)
+auxiliar2(k),3)];
end
%ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda
colores2 = sort(colores2);

medidas2 = ones(handles2.CantClusters,1) * 50;
scatter(matriz2(:,1),matriz2(:,2),medidas2,colores2);

%Armo la leyenda con los centroides
a='Cluster-';
leg=[];
for k=1:handles2.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);

hold on;

scatter(matriz(:,1),matriz(:,2),medidas,colores);
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles2.i = i;
guidata(gcbo,handles2);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles2.IntervalosTiempo)
set(handles2.cmdTiempoSiguiente,'Enable','off');
else
set(handles2.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles2.cmdTiempoAnterior,'Enable','off');
else
set(handles2.cmdTiempoAnterior,'Enable','on');
end


set(handles2.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');


% --------------------------------------------------------------------
function varargout = cmdTiempoAnterior_Callback(h, eventdata, handles2, varargin)

i = handles2.i -1;
set (handles2.txtTiempo,'String',i);


for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2)
matriz = [matriz; handles2.MatrizCompleta(k,[1:handles2.Atributos])];
end
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 148 -
end

%tengo que excluir los que vienen con -2
for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2)
colores = [colores; handles2.MatrizCompleta(k,3)];
end
end

matriz1=handles2.MatrizCompleta([(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)],5);

for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)
if (handles2.MatrizCompleta(k,3)~=-2) %si es -2 lo excluyo
if (handles2.MatrizCompleta(k,5)==-1) %si es -1 no es centroide
medidas = [medidas;10];
else % si no es -1 es centroide, y lo dibujo mas grande
medidas = [medidas;50];
end
end
end


auxiliar1=find(matriz1==-1);

%Dibujo primero los centroides
matriz2 = [];
colores2=[];
auxiliar2 = find(matriz1 ~= -1);
for k=1:handles2.CantClusters
matriz2 = [matriz2; handles2.MatrizCompleta((1+(i-1)*handles2.Individuos) +
auxiliar2(k),[1:handles2.Atributos])];
colores2 = [colores2; handles2.MatrizCompleta((1+(i-1)*handles2.Individuos)
+auxiliar2(k),3)];
end
%ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda
colores2 = sort(colores2);


medidas2 = ones(handles2.CantClusters,1) * 50;
scatter(matriz2(:,1),matriz2(:,2),medidas2,colores2);

%Armo la leyenda con los centroides
a='Cluster-';
leg=[];
for k=1:handles2.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);

hold on;
scatter(matriz(:,1),matriz(:,2),medidas,colores);
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles2.i = i;
guidata(gcbo,handles2);

%deshabilito el boton si no hay mas tiempos siguientes
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 149 -
if (i==handles2.IntervalosTiempo)
set(handles2.cmdTiempoSiguiente,'Enable','off');
else
set(handles2.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles2.cmdTiempoAnterior,'Enable','off');
else
set(handles2.cmdTiempoAnterior,'Enable','on');
end

set(handles2.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 150 -
Graficos2DTiempo.m

function varargout = Graficos2DTiempo(varargin)
% GRAFICOS2DTIEMPO Application M-file for Graficos2DTiempo.fig
% FIG = GRAFICOS2DTIEMPO launch Graficos2DTiempo GUI.
% GRAFICOS2DTIEMPO('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 15-May-2004 17:42:26

if nargin == 0 % LAUNCH GUI

fig5 = openfig(mfilename,'reuse');
set(fig5,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles5 = guihandles(fig5);

handlesAnt = getappdata(1,'handles');
handles5.MatrizCompleta = handlesAnt.MatrizCompleta;
handles5.Individuos = handlesAnt.Individuos;
handles5.Atributos = handlesAnt.Atributos;
handles5.CantClusters = handlesAnt.CantClusters;
handles5.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles5.i=0;

guidata(fig5, handles5);

if nargout > 0
varargout{1} = fig5;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 151 -
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.



% --------------------------------------------------------------------
function varargout = cmdClusterSiguiente_Callback(h, eventdata, handles5, varargin)

set(handles5.txtMensaje,'Visible','off');

i = handles5.i +1;
set (handles5.txtCluster,'String',i);

auxiliar1=size(handles5.MatrizCompleta);
auxiliar1=auxiliar1(1);
auxiliar=find(handles5.MatrizCompleta([2:auxiliar1],handles5.Atributos+1)==(i-1));
matriz=handles5.MatrizCompleta([2:auxiliar1],[1:handles5.Atributos+3]);
matriz=matriz(auxiliar,:);
auxiliar=size(matriz);
auxiliar=auxiliar(1);
medidas=10*ones(auxiliar,1);
auxiliar1=find(matriz(:,handles5.Atributos+3)==(i-1));
medidas(auxiliar1)=50;
colores=matriz(:,4);

auxiliar=size(handles5.MatrizCompleta);
auxiliar=auxiliar(1);
Eje1=max(handles5.MatrizCompleta([2:auxiliar],1))*1.1;
Eje2=max(handles5.MatrizCompleta([2:auxiliar],2))*1.1;
axis([0 Eje1 0 Eje2]);
Clusters=matriz(auxiliar1,:);

%Dibujo primero los centroides
medidas2 = ones(handles5.IntervalosTiempo,1) * 50;
colores2=Clusters(:,4);
scatter(Clusters(:,1),Clusters(:,2),medidas2,colores2);
hold on;
%inserto la leyenda
a='Tiempo-';
leg=[];
for k=1:handles5.IntervalosTiempo
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 152 -
%fin leyenda

scatter(matriz(:,1),matriz(:,2),medidas,colores);


for j=1:(handles5.IntervalosTiempo-1)
line(Clusters([j:j+1],1),Clusters([j:j+1],2));
end
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles5.i = i;
guidata(gcbo,handles5);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles5.CantClusters)
set(handles5.cmdClusterSiguiente,'Enable','off');
else
set(handles5.cmdClusterSiguiente,'Enable','on');
end
if (i==1)
set(handles5.cmdClusterAnterior,'Enable','off');
else
set(handles5.cmdClusterAnterior,'Enable','on');
end


set(handles5.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');

% --------------------------------------------------------------------
function varargout = cmdClusterAnterior_Callback(h, eventdata, handles5, varargin)

i = handles5.i -1;
set (handles5.txtCluster,'String',i);

auxiliar1=size(handles5.MatrizCompleta);
auxiliar1=auxiliar1(1);
auxiliar=find(handles5.MatrizCompleta([2:auxiliar1],handles5.Atributos+1)==(i-1));
matriz=handles5.MatrizCompleta([2:auxiliar1],[1:handles5.Atributos+3]);
matriz=matriz(auxiliar,:);
auxiliar=size(matriz);
auxiliar=auxiliar(1);
medidas=10*ones(auxiliar,1);
auxiliar1=find(matriz(:,handles5.Atributos+3)==(i-1));
medidas(auxiliar1)=50;
colores=matriz(:,4);

auxiliar=size(handles5.MatrizCompleta);
auxiliar=auxiliar(1);
Eje1=max(handles5.MatrizCompleta([2:auxiliar],1))*1.1;
Eje2=max(handles5.MatrizCompleta([2:auxiliar],2))*1.1;
axis([0 Eje1 0 Eje2]);
Clusters=matriz(auxiliar1,:);

%Dibujo primero los centroides
medidas2 = ones(handles5.IntervalosTiempo,1) * 50;
colores2=Clusters(:,4);
scatter(Clusters(:,1),Clusters(:,2),medidas2,colores2);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 153 -
hold on;
%inserto la leyenda
a='Tiempo-';
leg=[];
for k=1:handles5.IntervalosTiempo
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);
%fin leyenda

scatter(matriz(:,1),matriz(:,2),medidas,colores);

for j=1:(handles5.IntervalosTiempo-1)
line(Clusters([j:j+1],1),Clusters([j:j+1],2));
end
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles5.i = i;
guidata(gcbo,handles5);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles5.CantClusters)
set(handles5.cmdClusterSiguiente,'Enable','off');
else
set(handles5.cmdClusterSiguiente,'Enable','on');
end
if (i==1)
set(handles5.cmdClusterAnterior,'Enable','off');
else
set(handles5.cmdClusterAnterior,'Enable','on');
end


set(handles5.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 154 -
Graficos3D.m

function varargout = Graficos3D(varargin)
% GRAFICOS3D Application M-file for Graficos3D.fig
% FIG = GRAFICOS3D launch Graficos3D GUI.
% GRAFICOS3D('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 16-May-2004 23:17:36

if nargin == 0 % LAUNCH GUI

fig6 = openfig(mfilename,'reuse');
set(fig6,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles6 = guihandles(fig6);

handlesAnt = getappdata(1,'handles');
handles6.MatrizCompleta = handlesAnt.MatrizCompleta;
handles6.Individuos = handlesAnt.Individuos;
handles6.Atributos = handlesAnt.Atributos;
handles6.CantClusters = handlesAnt.CantClusters;
handles6.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles6.i=0;

guidata(fig6, handles6);

if nargout > 0
varargout{1} = fig6;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 155 -
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

% --------------------------------------------------------------------
function varargout = cmdTiempoSiguiente_Callback(h, eventdata, handles6, varargin)

set(handles6.txtMensaje,'Visible','off');

i = handles6.i +1;
set (handles6.txtTiempo,'String',i);

for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2)
matriz = [matriz; handles6.MatrizCompleta(k,[1:handles6.Atributos])];
end
end


for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2)
colores = [colores; handles6.MatrizCompleta(k,4)];
end
end


matriz1=handles6.MatrizCompleta([(2+(i-
1)*handles6.Individuos):(i*handles6.Individuos+1)],handles6.Atributos+3);


for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2) %si es -2 lo excluyo
if (handles6.MatrizCompleta(k,6)==-1) %si es -1 no es centroide
medidas = [medidas;10];
else % si no es -1 es centroide, y lo dibujo mas grande
medidas = [medidas;50];
end
end
end

auxiliar1=find(matriz1==-1);


%Dibujo primero los centroides
matriz2 = [];
colores2=[];
auxiliar2 = find(matriz1 ~= -1);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 156 -
for k=1:handles6.CantClusters
matriz2 = [matriz2; handles6.MatrizCompleta((1+(i-1)*handles6.Individuos) +
auxiliar2(k),[1:handles6.Atributos])];
colores2 = [colores2; handles6.MatrizCompleta((1+(i-1)*handles6.Individuos) +
auxiliar2(k),4)];
end
%ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda
colores2 = sort(colores2);

medidas2 = ones(handles6.CantClusters,1) * 50;
scatter3(matriz2(:,1),matriz2(:,2),matriz2(:,3),medidas2,colores2);

%Armo la leyenda con los centroides
a='Cluster-';
leg=[];
for k=1:handles6.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);

hold on;

scatter3(matriz(:,1),matriz(:,2),matriz(:,3),medidas,colores);
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles6.i = i;
guidata(gcbo,handles6);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles6.IntervalosTiempo)
set(handles6.cmdTiempoSiguiente,'Enable','off');
else
set(handles6.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles6.cmdTiempoAnterior,'Enable','off');
else
set(handles6.cmdTiempoAnterior,'Enable','on');
end


set(handles6.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');
zlabel('Atributo 3');


% --------------------------------------------------------------------
function varargout = cmdTiempoAnterior_Callback(h, eventdata, handles6, varargin)

i = handles6.i -1;
set (handles6.txtTiempo,'String',i);


for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2)
matriz = [matriz; handles6.MatrizCompleta(k,[1:handles6.Atributos])];
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 157 -
end
end

for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2)
colores = [colores; handles6.MatrizCompleta(k,4)];
end
end


matriz1=handles6.MatrizCompleta([(2+(i-
1)*handles6.Individuos):(i*handles6.Individuos+1)],handles6.Atributos+3);

medidas = [];
for k=(2+(i-1)*handles6.Individuos):(i*handles6.Individuos+1)
if (handles6.MatrizCompleta(k,4)~=-2) %si es -2 lo excluyo
if (handles6.MatrizCompleta(k,6)==-1) %si es -1 no es centroide
medidas = [medidas;10];
else % si no es -1 es centroide, y lo dibujo mas grande
medidas = [medidas;50];
end
end
end

auxiliar1=find(matriz1==-1);


%Dibujo primero los centroides
matriz2 = [];
colores2=[];
auxiliar2 = find(matriz1 ~= -1);
for k=1:handles6.CantClusters
matriz2 = [matriz2; handles6.MatrizCompleta((1+(i-1)*handles6.Individuos) +
auxiliar2(k),[1:handles6.Atributos])];
colores2 = [colores2; handles6.MatrizCompleta((1+(i-1)*handles6.Individuos)
+auxiliar2(k),4)];
end
%ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda
colores2 = sort(colores2);

medidas2 = ones(handles6.CantClusters,1) * 50;
scatter3(matriz2(:,1),matriz2(:,2),matriz2(:,3),medidas2,colores2);

%Armo la leyenda con los centroides
a='Cluster-';
leg=[];
for k=1:handles6.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);

hold on;

scatter3(matriz(:,1),matriz(:,2),matriz(:,3),medidas,colores);
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles6.i = i;
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 158 -
guidata(gcbo,handles6);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles6.IntervalosTiempo)
set(handles6.cmdTiempoSiguiente,'Enable','off');
else
set(handles6.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles6.cmdTiempoAnterior,'Enable','off');
else
set(handles6.cmdTiempoAnterior,'Enable','on');
end


set(handles6.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');
zlabel('Atributo 3');



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 159 -
Graficos3DTiempo.m

function varargout = Graficos3DTiempo(varargin)
% GRAFICOS3DTIEMPO Application M-file for Graficos3DTiempo.fig
% FIG = GRAFICOS3DTIEMPO launch Graficos3DTiempo GUI.
% GRAFICOS3DTIEMPO('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 16-May-2004 23:39:47

if nargin == 0 % LAUNCH GUI

fig7 = openfig(mfilename,'reuse');
set(fig7,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles7 = guihandles(fig7);

handlesAnt = getappdata(1,'handles');
handles7.MatrizCompleta = handlesAnt.MatrizCompleta;
handles7.Individuos = handlesAnt.Individuos;
handles7.Atributos = handlesAnt.Atributos;
handles7.CantClusters = handlesAnt.CantClusters;
handles7.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles7.i=0;

guidata(fig7, handles7);

if nargout > 0
varargout{1} = fig7;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 160 -
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

% --------------------------------------------------------------------
function varargout = cmdClusterSiguiente_Callback(h, eventdata, handles7, varargin)

set(handles7.txtMensaje,'Visible','off');

i = handles7.i +1;
set (handles7.txtCluster,'String',i);

auxiliar1=size(handles7.MatrizCompleta);
auxiliar1=auxiliar1(1);
auxiliar=find(handles7.MatrizCompleta([2:auxiliar1],handles7.Atributos+1)==(i-1));
matriz=handles7.MatrizCompleta([2:auxiliar1],[1:handles7.Atributos+3]);
matriz=matriz(auxiliar,:);
auxiliar=size(matriz);
auxiliar=auxiliar(1);
medidas=10*ones(auxiliar,1);
auxiliar1=find(matriz(:,handles7.Atributos+3)==(i-1));
medidas(auxiliar1)=50;
colores=matriz(:,handles7.Atributos+2);

Clusters=matriz(auxiliar1,:);


%Dibujo primero los centroides
medidas2 = ones(handles7.IntervalosTiempo,1) * 50;
colores2=Clusters(:,5);
scatter3(Clusters(:,1),Clusters(:,2),Clusters(:,3),medidas2,colores2);
hold on;
%inserto la leyenda
a='Tiempo-';
leg=[];
for k=1:handles7.IntervalosTiempo
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);
%fin leyenda

scatter3(matriz(:,1),matriz(:,2),matriz(:,3),medidas,colores);

for j=1:(handles7.IntervalosTiempo-1)
line(Clusters([j:j+1],1),Clusters([j:j+1],2),Clusters([j:j+1],3));
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 161 -
end
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles7.i = i;
guidata(gcbo,handles7);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles7.CantClusters)
set(handles7.cmdClusterSiguiente,'Enable','off');
else
set(handles7.cmdClusterSiguiente,'Enable','on');
end
if (i==1)
set(handles7.cmdClusterAnterior,'Enable','off');
else
set(handles7.cmdClusterAnterior,'Enable','on');
end


set(handles7.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');
zlabel('Atributo 3');


% --------------------------------------------------------------------
function varargout = cmdClusterAnterior_Callback(h, eventdata, handles7, varargin)

i = handles7.i-1;
set (handles7.txtCluster,'String',i);

auxiliar1=size(handles7.MatrizCompleta);
auxiliar1=auxiliar1(1);
auxiliar=find(handles7.MatrizCompleta([2:auxiliar1],handles7.Atributos+1)==(i-1));
matriz=handles7.MatrizCompleta([2:auxiliar1],[1:handles7.Atributos+3]);
matriz=matriz(auxiliar,:);
auxiliar=size(matriz);
auxiliar=auxiliar(1);
medidas=10*ones(auxiliar,1);
auxiliar1=find(matriz(:,handles7.Atributos+3)==(i-1));
medidas(auxiliar1)=50;
colores=matriz(:,handles7.Atributos+2);

Clusters=matriz(auxiliar1,:);


%Dibujo primero los centroides
medidas2 = ones(handles7.IntervalosTiempo,1) * 50;
colores2=Clusters(:,5);
scatter3(Clusters(:,1),Clusters(:,2),Clusters(:,3),medidas2,colores2);
hold on;
%inserto la leyenda
a='Tiempo-';
leg=[];
for k=1:handles7.IntervalosTiempo
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 162 -
legend(leg);
%fin leyenda

scatter3(matriz(:,1),matriz(:,2),matriz(:,3),medidas,colores);

for j=1:(handles7.IntervalosTiempo-1)
line(Clusters([j:j+1],1),Clusters([j:j+1],2),Clusters([j:j+1],3));
end
hold off;

%cuando termino, guardo el nuevo i (para la proxima)
handles7.i = i;
guidata(gcbo,handles7);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles7.CantClusters)
set(handles7.cmdClusterSiguiente,'Enable','off');
else
set(handles7.cmdClusterSiguiente,'Enable','on');
end
if (i==1)
set(handles7.cmdClusterAnterior,'Enable','off');
else
set(handles7.cmdClusterAnterior,'Enable','on');
end


set(handles7.axes1,'FontWeight','bold');
xlabel('Atributo 1');
ylabel('Atributo 2');
zlabel('Atributo 3');

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 163 -
Atributos.m

function varargout = Atributos(varargin)
% ATRIBUTOS Application M-file for Atributos.fig
% FIG = ATRIBUTOS launch Atributos GUI.
% ATRIBUTOS('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 15-May-2004 16:12:12

if nargin == 0 % LAUNCH GUI

fig3 = openfig(mfilename,'reuse');
set(fig3,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles3 = guihandles(fig3);

handlesAnt = getappdata(1,'handles');
handles3.MatrizCompleta = handlesAnt.MatrizCompleta;
handles3.Individuos = handlesAnt.Individuos;
handles3.Atributos = handlesAnt.Atributos;
handles3.CantClusters = handlesAnt.CantClusters;
handles3.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles3.i=0;

guidata(fig3, handles3);

if nargout > 0
varargout{1} = fig3;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 164 -
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

% --------------------------------------------------------------------
function varargout = cmdAtributoSiguiente_Callback(h, eventdata, handles3, varargin)

set(handles3.txtMensaje,'Visible','off');

i = handles3.i +1;
set (handles3.txtAtributo,'String',i);

Centroides=zeros(handles3.IntervalosTiempo,handles3.CantClusters,handles3.Atributos);
auxiliar1=size(handles3.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles3.MatrizCompleta([2:auxiliar1],[1:handles3.Atributos+3]);

for k=1:handles3.IntervalosTiempo
for j=1:handles3.CantClusters
auxiliar=find(matriz(:,handles3.Atributos+3)==(j-1));
matriz1=matriz(auxiliar,[1:handles3.Atributos]);
Centroides(:,j,:)=matriz1;
end
end

plot(Centroides(:,:,i));

%cuando termino, guardo el nuevo i (para la proxima)
handles3.i = i;
guidata(gcbo,handles3);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles3.Atributos)
set(handles3.cmdAtributoSiguiente,'Enable','off');
else
set(handles3.cmdAtributoSiguiente,'Enable','on');
end
if (i==1)
set(handles3.cmdAtributoAnterior,'Enable','off');
else
set(handles3.cmdAtributoAnterior,'Enable','on');
end


set(handles3.axes1,'FontWeight','bold');
xlabel('Tiempo');
ylabel('Atributo');
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 165 -

a='Cluster-';
leg=[];
for k=1:handles3.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
legend(leg);


% --------------------------------------------------------------------
function varargout = cmdAtributoAnterior_Callback(h, eventdata, handles3, varargin)

i = handles3.i -1;
set (handles3.txtAtributo,'String',i);

Centroides=zeros(handles3.IntervalosTiempo,handles3.CantClusters,handles3.Atributos);
auxiliar1=size(handles3.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles3.MatrizCompleta([2:auxiliar1],[1:handles3.Atributos+3]);

for k=1:handles3.IntervalosTiempo
for j=1:handles3.CantClusters
auxiliar=find(matriz(:,handles3.Atributos+3)==(j-1));
matriz1=matriz(auxiliar,[1:handles3.Atributos]);
Centroides(:,j,:)=matriz1;
end
end

plot(Centroides(:,:,i));

%cuando termino, guardo el nuevo i (para la proxima)
handles3.i = i;
guidata(gcbo,handles3);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==handles3.Atributos)
set(handles3.cmdAtributoSiguiente,'Enable','off');
else
set(handles3.cmdAtributoSiguiente,'Enable','on');
end
if (i==1)
set(handles3.cmdAtributoAnterior,'Enable','off');
else
set(handles3.cmdAtributoAnterior,'Enable','on');
end


set(handles3.axes1,'FontWeight','bold');
xlabel('Tiempo');
ylabel('Atributo');

a='Cluster-';
leg=[];
for k=1:handles3.CantClusters
b = num2str(k);
c= strcat(a,b);
leg=[leg;c];
end
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 166 -
legend(leg);


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 167 -
Estadisticas.m

function varargout = Estadisticas(varargin)
% ESTADISTICAS Application M-file for Estadisticas.fig
% FIG = ESTADISTICAS launch Estadisticas GUI.
% ESTADISTICAS('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 15-May-2004 17:06:49

if nargin == 0 % LAUNCH GUI

fig4 = openfig(mfilename,'reuse');
set(fig4,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles4 = guihandles(fig4);
handlesAnt = getappdata(1,'handles');
handles4.MatrizCompleta = handlesAnt.MatrizCompleta;
handles4.Individuos = handlesAnt.Individuos;
handles4.Atributos = handlesAnt.Atributos;
handles4.CantClusters = handlesAnt.CantClusters;
handles4.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles4.i=0;
guidata(fig4, handles4);

if nargout > 0
varargout{1} = fig4;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 168 -
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

% --------------------------------------------------------------------
function varargout = cmdTiempoSiguiente_Callback(h, eventdata, handles4, varargin)

set(handles4.txtMensaje,'Visible','off');

i = handles4.i +1;
set (handles4.txtTiempoOrigen,'String',i);
set (handles4.txtTiempoDestino,'String',i+1);


GraficoBarras=zeros(handles4.CantClusters*handles4.CantClusters,(handles4.IntervalosTiempo-
1));
auxiliar1=size(handles4.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles4.MatrizCompleta([2:auxiliar1],[handles4.Atributos+1:handles4.Atributos+2]);

for k=1:(handles4.IntervalosTiempo-1)
matriz1=matriz([(1+(k-1)*handles4.Individuos):(k*handles4.Individuos)],1);
matriz2=matriz([(1+(k)*handles4.Individuos):(k+1)*handles4.Individuos],1);
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;

for j=1:handles4.Individuos
if ((matriz1(j) == -2) & (matriz2(j) ~= -2))
%Esta operacion va en el otro grafico
else
if ((matriz1(j) ~= -2) & (matriz2(j) == -2))
%Esta operación va en el otro gráfico
else %los 2 tiempos son distintos de -2
if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2))
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;
end
end
end
end
end

GraficoAuxiliar=zeros(handles4.CantClusters);
for j=1:handles4.CantClusters;
GraficoAuxiliar(j,:)=GraficoBarras([((j-1)*
handles4.CantClusters+1):j*handles4.CantClusters],i)';
end
bar3(GraficoAuxiliar);

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 169 -
%cuando termino, guardo el nuevo i (para la proxima)
handles4.i = i;
guidata(gcbo,handles4);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==(handles4.IntervalosTiempo -1))
set(handles4.cmdTiempoSiguiente,'Enable','off');
else
set(handles4.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles4.cmdTiempoAnterior,'Enable','off');
else
set(handles4.cmdTiempoAnterior,'Enable','on');
end


set(handles4.axes1,'FontWeight','bold');
xlabel('Cluster Final');
ylabel('Cluster Inicial');

% --------------------------------------------------------------------
function varargout = cmdTiempoAnterior_Callback(h, eventdata, handles4, varargin)

i = handles4.i -1;
set (handles4.txtTiempoOrigen,'String',i);
set (handles4.txtTiempoDestino,'String',i+1);


GraficoBarras=zeros(handles4.CantClusters*handles4.CantClusters,(handles4.IntervalosTiempo-
1));
auxiliar1=size(handles4.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles4.MatrizCompleta([2:auxiliar1],[handles4.Atributos+1:handles4.Atributos+2]);

for k=1:(handles4.IntervalosTiempo-1)
matriz1=matriz([(1+(k-1)*handles4.Individuos):(k*handles4.Individuos)],1);
matriz2=matriz([(1+(k)*handles4.Individuos):(k+1)*handles4.Individuos],1);
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;
for j=1:handles4.Individuos
if ((matriz1(j) == -2) & (matriz2(j) ~= -2))
%Esto va en el otro grafico
else
if ((matriz1(j) ~= -2) & (matriz2(j) == -2))
%esto va en el otro grafico
else %los 2 tiempos son distintos de -2
if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2))
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;
end
end
end
end

end

GraficoAuxiliar=zeros(handles4.CantClusters);
for j=1:handles4.CantClusters;
GraficoAuxiliar(j,:)=GraficoBarras([((j-1)*
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 170 -
handles4.CantClusters+1):j*handles4.CantClusters],i)';
end
bar3(GraficoAuxiliar);

%cuando termino, guardo el nuevo i (para la proxima)
handles4.i = i;
guidata(gcbo,handles4);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==(handles4.IntervalosTiempo -1))
set(handles4.cmdTiempoSiguiente,'Enable','off');
else
set(handles4.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles4.cmdTiempoAnterior,'Enable','off');
else
set(handles4.cmdTiempoAnterior,'Enable','on');
end


set(handles4.axes1,'FontWeight','bold');
xlabel('Cluster Final');
ylabel('Cluster Inicial');



María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 171 -
Perdidos.m

function varargout = Perdidos(varargin)
% PERDIDOS Application M-file for Estadisticas.fig
% FIG = PERDIDOS launch Estadisticas GUI.
% PERDIDOS('callback_name', ...) invoke the named callback.

% Last Modified by GUIDE v2.0 15-May-2004 17:06:49

if nargin == 0 % LAUNCH GUI

fig8 = openfig(mfilename,'reuse');
set(fig8,'Color',get(0,'defaultUicontrolBackgroundColor'));

% Generate a structure of handles to pass to callbacks, and store it.
handles8 = guihandles(fig8);
handlesAnt = getappdata(1,'handles');
handles8.MatrizCompleta = handlesAnt.MatrizCompleta;
handles8.Individuos = handlesAnt.Individuos;
handles8.Atributos = handlesAnt.Atributos;
handles8.CantClusters = handlesAnt.CantClusters;
handles8.IntervalosTiempo = handlesAnt.IntervalosTiempo;
%este i se va a usar para contar
handles8.i=0;
guidata(fig8, handles8);

if nargout > 0
varargout{1} = fig8;
end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK

try
[varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard
catch
disp(lasterr);
end

end


%| ABOUT CALLBACKS:
%| GUIDE automatically appends subfunction prototypes to this file, and
%| sets objects' callback properties to call them through the FEVAL
%| switchyard above. This comment describes that mechanism.
%|
%| Each callback subfunction declaration has the following form:
%| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN)
%|
%| The subfunction name is composed using the object's Tag and the
%| callback type separated by '_', e.g. 'slider2_Callback',
%| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'.
%|
%| H is the callback object's handle (obtained using GCBO).
%|
%| EVENTDATA is empty, but reserved for future use.
%|
%| HANDLES is a structure containing handles of components in GUI using
%| tags as fieldnames, e.g. handles.figure1, handles.slider2. This
%| structure is created at GUI startup using GUIHANDLES and stored in
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 172 -
%| the figure's application data using GUIDATA. A copy of the structure
%| is passed to each callback. You can store additional information in
%| this structure at GUI startup, and you can change the structure
%| during callbacks. Call guidata(h, handles) after changing your
%| copy to replace the stored original so that subsequent callbacks see
%| the updates. Type "help guihandles" and "help guidata" for more
%| information.
%|
%| VARARGIN contains any extra arguments you have passed to the
%| callback. Specify the extra arguments by editing the callback
%| property in the inspector. By default, GUIDE sets the property to:
%| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo))
%| Add any extra arguments after the last argument, before the final
%| closing parenthesis.

% --------------------------------------------------------------------
function varargout = cmdTiempoSiguiente_Callback(h, eventdata, handles8, varargin)

set(handles8.txtMensaje,'Visible','off');

i = handles8.i +1;
set (handles8.txtTiempoOrigen,'String',i);
set (handles8.txtTiempoDestino,'String',i+1);

GraficoPerdidos = zeros((handles8.CantClusters +1)* (handles8.CantClusters +
1),(handles8.IntervalosTiempo-1));
auxiliar1=size(handles8.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles8.MatrizCompleta([2:auxiliar1],[handles8.Atributos+1:handles8.Atributos+2]);

for k=1:(handles8.IntervalosTiempo-1)
matriz1=matriz([(1+(k-1)*handles8.Individuos):(k*handles8.Individuos)],1);
matriz2=matriz([(1+(k)*handles8.Individuos):(k+1)*handles8.Individuos],1);
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;

for j=1:handles8.Individuos
if ((matriz1(j) == -2) & (matriz2(j) ~= -2))
GraficoPerdidos((handles8.CantClusters)* (handles8.CantClusters + 1) +
matriz2(j)+1,k)=GraficoPerdidos((handles8.CantClusters)* (handles8.CantClusters
+ 1) + matriz2(j)+1,k)+1;
else
if ((matriz1(j) ~= -2) & (matriz2(j) == -2))
GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1) +
handles8.CantClusters+1,k)=GraficoPerdidos(matriz1(j)*
(handles8.CantClusters +1) +handles8.CantClusters+1,k)+1;
else %los 2 tiempos son distintos de -2
if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2))
GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1) + matriz2(j)+1,k)=
GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1)
+matriz2(j)+1,k)+1;
end
end
end
end
end

GraficoAuxiliar=zeros(handles8.CantClusters + 1);
for j=1:(handles8.CantClusters + 1);
GraficoAuxiliar(j,:)=GraficoPerdidos([((j-1)*
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 173 -
(handles8.CantClusters+1)+1):j*(handles8.CantClusters+1)],i)';
end
bar3(GraficoAuxiliar);

%cuando termino, guardo el nuevo i (para la proxima)
handles8.i = i;
guidata(gcbo,handles8);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==(handles8.IntervalosTiempo -1))
set(handles8.cmdTiempoSiguiente,'Enable','off');
else
set(handles8.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles8.cmdTiempoAnterior,'Enable','off');
else
set(handles8.cmdTiempoAnterior,'Enable','on');
end


set(handles8.axes1,'FontWeight','bold');
%Eje x
a= 'Cluster Final(';
b=num2str(handles8.CantClusters+1);
c='=Sin Cluster)';
ley = strcat(a,b);
ley = strcat(ley,c);
xlabel(ley);

%Eje y
a= 'Cluster Inicio(';
b=num2str(handles8.CantClusters+1);
c='=Sin Cluster)';
ley = strcat(a,b);
ley = strcat(ley,c);

ylabel(ley);

% --------------------------------------------------------------------
function varargout = cmdTiempoAnterior_Callback(h, eventdata, handles8, varargin)

i = handles8.i -1;
set (handles8.txtTiempoOrigen,'String',i);
set (handles8.txtTiempoDestino,'String',i+1);

GraficoPerdidos = zeros((handles8.CantClusters +1)* (handles8.CantClusters +
1),(handles8.IntervalosTiempo-1));
auxiliar1=size(handles8.MatrizCompleta);
auxiliar1=auxiliar1(1);
matriz=handles8.MatrizCompleta([2:auxiliar1],[handles8.Atributos+1:handles8.Atributos+2]);

for k=1:(handles8.IntervalosTiempo-1)
matriz1=matriz([(1+(k-1)*handles8.Individuos):(k*handles8.Individuos)],1);
matriz2=matriz([(1+(k)*handles8.Individuos):(k+1)*handles8.Individuos],1);
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)=
GraficoBarras(matriz1(j)*handles4.CantClusters+matriz2(j)+1,k)+1;

for j=1:handles8.Individuos
if ((matriz1(j) == -2) & (matriz2(j) ~= -2))
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 174 -
GraficoPerdidos((handles8.CantClusters)* (handles8.CantClusters + 1) +
matriz2(j)+1,k)=GraficoPerdidos((handles8.CantClusters)* (handles8.CantClusters
+ 1) + matriz2(j)+1,k)+1;
else
if ((matriz1(j) ~= -2) & (matriz2(j) == -2))
GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1) +
handles8.CantClusters+1,k)=GraficoPerdidos(matriz1(j)* (handles8.CantClusters
+1) +handles8.CantClusters+1,k)+1;
else %los 2 tiempos son distintos de -2
if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2))
GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1) +
matriz2(j)+1,k)=GraficoPerdidos(matriz1(j)* (handles8.CantClusters +1)
+matriz2(j)+1,k)+1;
end
end
end
end
end

GraficoAuxiliar=zeros(handles8.CantClusters + 1);
for j=1:(handles8.CantClusters + 1);
GraficoAuxiliar(j,:)=GraficoPerdidos([((j-
1)*(handles8.CantClusters+1)+1):j*(handles8.CantClusters+1)],i)';
end
bar3(GraficoAuxiliar);

%cuando termino, guardo el nuevo i (para la proxima)
handles8.i = i;
guidata(gcbo,handles8);

%deshabilito el boton si no hay mas tiempos siguientes
if (i==(handles8.IntervalosTiempo -1))
set(handles8.cmdTiempoSiguiente,'Enable','off');
else
set(handles8.cmdTiempoSiguiente,'Enable','on');
end
if (i==1)
set(handles8.cmdTiempoAnterior,'Enable','off');
else
set(handles8.cmdTiempoAnterior,'Enable','on');
end


set(handles8.axes1,'FontWeight','bold');
%Eje x
a= 'Cluster Final(';
b=num2str(handles8.CantClusters+1);
c='=Sin Cluster)';
ley = strcat(a,b);
ley = strcat(ley,c);
xlabel(ley);

%Eje y
a= 'Cluster Inicio(';
b=num2str(handles8.CantClusters+1);
c='=Sin Cluster)';
ley = strcat(a,b);
ley = strcat(ley,c);

ylabel(ley);
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 175 -
A3 Instructivo de Instalación y Manual de Usuario

A3.1 Instructivo de Instalación

El software que realiza el Clustering Temporal se divide en dos partes, una realizada en
Weka y la otra en Matlab. Por lo tanto, es necesario tener configuradas las dos aplicaciones para
poder apreciar todas las funcionalidades del mismo.

Estructura del CD de instalación

Weka:
Weka 3.4.1: contiene los archivos necesarios para instalar el programa Weka estándar.
Además contiene el archivo weka.jar, que incluye las modificaciones agregadas a dicho
programa en esta implementación.

Ejemplos: contiene archivos *.arff preparados para ser utilizados con la aplicación weka.
Esta carpeta contiene dos subidrectorios:
o Con Fechas: contiene archivos *.arff que tienen como atributos Fecha de
Inicio y Fecha de Fin en cada registro. Para poder aplicarle a estos archivos el
proceso de clustering temporal es necesario antes aplicarles el filtro
CreateTemporalUnits, cómo se explica en el manual de uso.

o Con UnidadesTemporales: contiene archivos *.arff que ya fueron
filtrados con CreateTemporalUnits, por lo que en lugar de tener los atributos
Fecha de Inicio y Fecha de Fin tienen un único atributo Temp, que indica la
Unidad Temporal correspondiente. A estos archivos se les puede aplicar
directamente el proceso de clustering temporal.


Código Fuente Weka: para ver el código fuente de Weka, hay que descomprimir el
archivo weka-scr.jar. Los nuevos archivos implementados (*.java) se encuentran en este
directorio.

Matlab:
Matlab 6.0: contiene los archivos necesarios para instalar el programa Matlab.

Análisis Resultados: contiene los fuentes y ejecutables que hay que utilizar para
visualizar los resultados del clustering.

Ejemplos: contiene archivos *.csv que son resultados de procesos de clustering
realizados anteriormente.

Tesis: contiene el presente documento de la tesis.

Instructivo de instalación: contiene el instructivo de instalación.

CACIC 2004: contiene el paper sobre Clustering Temporal que se presentó en el X Congreso
Argentino de Ciencias de la Computacion.





María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 176 -
Instalación de Weka

1) Ejecutar el archivo weka-3-4-1jre.exe (instalador de Weka), que se encuentra en Weka\Weka
3.4.1, y seguir las instrucciones.

2) El archivo anterior también instala el JRE (Java RunTime Enviroment) necesario para
ejectutar la aplicación, pero en caso de fallar la instalación (depende de la versión de
Windows instalada), o de tener problemas al momento de ejecutar el programa Weka,
también se debe instalar el JRE desde el archivo j2re-1_4_2_05-windows-i586-p.exe

3) Buscar los archivos weka.jar y RunWeka.bat en el directorio en donde se instaló Weka
(generalmente C:\Archivos de Programa\Weka 3.4), y REEMPLAZARLOS por los archivos del
mismo nombre en directorio Weka\Weka 3.4.1 del CD.

4) Copiar los archivos de Weka\Ejemplos en un directorio a elección (este paso es optativo, se
puede acceder a los archivos de ejemplo directamente desde el CD).

5) Ejecutar el archivo RunWeka.bat para abrir el programa Weka (o ejecutarlo desde el Menù
Inicio). Ingresar a la opción Explorer.




Instalación de Matlab

1) Ejecutar el archivo de instalación en Matlab\MatLab 6.0\Setup.exe (el número de serie se
encuentra en el archivo serial.txt), y seguir las instrucciones. Cuando se ejecutó
aproximadamente el 70 % de la instalación, el instalador solicita insertar el CD con los
archivos del Help; dichos archivos no se encuentran en el CD por lo que es necesario
Cancelar la instalación en este punto.

2) Copiar la carpeta Matlab\Análisis Resultados y todo su contenido a un directorio de su
elección.

3) Copiar los archivos de Matlab\Ejemplos a un directorio de su elección (este paso es optativo,
se puede acceder a los archivos de ejemplo directamente desde el CD).

4) Ejecutar el archivo <matlabR12>\bin\win32\matlab.exe para abrir la aplicación (o desde el
menú Inicio de Windows).

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 177 -
5) Elegir como directorio de trabajo , la carpeta “Analisis Resultados”


Figura A3.1.1

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 178 -
6) En la ventana de comandos tipear Resultados, y automáticamente se ejecuta la aplicación.




Figura A3.1.2

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 179 -
A3.2 Manual de Usuario

Como ya se indicó anteriormente el proceso de clustering temporal consta de 2 etapas: la
generación del archivo temporal y el Clustering temporal propiamente dicho, donde los datos de
entrada se dividen en grupos o clusters, según su unidad de tiempo.

Generación del archivo temporal

En el panel de Preproceso, abrir un archivo *.arff. El formato del archivo debe cumplir con
las normas para los archivos arff y además cada registro debe tener un atributo que lo identifique
y un rango de tiempo en el que sean válidos sus atributos especificados.
Una vez abierto el archivo, se mostrarán en el Panel de Preproceso las características del
mismo (Cantidad y tipo de atributos, cantidad de instancias, etc.)































Figura A3.2.1

A este archivo hay que aplicarle el Filtro “CreateTemporalUnits”. Para ello hay que elegir
el filtro en Filter\Unsupervised\Attribute\CreateTemporalUnits
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 180 -






















Figura A3.2.2


Es importante configurar bien los parámetros del filtro para que el proceso realice lo que
se espera de él.
Los parámetros del filtro son:
• PosFechaIni : Posición del atributo que indica la Fecha de Inicio.
• PosFechaFin: Posición del atributo que indica la Fecha de Fin.
• PosId: Posición del atributo que indica el ID del registro.
• NumIntervalos: Cantidad de intervalos en los que se desea dividir el período
completo.
• Chronon: esta es la unidad de medida. Como las fechas tienen precisión hasta
milisegundos, y a veces esto no es necesario, por medio de este parámetro se indica
con qué precisión tratar las fechas. Los valores posibles son:
• 1 : Año
• 2: Mes
• 3: Día
• 4: Hora
• 5: Minuto
• 6: Segundo


Luego de configurar los parámetros, se debe aplicar el filtro mediante el botón Apply.
Cuando termina de procesar, se observará que se actualiza el encabezado de los
atributos. En lugar de tener
Fecha Inicio
Fecha Fin
Los registros tienen los atributos:
Temp: es un número entero que va de 0 a la cantidad de intervalos que se hayan elegido.
Reemplaza a los rangos de las fechas.
Una vez aplicado el filtro, se puede trabajar con el clustering temporal, o se puede
Guardar el archivo (mediante el botón SAVE), eligiendo nombre y ubicación del mismo,
cargándolo en otra oportunidad para trabajar directamente sin necesidad de aplicar el filtro.
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 181 -
Este proceso genera automáticamente un archivo llamado IntervalosTiempo.txt, que se
guarda en el directorio en donde corre la aplicación, indicando a que intervalo de tiempo real
equivale cada unidad de tiempo Temp.
A continuación se muestra un ejemplo de dicho archivo:


Intervalo de tiempo perteneciente a la unidad temporal 0
Desde: Mon Mar 01 00:00:00 ART 2004 Hasta: Sun Mar 07 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 1
Desde: Mon Mar 08 00:00:00 ART 2004 Hasta: Sun Mar 14 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 2
Desde: Mon Mar 15 00:00:00 ART 2004 Hasta: Sun Mar 21 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 3
Desde: Mon Mar 22 00:00:00 ART 2004 Hasta: Sun Mar 28 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 4
Desde: Mon Mar 29 00:00:00 ART 2004 Hasta: Sun Apr 04 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 5
Desde: Mon Apr 05 00:00:00 ART 2004 Hasta: Sun Apr 11 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 6
Desde: Mon Apr 12 00:00:00 ART 2004 Hasta: Sun Apr 18 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 7
Desde: Mon Apr 19 00:00:00 ART 2004 Hasta: Sun Apr 25 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 8
Desde: Mon Apr 26 00:00:00 ART 2004 Hasta: Sun May 02 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 9
Desde: Mon May 03 00:00:00 ART 2004 Hasta: Sun May 09 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 10
Desde: Mon May 10 00:00:00 ART 2004 Hasta: Sun May 16 00:00:00 ART
2004

Intervalo de tiempo perteneciente a la unidad temporal 11
Desde: Mon May 17 00:00:00 ART 2004 Hasta: Sun May 23 00:00:00 ART
2004



Figura A3.2.3

Luego de aplicado el filtro los registros del archivo arff quedan de la siguiente forma:
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 182 -
• Existen tantas Unidades Temporales (UT) como intervalos de tiempo se
parametrizaron.
• Cada UT tiene la misma cantidad de registros o individuos.
• El mismo registro, con el mismo ID aunque con valores de atributos distintos (o no),
se repite en cada UT.
• Si por el particionamiento elegido en alguna UT no existe ningún registro con
determinado ID, se crea un registro “vacío” o “perdido”. En los resultados finales se
puede apreciar el comportamiento de estos registros.
• Si por el particionamiento elegido existe más de un registro para el mismo ID, los
mismos se conjugan en un solo registro.

El filtro CreateTemporalUnits se puede aplicar tantas veces como se desee al archivo
origen, generando distintas salidas según la configuración de los parámetros.
También se puede aplicar en forma complementaria cualquier otro filtro definido en
WEKA, por ejemplo, para filtrar atributos, instancias, etc.

Clustering temporal

En la solapa de Clustering, se debe elegir el algoritmo Temporal_k_D_Median. Este
algoritmo sólo tiene un parámetro que indica la cantidad de clusters que se desean generar.
Al presionar el botón START comienza el proceso de clustering. Al finalizar, se muestra
en la pantalla lateral un resumen de cuáles son los individuos centroides de cada cluster, para
cada UT.
Figura A3.2.4

En el directorio donde corre la aplicación, se genera automáticamente un archivo con el
nombre del archivo ingresado + _C + Nro de Clusters + _T + Nro de Unidades Temporales, con
María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 183 -
extensión csv (Por ej. NombreArchivo_C4_T6.csv). Estos archivos contienen toda la información
necesaria para la visualización de los resultados mediante Matlab.


Análisis de Resultados

Una vez cargado el programa, presionar el botón Abrir y elegir un archivo de resultados
(*.csv).


Figura A3.2.5

A continuación se habilitarán o deshabilitarán los botones según las características del
archivo elegido:

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 184 -
Cluster 2D: Sólo se habilita si el archivo de entrada tiene 2 atributos. Se muestra
gráficamente la representación de los clusters en cada UT.

Figura A3.2.6

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 185 -
Cluster 2 D Tiempo: Solo se habilita si el archivo de entrada tiene 2 atributos. Se
muestra gráficamente la evolución de cada cluster a través de las distintas UT.


Figura A3.2.7

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 186 -
Cluster 3 D: Sólo se habilita si el archivo de entrada tiene 3 atributos. Se muestra
gráficamente la representación de los clusters en cada UT.






























Figura A3.2.8


María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 187 -
Cluster 3 D Tiempo: Sólo se habilita si el archivo de entrada tiene 3 atributos. Se
muestra gráficamente la evolución de cada cluster a través de las distintas UT.


Figura A3.2.9

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 188 -
Análisis por Atributo: esta opción está habilitada siempre. Muestra atributo por atributo,
la evolución del centroide del cluster a través del tiempo, y a su vez la comparación del mismo
atributo en los distintos clusters.



Figura A3.2.10

María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 189 -
Estadísticas: Este es un gráfico de barras, que muestra cuántos individuos cambiaron de
cluster en el pasaje de un tiempo al siguiente. Cluster Origen muestra la cantidad de individuos
para cada cluster en un determinado tiempo, y Cluster Destino indica la cantidad de individuos
que tienen esos clusters en el tiempo siguiente.

Figura A3.2.11




María Daniela Navas Un modelo de Clustering Temporal
Padrón: 75.626 Octubre 2004

- 190 -
Individuos Perdidos: Muestra en un gráfico de barras, los individuos que pertenecían a
algún cluster en un tiempo dado, y no pertenecen a ninguno en el tiempo siguiente.

Figura A3.2.12


Operación en cada Figura

Las pantallas que se abren al presionar los botones de la pantalla principal poseen el
mismo comportamiento. Tienen 2 botones ==> y <== , para trasladarse a través de las distintas
UT o los distintos clusters, según corresponda.
También poseen un Menú, con opciones generales como Guardar, Imprimir, Copiar,
Cortar, Pegar. Y también se puede editar la figura agregando etiquetas, leyendas, etc.
Una opción interesante es Menu Tools- Edit Plot, que habilita una barra de herramientas
que permite ampliar, reducir o girar los gráficos.

Resumen
Clustering consiste en particionar el conjunto de datos en colecciones de objetos de manera que dentro de cada partición los objetos sean “similares” entre sí, y a su vez se “diferencien” de los objetos contenidos en otras particiones. En la literatura han sido propuestos muchos algoritmos para realizar el proceso de clustering, pero la mayoría de ellos tiene un enfoque estático, por lo tanto, estas soluciones no pueden ser aplicadas correctamente para datos más complejos, como colecciones de objetos espacio-temporales. En muchos casos, la información guardada en las bases de datos tiene una naturaleza espacial dinámica: además de tener datos espaciales, a menudo se asocian los mismos con información temporal, como marcas de tiempo (time-stamp) ,manejo de versiones, fechas o rango de fechas.

En el presente trabajo se propone un método de Clustering Temporal que realiza el proceso de clustering sólo teniendo en cuenta los atributos espaciales o “no temporales”, para distintos momentos de tiempo (dato aportado por los atributos temporales). Esto nos permite ver cómo varían los clusters durante el transcurso del tiempo, observar la trayectoria de los objetos, y obtener distintas estadísticas sobre el movimiento de clusters y objetos, que no se podrían obtener aplicando un algoritmo de clustering estándar.

Abstract
Clustering consists in partitioning a data group into object collections in a way that inside each partition the objects are "similar" between them, and at the same time they could be "differentiated" from the objects contained by another partitions. In the literature a lot of algorithms have been proposed to make the clustering process, but most of them have a static point of view, so they cannot be used correctly for more complex data, as spatial - temporal object collections. In many situations, the information stored at data bases has a dynamic spatial structure, as time stamps, version management, dates or date ranges.

In the present work a Temporal Clustering method is proposed which uses the clustering method only taking into account the spatial or “no temporal” attributes, for different portions of time (information given by the temporal attributes). This allows us to see how the clusters modify with the time, determine the trajectory of the objects, and obtain different statistics about cluster and object movements, which could not be obtained by using a standard clustering algorithm.

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Indice
1 Introducción __________________________________________________ 5 1.1 Clustering 5 1.2 Clustering Temporal____________________________________________ 5 1.3 Contribución __________________________________________________ 6 1.4 Algoritmos de Clustering ________________________________________ 6
1.4.1 1.4.2 1.4.3 1.4.4 Algoritmos de Particionamiento (Partitioning Algorithms) ________________________ 7 Algoritmos Jerárquicos (Hieralchical Algorithms) ______________________________ 7 Algoritmos Basados en Densidad (Density-Based Algorithms)____________________ 7 Algoritmos Basados en Grillas (Grid-Based Algorithms)_________________________ 8

1.5 Elección del algoritmo adecuado __________________________________ 8 1.6 Objetivo de la Tesis ____________________________________________ 9 1.7 Estructura de la Tesis __________________________________________ 9 2 Trabajos Relacionados ________________________________________ 11 3 Modelo Temporal _____________________________________________ 13 3.1 Modelos temporales de datos ___________________________________ 13
3.1.1 Combinación y Eliminación de Información repetida___________________________ 14

3.2 Distintos esquemas de representación de datos temporales ___________ 15
3.2.1 Tupla con marca de tiempo de Snodgrass __________________________________ 15 3.2.2 Esquema acumulativo de Jensen _________________________________________ 16 3.2.3 Atributo con marca de tiempo de Gadia ____________________________________ 16 3.2.4 Atributo con Marca de Tiempo de McKenzie_________________________________ 17 3.2.5 Tupla con marca de tiempo de Ben-Zvi_____________________________________ 17

3.3 Modelo de representación de datos para clustering temporal ___________ 18 3.4 Intervalos de tiempo a analizar __________________________________ 18 4 Implementación ______________________________________________ 23 4.1 Generación del Archivo temporal_________________________________ 23 4.2 Clustering temporal ___________________________________________ 25
4.2.1 K-D-Median __________________________________________________________ 25 4.2.2 Implementación de k-D-Median___________________________________________ 27 4.2.3 Atributos Categóricos en K-D-Median ______________________________________ 32 4.2.4 Algoritmo k-D-Median Temporal __________________________________________ 34 4.2.5 Relación entre clusters de distintos tiempos _________________________________ 35 4.2.6 Análisis de Resultados _________________________________________________ 36

5

Experimentación _____________________________________________ 37 5.1 Casos de prueba _____________________________________________ 37
5.1.1 Consideraciones generales ______________________________________________ 37 5.1.2 Caso de prueba 1 _____________________________________________________ 37 5.1.3 Caso de prueba 2 _____________________________________________________ 51 5.1.4 Caso de prueba 3 _____________________________________________________ 66
-3-

2 Detalle de Casos de Uso ________________________________________________ 90 A1.1 Conclusiones ________________________________________________ 83 6.María Daniela Navas Padrón: 75.5 Prueba de Performance ________________________________________________ 81 Conclusiones ________________________________________________ 83 6.1.626 Un modelo de Clustering Temporal Octubre 2004 5.2 Manual de Usuario ____________________________________________________ 179 -4- .1 Casos de Uso ________________________________________________________ 89 A1.1 WEKA ______________________________________________________________ 99 A2.1 Instructivo de Instalación _______________________________________________ 175 Estructura del CD de instalación _____________________________________________ 175 A3.2 MATLAB____________________________________________________________ 142 A3 Instructivo de Instalación y Manual de Usuario _____________________ 175 A3.2 Trabajo Futuro _______________________________________________ 83 Apéndices ______________________________________________________ 89 A1 Diseño del Código ____________________________________________ 89 A1.4 Nuevas Clases________________________________________________________ 96 6 A2 Código Fuente _______________________________________________ 99 A2.3 Estructura de Clases ___________________________________________________ 93 A1.

Esto requiere la aplicación de otras técnicas como análisis estadístico. sino que a menudo asocian los datos espaciales con información temporal. o sea.2 Clustering Temporal En la literatura han sido propuestos hasta el momento. Luego de haber particionado al grupo de datos en clusters. por lo tanto clustering es sólo un paso si el objetivo de análisis es más amplio (Nanni. anomalías y estructuras significativas. que es un componente del proceso de Knowlegde Discovery. y a su vez se “diferencien” de los objetos contenidos en otras particiones. como por ejemplo patrones. [14]). como colecciones de objetos espacio-temporales. e incluso en muchos casos contienen información temporal dada por una fecha o rango de fechas. en grandes cantidades de datos guardados en bases de datos u otros repositorios de información. compuestos por elementos representados como puntos individuales en un espacio multidimensional (posiblemente con una combinación de dimensiones discretas y continuas).626 Un modelo de Clustering Temporal Octubre 2004 1 Introducción 1. hasta ahora.María Daniela Navas Padrón: 75. 1. asociaciones. Clustering es una de las principales tareas en Data Mining y consiste en particionar el conjunto de datos (dataset) en colecciones de objetos o instancias de manera que dentro de cada partición los objetos sean “similares” entre sí. Data Mining se refiere a la aplicación de algoritmos para la extracción de patrones utilizando los datos disponibles. como marcas de tiempo (time-stamp) o manejo de versiones.21]). Las soluciones desarrolladas bajo estas restricciones no pueden ser aplicadas correctamente para datos más complejos. Sin embargo. la mayoría de los resultados conciernen a datos simples. [20.. se requieren soluciones -5- . cambios. clasificación o reglas de asociación. En muchos casos. es interesante encontrar cuáles son las características claves de cada grupo. Similitud y disimilitud son expresadas a través de funciones de distancia / similitud y a las particiones resultantes se las denomina clusters. Por lo tanto. muchos algoritmos para realizar el proceso de clustering (Han et al. En estos casos algunas de las peculiaridades de los datos deben ser sacrificadas para poder utilizar los procesos de clustering convencionales.1 Clustering Se denomina proceso de descubrimiento de conocimiento en bases de datos (Knowlegde Discovery in Databases-KDD) al proceso de descubrir conocimiento interesante. la información guardada en las bases de datos tiene una naturaleza espacial dinámica: no solamente las bases tienen datos espaciales.

4 Algoritmos de Clustering Para elegir un algoritmo de clustering adecuado para una determinada aplicación deben considerarse varios factores. por lo tanto se investigó qué algoritmo podía ser el más adecuado para este propósito. Esto nos permite ver cómo varían los clusters durante el transcurso del tiempo. etc. Un algoritmo adecuado debe cumplir con estas dos características. para crear el algoritmo temporal que provee todas las ventajas que se especifican en el presente trabajo. 1. Los algoritmos de particionamiento (partitioning algorithms) como k-means o k-medoids. y tienden a descubrir clusters con forma esférica y tamaño similar. Por ejemplo. pero a veces la cantidad de instancias a procesar juega un papel importante en el tiempo de ejecución del algoritmo de clustering. a menudo es deseable hallar los clusters que se forman naturalmente. según se indica en (Han et al.3 Contribución En el presente trabajo se resuelve el problema desde otro enfoque (Navas et. En el caso de reconocimiento de imágenes. cuando se trabaja con grandes volúmenes de datos se realiza una especie de compresión sobre la información inicial. también son un factor importante para la elección del método adecuado. [14]). [22]): se propone un método que realiza el proceso de clustering sólo teniendo en cuenta los atributos espaciales o “no temporales”.21]). si se desea encontrar la ubicación óptima de las sucursales de una cadena de supermercados. cómo se deben especificar los mismos. 1. A su vez. para distintos momentos de tiempo (dato aportado por los atributos temporales). o Tipos de datos de los atributos: La similitud entre dos objetos es medida según la diferencia entre los valores de sus atributos. Este modelo se comporta como un framework o marco. Lo que se hizo fue crear un modelo temporal que determina a qué tipo de datos se puede aplicar este proceso de clustering. cómo se procesa la información y cómo se muestran los resultados. [20. En cambio para el segundo caso responden mejor los algoritmos basados en densidad (density-based algorithms) ♦ Elección entre calidad y velocidad: Existe siempre un problema al elegir entre velocidad de procesamiento y calidad de los clusters obtenidos. Para resolver esto. al. Los mismos son: ♦ Objetivo de la aplicación: El objetivo de la aplicación a menudo afecta la elección de un algoritmo de clustering. Características de los datos: Las características de los datos a los cuales se quiere aplicar el clustering. es un “molde” que puede basarse en cualquier algoritmo de clustering “convencional” (que no maneje datos temporales). Un algoritmo que produce clusters de calidad. Cuando todos los atributos son numéricos las medidas de distancia como Euclídea o Manhattan pueden ser ♦ -6- . densidad. perdiendo así calidad. por lo general es incapaz de manejar grandes cantidades de información.María Daniela Navas Padrón: 75. el objetivo será encontrar la mínima distancia entre los clientes y cada sucursal. son útiles para el primer caso. en donde los clusters deberán tener cierta uniformidad de color.626 Un modelo de Clustering Temporal Octubre 2004 capaces de manejar las nuevas nociones de “distancias” que pueden desprenderse de datos tan complejos. esto permite agrupar en un mismo cluster a objetos que tienen similitudes tanto en sus atributos espaciales como en sus atributos temporales. algunas propuestas proponen utilizar nuevos conceptos de distancias y métricas adaptadas a un contexto espacio-temporal (Nanni.

pero al aumentar las dimensiones los resultados se degeneran. La degeneración puede darse por la disminución de la velocidad o el empobrecimiento de la calidad de los clusters.1 Algoritmos de Particionamiento (Partitioning Algorithms) Dado un conjunto D de n objetos en un espacio de d dimensiones. un árbol que divide la base de datos recursivamente en conjuntos cada vez más pequeños. hasta que cada objeto esté en un cluster individual o hasta que se cumplan las condiciones de terminación. y se les dificulta hallar clusters de diversas figuras. EM (Expectation Maximization) 1. Los objetos o grupos se combinan sucesivamente según determinadas medidas. se comienza con cada objeto formando un grupo por separado. Por lo tanto. En cambio. El árbol puede ser formado de dos formas: de abajo hacia arriba (“botton-up”) o de arriba hacia abajo (“top-down”). CHAMALEON. también llamado aglomerativo. se comienza con todos los objetos en el mismo cluster. y a medida que se va iterando. k-medoids.626 Un modelo de Clustering Temporal Octubre 2004 fácilmente computadas. La desviación de un punto puede ser computada en forma diferente según el algoritmo. también llamado divisivo.3 Algoritmos Basados en Densidad (Density-Based Algorithms) La mayoría de los métodos de particionamiento. BIRCH (Balanced Iterative Reducing and Cluestering using Hierarchical) 1. En el caso “top-down”. y tomando como parámetro de entrada el valor k. este cálculo se complica. los cuatro principales tipos de algoritmos de clustering. se dividen los grupos en subconjuntos más pequeños según determinadas medidas. categóricos u ordinales. realizan el proceso de clustering en base a la distancia entre dos objetos.4.4. 1. la mayoría de los algoritmos se aplican sólo a datos numéricos. un algoritmo de particionamiento organiza los objetos dentro de k clusters tal que sea minimizada la desviación total de cada objeto desde el centro de su cluster o desde una distribución de clusters. Muchos algoritmos funcionan bien con pocos atributos. formando un dendrograma. o A continuación se explican brevemente. Estos métodos pueden encontrar sólo clusters esféricos. o Dimensionalidad: la dimensionalidad se refiere al número de atributos de cada objeto. DIANA (Divisia ANAlysis). En el caso “botton-up”. no pudiendo funcionar correctamente ante la presencia de los mismos.4.María Daniela Navas Padrón: 75. CURE (Clustering Using Representatives). Ejemplos: AGNES (Aglomerative NESting). Ejemplos : k-means. Cantidad de ruido en los datos: Algunos algoritmos son muy sensibles a ruido o elementos aislados. Otros algoritmos de clustering han sido desarrollados en -7- .2 Algoritmos Jerárquicos (Hieralchical Algorithms) Un método jerárquico crea una descomposición jerárquica de un conjunto de datos. hasta que todos los grupos se hayan unido en uno solo. o hasta que se cumpla alguna condición de terminación. cuando los atributos son binarios. y es llamada generalmente función de similitud.

8. Como se especificó con anterioridad. Se ha decidido utilizar bases de datos con información demográfica. al. Ng et. [12]. por lo que se necesita un algoritmo que sea lo suficientemente rápido para poder analizar grandes volúmenes de datos. presentado por sus autores (Estivill-Castro. existen numerosos algoritmos y la elección del adecuado depende del tipo de problema que se quiera encarar. Huang et. etc. al. CLIQUE. También se creó en Matlab una aplicación que permite analizar gráficamente los resultados del clustering. [10]) como un algoritmo de clustering de propósito general rápido y robusto.María Daniela Navas Padrón: 75. El método divide el espacio en un número finito de celdas. OPTICS (Ordering Points To Identify the Clustering Structure). La mayor ventaja de este método es su veloz procesamiento del tiempo.7.9]. Comparando distintos algoritmos existentes dentro de este rubro (Estivill-Castro et. al.6. datos que provee el INDEC (Instituto Nacional de Estadística y Censos). en la cuál sea útil la información que puede proveer este clustering temporal. Estas bases de datos poseen la particularidad de ser muy grandes. pero puede estar presente.5 Elección del algoritmo adecuado El objetivo del presente trabajo es implementar un nuevo método de clustering temporal el cual está basado en algún algoritmo ya existente. Estos generalmente estiman clusters como regiones con gran densidad de objetos. que realiza el formateo de los datos y el proceso de clustering en sí.626 Un modelo de Clustering Temporal Octubre 2004 base a la noción de “densidad”. Ejemplos: STING (A STatistical INformation Grid). formando una grilla. Ejemplos: DBSCAN (Density-Based Spatial Clustering of Aplications with Noise). ya que sería muy útil poder determinar como varían los resultados obtenidos en censos durante el transcurso de los años. 1. Grabmeier et. los algoritmos que mejor se adaptan a este tipo de problema son los de particionamiento. WaveCluster. es necesario buscar un área determinada. el cual generalmente es independiente de la cantidad de objetos a procesar.4 Algoritmos Basados en Grillas (Grid-Based Algorithms) Los métodos basados en densidad suelen tener grandes problemas cuando se trabaja con bases de datos muy grandes. Por lo tanto. Lo que se hizo en el presente trabajo fue implementar un nuevo algoritmo en Java para integrarlo al sistema WEKA. Para mejorar la efectividad del clustering. por ejemplo. La información recolectada es representada por una cantidad mediana de atributos. que pueden ser numéricos o nominales.4. La cantidad de ruido o de objetos aislados no se puede determinar. en donde se realizan todas las operaciones del clustering.al. [15]. separados de regiones de baja densidad de objetos (estos elementos aislados representan ruido). Este tipo de métodos es muy útil para filtrar ruido y encontrar clusters de diversas formas. et al. [23]) se seleccionó un algoritmo llamado k-D-median. un método basado en grillas usa una estructura de grilla de datos. -8- . DENCLUE (DENsity-based CLUstEring) 1. Según la división de algoritmos de clustering explicada anteriormente. [5.

el Capítulo 6 remarca las conclusiones. En el Capítulo 4 se describe cómo se implementó el algoritmo. basándose en el modelo indicado anteriormente. para distintos momentos de tiempo.6 Objetivo de la Tesis El objetivo de esta Tesis de grado es: Crear un modelo genérico de clustering temporal que permita realizar el proceso de clustering teniendo en cuenta los atributos espaciales o “no temporales”. y su adaptación para realizar el clustering temporal.María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 1. El Apéndice 2 contiene el código fuente generado y el Apéndice 3 indica los pasos necesarios a realizar para la instalación del software adjunto y el manual de usuario. Utilizar una herramienta gráfica para visualizar el resultado del clustering temporal. como ya se pudo apreciar.7 Estructura de la Tesis La presente tesis se divide en 6 capítulos y 3 apéndices. performance y escalabilidad del algoritmo. Por último. En el Capítulo 5 se describe una serie de experimentos que muestran la utilidad. detalla una introducción al clustering en general y al clustering temporal en particular. 1. En el Capítulo 3 se explica el modelo temporal de datos utilizado. El Capítulo 2 describe trabajos realizados por otros autores que están relacionados con este tema. Desarrollar un algoritmo que realice el clustering temporal. El Capítulo 1. El Apéndice 1 muestra el análisis y diseño que se realizó para llegar a la solución implementada. -9- .

626 Un modelo de Clustering Temporal Octubre 2004 .María Daniela Navas Padrón: 75.10 - .

y se proponen optimizaciones a dichos algoritmos. Bittner et. pero algunos son muy específicos a un problema determinado. En (Adair et. para obtener información temporal sobre prácticamente cualquier campo de estudio (dependiendo del algoritmo base). que se pueden utilizar con cualquier algoritmo de clustering para mejorar su performance. al. . [25]) se realizan distintos enfoques de clustering espaciotemporal. [11]. [2]. al. al. [20. En (Han et al. Galic et. y otros no llegan a proponer algún modelo o algoritmo interesante. Por ejemplo. que se consultó para evaluar la mejor forma de implementar el presente trabajo. al. Primero se propone una definición de lo que es una distancia espacio-temporal.María Daniela Navas Padrón: 75. enfocándose en las propiedades de las métricas. [1]. La diferencia del presente trabajo con otros trabajos o algoritmos implementados es justamente que no se trata sólo de un algoritmo. sino de un framework que se puede aplicar a cualquier algoritmo de clustering convencional. Popescul et. al. [30]) se propone tratar las coordenadas temporales como geográficas.626 Un modelo de Clustering Temporal Octubre 2004 2 Trabajos Relacionados En la bibliografía actual existen varios intentos para tratar los objetos temporales. utilizando el espacio cartesiano.11 - . En (Nanni. Pero prácticamente ninguno aplica estos conocimientos específicamente al proceso de clustering. Hammoud et. [13]. al. [14]) se presenta un estudio sobre distintos tipos de algoritmos de clustering. en (Roddick et.21]) se propone una familia de medidas de similitud definida sobre objetos espacio-temporales. Luego se analiza el comportamiento de algoritmos de clustering al aplicar alguna distancia de las definidas en su esquema.

María Daniela Navas Padrón: 75.12 - .626 Un modelo de Clustering Temporal Octubre 2004 .

. una tupla (A1.626 Un modelo de Clustering Temporal Octubre 2004 3 Modelo Temporal 3. asociados con una marca de tiempo bitemporal tb . [24]. . [17]. La unión de estos intervalos se denomina elemento temporal..13 - . En términos matemáticos. [31]) Enfocándose sólo en la semántica (Jensen et al. eran demasiado complicados. simplemente por el par de cronos inicial y final. incluso los desarrollados por ellos. acudimos a (Chen et.. es una unidad de tiempo no descomponible. Un crono es la más corta duración de tiempo soportada por una base de datos temporal. un instante de inicio y otro de fin. [28]. En este modelo conceptual. Ramamritham et. de duración fija.. Xiong et. cuyo objetivo es capturar cuándo los hechos son válidos en la realidad (tiempo válido) y cuaádo son almacenados en la base de datos (tiempo de transacción). en años.[18]) determinaron que los modelos existentes. donde cada crono representa todas las instancias que ocurren durante la duración del mismo. A2. An . Padmanabhan et. al.. la principal pregunta es cómo asociar los hechos con el tiempo.27]. Para entender los conceptos básicos para trabajar con bases de datos temporales. Povinelli et. Según (Jensen et.1 Modelos temporales de datos Cuando se piensa en la forma de representar valores que varían con el tiempo. etc. Un intervalo de tiempo es definido como el tiempo entre dos instantes...[18]) existen numerosos modelos de datos temporales que de alguna forma asocian los hechos con un tiempo válido. Entonces crearon un modelo muy simple. La terminología “conceptual” es usada sólo para enfatizar el uso del modelo en el diseño y como base de un lenguaje de consultas. en días. A2.. También se puede representar una secuencia de cronos. Un intervalo de tiempo es representado por una secuencia de cronos consecutivos. al. al. .. Modelo Conceptual Bitemporal de Datos (Bitemporal Conceptual Data Model – BCDM).al [3]. Puede estar medido en segundos. al. Jensen et. [26. un sub intervalo de la línea de tiempo real. esta secuencia de cronos es representada por una secuencia finita de números naturales.al. El BCDM emplea el mismo modelo para los dos dominios de tiempo (válido y de transacción): una secuencia finita de cronos. al. dependiendo de las necesidades particulares de los datos procesados.. An | tb) consiste en un número de atributos A1.María Daniela Navas Padrón: 75..

15) y así sucesivamente. El valor especial UC (Until Changed – Hasta que cambie) .1 Combinación y Eliminación de Información repetida En el modelo conceptual representación de las tuplas. se pueden juntar en una sola tupla.. 3.. (15. están temporalmente superpuestas o son temporalmente adyacentes. BCDM se observa que existe una cierta flexibilidad en la Existen dos transformaciones que pueden cambiar la forma de ver los datos sin afectar los resultados de las consultas que se hacen a la base de datos (Jensen et al.. lo mismo para los otros intervalos.11) hasta (5.5). (10. Se usan números enteros como componentes de las marcas de tiempo. Esta transformación permite reducir el número de tuplas necesarias para representar una relación bitemporal.(14..10)..1.... Cada rectángulo representa un intervalo de tiempo.10).1 Tomás Diego Ventas Compras Esta tabla muestra la marca de tiempo T como una secuencia de cronos bitemporales.. Significa que si dos tuplas.20). si se desea optimizar el espacio físico de la base de datos. significa que esa tupla es todavía válida en la base de datos.15).30)} Figura 3.... V es el dominio del tiempo Válido y T el de tiempo de transacción.... útil....(19.(14. Esto significa que cuando el tiempo de transacción está entre 5 y 9.[18]).10).. el tiempo válido está entre 10 y 15. (UC..626 Un modelo de Clustering Temporal Octubre 2004 Nombre Tomás Departamento asignado Compras T {(5. (5..(9. por ejemplo.. La primera transformación se denomina Combinación.20)... V V V T (a) (b) Figura 3.5).. (5.15)} {(UC.. Para la tupla (Tomás – Compras) las marcas de tiempo incluyen los cronos (5.(19..14 - .10)..10)....10). el entero 15 representa el día 15/01/04).15)} {(UC. (UC. Cada par (ct... cada entero representa una fecha (por ejemplo.15)..2 T (c) T .2 muestra cómo los rectángulos se pueden combinar cuando los tiempos de transacción son adyacentes (a) o los tiempos válidos son adyacentes (c).... La Figura 3...María Daniela Navas Padrón: 75... Esta transformación se puede aplicar tanto para el tiempo válido como para el tiempo de transacción.15)..(15. A continuación se muestra gráficamente esta transformación..(10. con los valores de atributos explícitos iguales. cv) representa un crono bitemporal donde ct es el tiempo de transacción y cv el tiempo válido..(9.25).

z se usa para las tuplas. Vi. An. Vi.. A2. y . Para representar este modelo en una base de datos real existen muchas formas distintas. V V V T (a) (b) Figura 3. es un conjunto de hechos asociados con un conjunto de cronos bitemporales. .María Daniela Navas Padrón: 75. se representa R de la siguiente forma: R = (A1. .1 se representaría de la siguiente forma: .2. precisamente por eso es conceptual. 3. Ti. y tienen marcas de tiempo superpuestas en el tiempo.2 Distintos esquemas de representación de datos temporales Una relación bitemporal conceptual es estructuralmente simple. Vf) Los atributos adicionales Ti. [19]). si contiene dos tuplas distintas con valores equivalentes. Esta transformación es empleada para eliminar información temporal redundante.1 Tupla con marca de tiempo de Snodgrass En este esquema . a expensas de agregar tuplas extras. 1 ≤ i ≤ n de la relación x. Tf.3 se muestra un ejemplo de cómo esta transformación puede particionar las regiones cubiertas por el tiempo válido o el de transacción. En los mismos se utilizarán las siguientes notaciones: • • • R para denotar un esquema de relación. antes se debe indicar que una relación tiene información repetida. Pero este modelo conceptual es sólo a nivel del diseño. y la notación x[Ai] denota el Ai-ésimo atributo de x..626 Un modelo de Clustering Temporal Octubre 2004 Para introducir la otra transformación. 3. A representa el conjunto de todos los atributos Ai . A continuación se enumeran algunos esquemas de representación.3 T (c) T En la Figura 3. Lo que hace es transformar dos tuplas con valores equivalentes con superposición temporal. en donde no existe la superposición temporal. en tres tuplas con valores equivalentes. El ejemplo conceptual de la Figura 3. o sea que los valores de sus atributos explícitos (no temporales) son idénticos. enumeradas en (Jensen et al. Vf son valores atómicos temporales conteniendo cronos de inicio y fin del tiempo de transacción y cronos de inicio y fin del tiempo válido. Tf..15 - .

El ejemplo conceptual de la Figura 3.5 Vi 10 10 5 5 10 10 10 25 Vf 15 15 20 20 15 15 15 30 T 5 10 10 15 15 20 20 20 Op I D I D I D I I 3.1 se representaría de la siguiente forma: Nombre Tomás Tomás Tomás Tomás Tomás Tomás Tomás Diego Departamento asignado Compras Compras Compras Compras Compras Compras Ventas Compras Figura 3.16 - . .4 3. Tf ].2 Esquema acumulativo de Jensen La principal diferencia entre este esquema y el anterior es que las tuplas no pueden ser modificadas.Insertar) o D (Delete . .. Tf ] x [ Vi . El atributo Op puede tomar el valor I (Insert . Vf ] A1 )}. Vi. El ejemplo conceptual de la Figura 3.Tf] x [Vi.Eliminar). el intervalo de tiempo válido [ Vi . para cuando se quiere representar el agregado o la eliminación de la tupla. Op) Donde T indica el tiempo de transacción en que la tupla es almacenada en la base de datos. . Cada elemento del conjunto tiene tres partes: el intervalo de tiempo de transacción [ Ti . .626 Un modelo de Clustering Temporal Octubre 2004 Nombre Tomás Tomás Tomás Diego Departamento asignado Compras Compras Ventas Compras Ti 5 10 20 20 Tf 9 14 UC UC 10 5 10 25 Vi Vf 15 20 15 30 Figura 3.1 se representaría de la siguiente forma: . An.María Daniela Navas Padrón: 75. . Vf. una vez que se agregaron a la base de datos no se puede modificar su contenido. T. En este esquema se representa R de la siguiente forma: R = (A1. . Vf] An )} ) donde cada tupla está compuesta de n conjuntos.2.3 Atributo con marca de tiempo de Gadia En este esquema se representa R de la siguiente forma: R = ( { ( [ Ti . Sólo se pueden agregar más tuplas. . Vf ] y el valor de un atributo.2. {( [Ti.

.19] x [10.626 Un modelo de Clustering Temporal Octubre 2004 Nombre [5.30] Tomás Tomás Tomás Tomás Diego Departamento asignado [5. Aquí se representa R de la siguiente forma: R = (A1.UC] x [25. Similarmente. VR) donde VR = (A1 V1. El valor Tir (inicio registro) indica cuando el valor Tie fue almacenado....15] Ventas [20. Tir. Tfe. El símbolo “-“ en el campo Td indica que la tupla contiene información actual. Compras {25. 15}.15} ) } {( Tomás {10.14] x [5.. el valor Tfe (fin efectivo) indica cuando la información almacenada deja de ser verdadera y Tfr (fin registro) contiene el tiempo cuando el valor Tfe fue almacenado...1 se representaría de la siguiente forma: .UC] x [25.6 3.2..20} ) } { ( Tomás {1 0. .15] [20.30} )} Figura 3. .19] x [10. Td) En la tupla.9] x [10.15] Compras [10..….. Tfr.….….5 Tupla con marca de tiempo de Ben-Zvi En este modelo cada tupla de atributos explícitos tiene 5 atributos temporales. .9] x [10.2... el valor del atributo Tie (inicio efectivo) es el tiempo cuando los atributos explícitos comienzan a ser verdaderos. Tie . . ( Diego {25. . .7 3. El ejemplo conceptual de la Figura 3.UC] x [10.15] [20.4 Atributo con Marca de Tiempo de McKenzie En este modelo una relación bitemporal es una secuencia de estados de tiempo válido indexados por el tiempo de transacción.María Daniela Navas Padrón: 75. . . En este esquema se representa R de la siguiente forma: R = (T.14] x [5. 15} .17 - . 15} ..…. . El último atributo implícito Td (deletion – eliminación) indica el tiempo cuando la información de la tupla fue lógicamente borrada de la base de datos. Compras {10.15} ) . .20] Compras [15.…. An Vn ) El ejemplo conceptual de la Figura 31 se representaría de la siguiente forma: T 0 5 10 15 20 VR vacío { ( Tomás {10. .UC] x [10.20] [15.15] Compras [20. An.. Compras {10.. 30} .30] Compras Figura 3. Compras {5.Ventas {10.15} ) } { ( Tomás {5.15] [10.. 20} . .

. pero para distintos momentos de tiempo (dato aportado por los atributos temporales). El algoritmo de clustering divide el período total de tiempo en T subconjuntos o intervalos. se deben reemplazar Vi....626 Un modelo de Clustering Temporal Octubre 2004 Nombre Tomás Tomás Tomás Tomás Diego Departamento asignado Compras Compras Compras Ventas Compras Tie 10 5 10 10 2 Tir 5 10 15 20 20 Tfe 15 20 15 15 30 Tfr 5 10 15 20 20 Td 10 15 20 - Figura 3. Vf por los respectivos tiempos de transacción.María Daniela Navas Padrón: 75.. Conceptualmente se puede representar a los datos con el modelo BCDM de (Jensen et al. 3. .. pudiendo aplicarles las transformaciones de combinación y eliminación de información repetida. De los cinco esquemas físicos para representar los datos propuestos por (Jensen et al. . An. A2. pero sólo se trabaja con un dominio de tiempo.8 3. Se utilizó el siguiente modelo: R = (Ao. Sólo se utiliza el tiempo válido porque es el que interesa al proceso de clustering.[18]). ya que se estudia cómo varían los objetos en la realidad. Es preciso determinar cuál es el formato más adecuado que deben tener los datos de entrada para obtener los mejores resultados al aplicar el algoritmo de clustering temporal.3 Modelo de representación de datos para clustering temporal El objetivo del clustering temporal es realizar el proceso de clustering sólo teniendo en cuenta los atributos espaciales (utilizando algún algoritmo convencional).18 - . A1. Estos datos provienen de una base de datos temporal. . La duración de estos intervalos se calcula teniendo en cuenta el crono (que es la mínima unidad de medida utilizada para este proceso).4 Intervalos de tiempo a analizar Un proceso de clustering temporal abarca cierto período de tiempo. En el caso específico que se quieran agrupar los datos según el momento en que fueron almacenados en la base de datos. A2. Vf : es el tiempo válido de inicio y de fin. por ejemplo. [19]). pueden ser categóricos o numéricos. se seleccionó la Tupla con marca de tiempo de Snodgrass para obtener la forma de representar los datos a los que se les aplicará el clustering temporal. Vi. es el que se utiliza para determinar cómo el objeto cambia a través del tiempo. Un intervalo es un subconjunto de ese período de tiempo. . An : son los atributos explícitos del objeto. A1. El crono lo determina la unidad con que están almacenados los rangos de tiempo válido de las tuplas. Vi. . El intervalo durante el cual son verdaderos en el mundo real los atributos mencionados. un año calendario (desde Enero hasta Diciembre). Vf) donde • • • Ao :es el atributo que identifica al objeto. Esto nos permite ver cómo varían los clusters durante el transcurso del tiempo.

tiene un rango de tiempo válido que ocupa parte de los dos intervalos a analizar. días. cada una con un rango de tiempo válido contenido en cada uno de los intervalos a analizar (transformación similar a la de eliminación de información repetida). Otro caso: si el período total a observar es cuestión de segundos.626 Un modelo de Clustering Temporal Octubre 2004 Las medidas disponibles en principio. por lo que en estos casos no sería necesario aplicar ninguna transformación. En cambio. la segunda tupla del Objeto 2. Por ejemplo. el período total y la cantidad de intervalos que se desean analizar nos enfrentamos a que los rangos de tiempo válido definidos para cada tupla no necesariamente coinciden con los intervalos que se desean analizar. las tuplas del Objeto 1 están íntegramente en un intervalo de tiempo. Una vez determinada la unidad de medida. Idem para cada segmento verde. minutos. El resultado de hacer esta transformación se observa en la Figura 3. medirlo en años implicaría una pérdida de precisión enorme.María Daniela Navas Padrón: 75. Como se puede observar.9 se muestra gráficamente cuál sería este caso. Existen dos casos en los que será necesario aplicar alguna transformación a las tuplas: 1) Las tuplas cuyo rango de tiempo válido no está contenido íntegramente en un intervalo a analizar se deberán particionar. Entonces el período completo se vería como 12 meses. y al dividir por T=12 se analizarían intervalos de 1 mes. ya que hacer la cuenta del ejemplo en segundos implicaría números muy grandes que pueden producir un desbordamiento de memoria.9 T2 Tiempo El eje horizontal indica el tiempo. en el caso anterior el crono a utilizar sería el “mes”. Con rojo están separados los intervalos de tiempo que se desean analizar. En la Figura 3.10.19 - . Es importante determinar el crono para lograr efectividad en las cuentas. meses y años. o sea que en este caso se desea realizar el clustering para el intervalo T1 y compararlo con el clustering para el intervalo T2. horas. . Es aquí donde se acudió a los conceptos de combinación y eliminación de información repetida para obtener tuplas cuyos rangos de tiempo válido coincidan totalmente con los intervalos a analizar. En esto caso lo que se hace es dividir la tupla en dos. Objeto1 Objeto2 T1 (Intervalos a analizar) Figura 3. Cada segmento azul representa una tupla del mismo objeto. pero para distintos rangos de tiempo válido. son: segundos.

no es necesario que el rango de tiempo válido tenga la misma duración que el intervalo de tiempo a analizar. sino que puede ser entre cualquier cantidad. Como se observa. donde los atributos explícitos son los de cualquiera de las tuplas y cuyo rango de tiempo válido es la suma de los rangos de las tuplas originales. Pero este tampoco es el caso ideal. Si todos los atributos explícitos (o sea. para obtener el valor de dicho atributo en la tupla resultante. Para el caso en que las tuplas no posean los mismos atributos explícitos se calculará el “promedio” de cada atributo. 2) Lo que se realiza en este caso es una transformación similar a la combinación explicada anteriormente.María Daniela Navas Padrón: 75. para obtener el valor central (si la cantidad de valores es impar) o el promedio de los valores centrales (si la cantidad es par). Si todos los valores tienen la misma frecuencia se tomará cualquiera de dichos valores. la exactitud del proceso de clustering va decayendo. ya que mediante estas operaciones se pierde un poco el sentido de la . Si los atributos son categóricos: el “promedio” es la moda (mode) que es simplemente el valor más frecuente.626 Un modelo de Clustering Temporal Octubre 2004 Objeto1 Objeto2 T1 (Intervalos a analizar) Figura 3. Objeto1 Objeto2 T1 (Intervalos a analizar) Figura 3.11 T2 Tiempo Mientras mayor sea la cantidad de tuplas divididas o combinadas. se transforman las mismas en una sola. por lo que se puede aplicar el proceso de clustering temporal. sólo basta con que esté contenido íntegramente. que consiste en ordenar todos los valores. los no temporales). • Si los atributos son numéricos: el “promedio” es la mediana (median). ya que existen dos tuplas del Objeto 2 para el mismo intervalo de tiempo (T1) y es necesario contar sólo con una que represente a ese intervalo. son iguales en ambas tuplas.11. También es importante aclarar que la combinación no necesariamente se realiza entre dos tuplas.20 - . • El resultado de combinar las tuplas se observa en la Figura 3.10 muestra que ya no existen tuplas cuyos rangos de tiempo estén compartidos entre distintos intervalos a analizar. Ahora existe una única tupla contenida exclusivamente en cada intervalo a analizar.10 T2 Tiempo La Figura 3.

Lo ideal en este caso es cambiar la longitud del intervalo de tiempo a analizar de forma que se ajuste lo mejor posible a los rangos de tiempo válido de todas las tuplas. se mostrará un informe de las transformaciones realizadas. cada vez que se combine o divida una tupla. . para poder corregirlas y minimizarlas.María Daniela Navas Padrón: 75. Para permitir este análisis.21 - .626 Un modelo de Clustering Temporal Octubre 2004 realidad.

626 Un modelo de Clustering Temporal Octubre 2004 .22 - .María Daniela Navas Padrón: 75.

).23 - . A su vez. según su unidad de tiempo. • Listar los valores de los atributos separados por coma (. etc. precedidos por los caracteres @data . se deberán indicar todos los valores posibles del mismo. Ordinales: son categóricos. el proceso de clustering temporal implementado en Java consta de 2 etapas: • • Generación del archivo temporal. pero con cierto orden. denominada Weka (Ian et al. Clustering temporal. donde se transforma un archivo de entrada en un archivo que contemple el formato adecuado para procesarlo temporalmente. en la que se agregaron funciones específicas para realizar el proceso de Clustering Temporal.arff) debe cumplir con las siguientes pautas: • • Indicar el nombre de la relación. Y otra aplicación. Una aplicación implementada en Java. Por ejemplo Edad. Nominales: pueden ser descripciones.1 Generación del Archivo temporal El algoritmo de clustering temporal está implementado en WEKA. precedido por los caracteres @relation Listar nombre y tipo de datos de los atributos. que es una herramienta para Data Mining. por lo que el archivo de entrada al proceso de clustering (*. por ejemplo “Sexo”. implementada en Matlab.María Daniela Navas Padrón: 75. que puede ser Femenino o Masculino. Si el atributo es categórico. Los atributos pueden ser: o Categóricos: son valores discretos. senior” o Numéricos: reales o enteros. donde los datos de entrada se dividen en grupos o clusters. nombres. que se utiliza para analizar gráficamente los resultados del proceso de clustering.626 Un modelo de Clustering Temporal Octubre 2004 4 Implementación La implementación del Clustering Temporal se divide en dos partes. Ingresos. 4.[16]). semi senior. por ejemplo: “junior.

24 - .16000.32.32.23.253 wang.María Daniela Navas Padrón: 75.32.64000.290 microdata.26.32000. Este filtro combina o separa los registros según sea necesario.23.199 amdahl.29.64.32000. aunque deben tener distintas fechas) Uno o más atributos (numéricos o categóricos) que se compararán para realizar el clustering.749 Figura 4.).16.32000.32.32.128.1 Para cumplir con las condiciones de archivo temporal.16000.8000.256.16.64. crono. Por ejemplo “2004-12-05 21:35:00” Un atributo que sea un ID único. el archivo arff además debe poseer: • • • • Un atributo que indique Fecha de Inicio de validez del registro.29.626 Un modelo de Clustering Temporal Octubre 2004 Ejemplo de archivo arff: @relation 'cpu' @attribute @attribute @attribute @attribute @attribute @attribute @attribute @attribute vendor {adviser.16.125.sperry. Por ejemplo “2004-12-01 21:35:00” Un atributo que indique Fecha de Fin de validez del registro.32.381 sperry.64. Otro parámetro fundamental para el algoritmo es la cantidad de intervalos que se desean analizar.32.32000. . cómo se indicó en la sección anterior.29. Además. se pide que su orden se ingrese como parámetro del algoritmo de clustering temporal.64.253 amdahl. la misma debe tener el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. etc.32.8.32000.8000.dec.23.8.16000.wang} MYCT real MMIN real MMAX real CACH real CHMIN real CHMAX real class real @data adviser. que identifique al registro (puede haber más de un registro para el mismo ID. El orden de los atributos (temporales o no) puede ser cualquiera.prime.8.132 prime.381 dec.32.256.32.8000.8.32.32000. la misma debe tener el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”.8000.6000. pero debe ser el mismo para todas las tuplas.microdata.8000.16. a fin de determinar cuál es el atributo identificatorio y cuáles son los temporales.16000.253 dec.29.8.amdahl. A este archivo se le aplica un filtro que transforma los rangos de fechas en unidades temporales (intervalos) según los parámetros especificados (cantidad de intervalos.16.

por lo que el gradiente no está definido.( x − xi ) i =1 i =1 nj nj El gran problema de los métodos de mediana es que el gradiente de la función FW(x) no está definido para x=xi. calculada como la sumatoria ponderada de las distancias de todos los individuos al centroide... x − x ) ∑ ωi...1 K-D-Median La idea de todos los algoritmos de particionamiento es encontrar el punto mínimo de una función FW.....25 - . C ]) i =1 n Para el caso de los métodos basados en la distancia Euclídea (métodos de Mediana).Euclid ( si.Euclid ( x.. + ( xdim − xi dim )  =      i =1   i =1  nj nj (2. ( x2 − xi)i 2T . ( x − xi ) T . xi ) =∑ ωi.2.s2. REP[ sj .xnj} debemos encontrar el mínimo para esta función: FW ( x) = ∑ ωi. ya que la minimización de FW en este caso es extremadamente sencilla..María Daniela Navas Padrón: 75. como se desprende de la siguiente fórmula:  nj   nj 2 2 2  ∇FW ( x) = ∇ ∑ ωi. 1 i1 ( x2 − xi)i 2T . REP[ sj . la función a minimizar es: FW (C ) = ∑ ωi. El peso ωi > 0 refleja la relevancia de la observación si y Euclid ( x. C ]) i =1 n Donde: • • • • S = {s1.2.2.. Este problema no se presenta en el algoritmo Kmeans. ( x1 − xi1 ) + (x 2 − xi 2 ) + . El método K-means.2 Clustering temporal 4.( x −dimi) i dim i =1 i =1 x Como se observa de la última fórmula.( x − xi)dim i dim = ∑ ωi....(x − x )) (x − x ..c2.. como se muestra en el siguiente desarrollo: . x − x .. que utiliza la Distancia Euclídea al Cuadrado se enfoca en minimizar la función: FWKMeans (C ) = ∑ ωi... y ) = C = {c1. 1 i1 2.(x − x ).sn} es un conjunto de n ítems en un espacio real D-dimensional.. REP[si...626 Un modelo de Clustering Temporal Octubre 2004 4.( x − xi )  = ∇ ∑ ωi..C] es el punto en C más cercano si D ∑| x − y | i i i =1 2 O sea que si buscamos los puntos representativos para el cluster Cj = {x1. ( x − xi ) T .(x − x ).Euclid 2 ( si. para todos los puntos x = xi el divisor se hace 0.ck)} es el conjunto de k centroides de los clusters.x2..

Esta gran limitación del Kmeans nos llevó a considerar otros algoritmos que sacrifiquen un poco la velocidad de cálculo pero que arrojen valores utilizando un método de mediana.(x i i =1 nj 1 − xi1 ).2. como ya se expresó.. arrojó un centroide cercano al valor (2.. La figura 4. x 2 − xi 2 ..( x 2 − xi 2 ).(2..( xdim − xi dim )) = ∑ ωi.2 Como se observa.. en una distribución no simétrica (la de la figura se obtuvo multiplicando dos distribuciones uniformes [0. xdim − xi dim ) i =1 nj ⇒ ∇FWKMeans ( x min ) = 0 ⇔ x min = ∑ ω . ya que la contribución de éstos a la función FW es cuadrática en lugar de lineal.. el uso de la distancia Euclídea al cuadrado le quita sentido físico a los resultados si la distribución de individuos no es simétrica.626 Un modelo de Clustering Temporal Octubre 2004  nj   nj 2 2 2 ∇FWKMeans ( x) = ∇ ∑ ωi..( x − xi )  = ∇ ∑ ωi.26 - .( x1 − xi1 ..2 presenta en forma gráfica esta diferencia entre los resultados de ambos métodos: Figura 4.María Daniela Navas Padrón: 75. Sin embargo. sin embargo.1] y multiplicando por 10 el resultado) el centroide obtenido por Kmeans deja de representar al cluster. + (xdim − xi dim )     i =1   i =1 ( ) =    ∑ ω . representando así tanto al conjunto de valores medios como a los valores pequeños que forman el aglomerado entre 0 y 1.( x − xi ) T .x i i =1 nj nj i ∑ω i =1 i Esta simplicidad posiciona al Kmeans como el algoritmo óptimo en cuanto a velocidad de procesamiento.. . ( x1 − xi1 ) + ( x 2 − xi 2 ) + . Además lo hace altamente sensible a individuos aislados.2.2).. El método de Mediana. ya que aumenta considerablemente su amplitud influenciado por los individuos aislados entre 8 y 10.2.

2. como el gradiente de FW no está definido para los puntos del cluster la solución no es tan directa.626 Un modelo de Clustering Temporal Octubre 2004 El método propuesto. por lo que pueden ser excluidos del análisis. Por último se evalúa la función FW en cada uno de estos puntos y se encuentra el centroide. especificado en (Estivill-Castro. si se obtiene para cualquiera de sus individuos una recta normal a la función FW. y se han obtenido resultados satisfactorios. [10]) resulta ser el indicado para este proceso. La mediana discreta (o simplemente mediana) es el punto que está más cercano a la mediana continua. Sin embargo se puede definir una función llamada gradiente extendido de la siguiente forma: ∇ FW(x)     ∇ E FW ( x) =  1   max 1 − ∇FW ( x) . 4.V et. ya que obtiene resultados basados en la mediana haciendo cálculos altamente eficientes que reducen el tiempo de ejecución a valores comparables con el KMeans.[10]) que el gradiente extendido ∇ E (FW ) es normal al hiperplano tangente a FW para cualquier punto x. Esta propiedad permite utilizarlo para filtrar los individuos que están de un lado u otro del mismo. k-D-Median. como es el caso de FW) se obtiene en forma directa a escalar (función que va desde Rn partir de su gradiente. Resumidamente el k-D-Median funciona de la siguiente forma para hallar el centroide de un cluster: • • • Se encuentra la mediana discreta: La mediana continua es el punto que minimiza la distancia Euclídea entre todos los individuos. En particular si se elige el punto más cercano a la media (centro de masa de la distribución) se garantiza que se filtrará aproximadamente el 50% de los puntos en cada iteración. Obtención de la recta normal: En la mayoría de los casos la recta normal de un campo R1.al. se garantiza que los puntos cuyo producto escalar con esta recta es negativo estarán fuera del hiperplano tangente a FW en dicho punto y la función evaluada en ellos será mayor que la del punto seleccionado. N ( fn) = −∇( fn) En nuestro caso. Se ha realizado la comparación de cuánto se tarda en encontrar un centroide entre un grupo de individuos. El método se repite en forma iterativa hasta reducir la población de individuos a 6 o menos. El método propuesto en k-D-Median tiene en cuenta que la función FW es convexa.V et. El método más directo para buscar la mediana sería evaluar la función FW en todos los puntos.27 - .∇FW¬m ( xm)    ¬m    if x ∉ Cj if x ∈ Cj donde FW¬m ( x m ) es la función FW excluyendo al punto Xm del conjunto de valores. calculando el valor de la función FW punto por punto (Algoritmo estándar) y utilizando el algoritmo k-D-median descrito anteriormente.María Daniela Navas Padrón: 75. al. Se demuestra en (Estivill-Castro. .0. y determinar en que punto es mínima pero para clusters muy grandes este proceso es ineficiente y se hace imposible de usar. Entonces.2 Implementación de k-D-Median Se ha implementado una versión simplificada de este método en MatLab para verificar la utilidad del método.

28 - .María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 Los resultados obtenidos fueron los siguientes: Comparación algortimos clustering 650 600 550 500 450 615 Tiempo (seg) 400 350 300 250 200 150 100 50 0 3 0.5 100 7 1 200 33 2 500 150 Estándar k-D-Median 4 1000 5 2000 Individuos Figura 4.3 A continuación se muestra gráficamente cómo va avanzando el algoritmo k-D-median para encontrar el centroide: .

8 se muestra el resultado final. .626 Un modelo de Clustering Temporal Octubre 2004 Distribución Inicial: En la Figura 4. Última iteración: En la Figura 4.7 se muestra el resultado de la segunda y tercera iteración. El punto rojo es el centroide que deberá ser elegido. Luego de filtrar todos los individuos hasta obtener 6 o menos se procede a calcular el mínimo manualmente (lo cual es sencillo en tan pocos elementos) El punto rojo es el centroide hallado.5 se traza la recta normal a la función y se descartan todos los puntos que se excluyen del hiperplano tangente (azules).4 Primera iteración: En la Figura 4. En la Figura 4.María Daniela Navas Padrón: 75. El punto verde es el centroide encontrado utilizando el algoritmo k-means (como se observa está más influenciado por los puntos aislados) Figura 4.4 se observa la distribución inicial de individuos sobre la cual se quiere encontrar el punto más representativo (centroide). Este punto se calculó manualmente para corroborar los resultados.29 - . el cual coincide con el encontrado originalmente.6 y 4.

30 - .6 .5 Segunda Iteración: Figura 4.626 Un modelo de Clustering Temporal Octubre 2004 Primera iteración: Figura 4.María Daniela Navas Padrón: 75.

8 .626 Un modelo de Clustering Temporal Octubre 2004 Tercera Iteración: Figura 4.María Daniela Navas Padrón: 75.31 - .7 Última Iteración: Figura 4.

ya que la distancia categórica es siempre 1 excepto para x=xi.32 - . en la cual es 0.2. Un ejemplo de esta característica puede verse en la siguiente figura: Figura 4.10 . 0 si x = x j ij j ij) Esta función deja de ser convexa.3 Atributos Categóricos en K-D-Median Si graficamos la función FW definida anteriormente para dos atributos numéricos.María Daniela Navas Padrón: 75. la misma tiene el siguiente formato: Figura 4.626 Un modelo de Clustering Temporal Octubre 2004 4.9 Si se utilizan atributos categóricos la función FW pasa a estar definida como: FW (C ) = ∑ ωi. i =1 n j = AtNum ∑ ( xj − xij ) 2 + k = AtCateg ∑ (1 si x ≠ x .

12 • Para cuatro atributos. resultando en (0. Figura 4. 1 − 1 / 2       2   :   . por lo que se pudo calcular las posiciones en forma iterativa.María Daniela Navas Padrón: 75. 3 − 1 2. A continuación se detalla resumidamente el proceso de búsqueda de estos puntos: • Para dos atributos. Para encontrar el conjunto de puntos cuya distancia entre sí sea siempre 1.  0. 3 − 1  4 4 3 − el cuarto se completa con (0. los dos primeros quedan ( ½.33 - . y el tercero se obtiene a partir de un sistema de dos ecuaciones con dos incógnitas. por lo que hay que subsanar este impedimento para posibilitar el análisis de atributos categóricos.0).11 • Para tres atributos. 1 − 1 / 2 2  2.0) y (. 1 − 1 / 2 ). 2 4  2. . se procedió a desarrollar un algoritmo que resuelva el conjunto de ecuaciones. Además. la obtención de los puntos es directa: (½) y (– ½). los tres primeros aumentan con ceros su tercer dimensiòn. Hay distintos trabajos que tratan de solucionar este conocido problema.626 Un modelo de Clustering Temporal Octubre 2004 Esta característica invalida el principio de funcionamiento del algoritmo K-D-Median. se observó que la posición de cada punto depende sólo de los puntos anteriores. Lo que se propone en este trabajo es reemplazar los atributos categóricos por un conjunto de tuplas numéricas. de forma tal que la distancia entre dichas tuplas sea 1 si son distintas o 0 si son iguales (esta es la forma en que se tratan los atributos categóricos). y   2. Se observó que si la cantidad de atributos diferentes es n. 2 Figura 4. uno de ellos es (Estivill-Castro.½. [4]). la cantidad de dimensiones necesarias es siempre n-1.

se generan n tuplas de dimensión (n-1). a ( n − 1)( n − 3) a ( n − 1) 2 [ 2 . . . columna j.. tantos individuos como clusters se desee obtener. resultando así un conjunto numérico de X cuya función de FW (puramente numérica) evaluada en cada punto será igual a la función de FW (numérica y categórica) del dominio original. Se dividen las instancias (o registros) del archivo de entrada.34 - . 2 0 0 0 0 2 a 32 0 0 0 0 − a 42 . aparecen ciertas reglas que nos permitieron desarrollar la siguiente matriz: Siendo n los posibles valores de un atributo categórico. se encuentra que para cada nueva dimensión se van generando sistemas de ecuaciones.626 Un modelo de Clustering Temporal Octubre 2004 Figura 4. Cada valor categórico entonces se reemplaza por uno de estos vectores. Estos individuos serán los centroides originales..   . . De esta manera se puede obtener la mediana discreta por el método K-D-Median propuesto. cada vez con más incógnitas.2.        An   0   0 0 1 −a 11 2 2a 32 − 1 2a 32 . 4. se encontró que con un sistema iterativo que vaya calculando cada dimensión a partir de sus anteriores. y aplicar el resultado al dominio original de valores. .... 2 0 0 0 a 32 2 ... de la siguiente forma:  1  2  1  A1   − 2    A2   0 A    3= 0  A4    .. La particularidad de los vectores así definidos es que la distancia entre dos de ellos es siempre 1.. 2 − ∑ ( a 42 Ka ( n −1)( n −3) ) − 1 2 ] 0 a ( n −1)( n − 2 ) − x n ( n − 2 ) 2 2 2 x ( n −1)( n − 2 )               Siendo aij el valor de la matriz presente en la fila i... Sin embargo.. Se elige entre los individuos de cada unidad temporal (UT)..... ..4 Algoritmo k-D-Median Temporal Este algoritmo ejecuta los siguientes pasos: • • • Se reemplazan los atributos categóricos por atributos numéricos según la fórmula anterior y se normalizan los valores numéricos (no así los categóricos. según su unidad temporal (ya pasaron por el filtro principal).María Daniela Navas Padrón: 75... .. pues de la forma en que se calcularon la distancia siempre será 0 o 1).13 Repitiendo estos cálculos...

porque el algoritmo da el número de orden de cada cluster en forma totalmente aleatoria. y 3 y 1 respectivamente. el algoritmo armó clusters similares. sus centroides. a pesar que se llaman diferentes. para saber cómo se llamó a cada cluster en los distintos intervalos de tiempo.35 - . En el intervalo T2. según se explica en el siguiente apartado. De esto se obtiene una distribución de clusters en cada intervalo. hay que seguir la trayectoria del mismo. Se toman los individuos de cada cluster. el algoritmo armó ciertos clusters que numeró 1. pero lo que no se sabe es si el cluster denominado “Cluster 1” en el primer intervalo es el mismo “Cluster 1” en el segundo intervalo.5 Relación entre clusters de distintos tiempos Como se pudo observar. 4.14 3 2 1 T2 Por ejemplo. Lo mismo sucede con el cluster 2 y 3. Entonces. Ahora se determina la relación entre los clusters entre distintos tiempos. Para hacer esto. 2 1 3 T1 Figura 4. e información adicional para calcular las estadísticas. en cada UT. Por último. en la Figura 4. Luego se computan todas las combinaciones posibles de pasar de un cluster a otro al cambiar de tiempo y se encuentra la combinación que maximiza la cantidad de individuos que se quedaron en el mismo cluster. sin basarse en el nombre u orden que se le dio. un individuo que oscila entre 2 clusters) En este punto. se genera un archivo con la distribución de los clusters obtenidos en cada UT.626 Un modelo de Clustering Temporal Octubre 2004 • • • • • Se calcula la distancia Euclídea de cada individuo respecto de los centroides. Intuitivamente se puede decir que el cluster 1 evolucionó en el tiempo en el cluster 2. Este análisis permite garantizar que se mantiene el número máximo de individuos que permanecen en sus clusters originales.14 se puede observar que en el intervalo de tiempo T1. una función importante que debe cumplir el algoritmo de Clustering Temporal. Dicho individuo se asigna al cluster cuyo centroide esté más cercano (mínima distancia). se tiene la distribución final de cada cluster en cada UT. Por lo tanto.2.María Daniela Navas Padrón: 75. primero se cuentan cuántos individuos pasaron de cada cluster en el primer intervalo a cada cluster en el segundo intervalo. el algoritmo de clustering temporal aplica el algoritmo convencional para cada intervalo de tiempo. . y se aplica el algoritmo k-DMedian para obtener su nuevo centroide (mínimo de la función FW) Con los nuevos centroides se repiten los pasos 4 y 5 hasta que ningún individuo cambie de cluster o los cambios sean recurrentes (por ej. 2 y 3. es determinar cuál es la evolución de los clusters.

Cluster 3 D: Sólo se habilita si el archivo de entrada tiene 3 atributos. ampliar o reducir las imágenes.626 Un modelo de Clustering Temporal Octubre 2004 4. rotar las figuras e imprimir o guardar los resultados.6 Análisis de Resultados La aplicación implementada en Matlab analiza los resultados obtenidos a partir del archivo generado en la aplicación de clustering temporal. Muestra atributo por atributo. Cluster Inicial muestra la cantidad de individuos para cada cluster en un determinado tiempo.María Daniela Navas Padrón: 75. Se muestra gráficamente la representación de todos los clusters en cada UT. Cluster 2 D Tiempo: Sólo se habilita si el archivo de entrada tiene 2 atributos. Individuos Perdidos: Muestra en un gráfico de barras. Se muestra gráficamente la evolución de cada cluster a través de las distintas UT. y a su vez compara el mismo atributo en los distintos clusters. . Análisis por Atributo: esta opción está habilitada siempre. agregar textos o etiquetas. que muestra cuántos individuos cambiaron de cluster en el pasaje de un tiempo al siguiente. Se muestra gráficamente la representación de todos los clusters en cada UT. la evolución del mismo a través del tiempo. Cluster 3 D Tiempo: Sólo se habilita si el archivo de entrada tiene 3 atributos.2. los individuos que pertenecían a algún cluster en un tiempo dado. y Cluster Final indica la cantidad de individuos que tienen esos clusters en el tiempo siguiente. mediante un gráfico de líneas. y no pertenecen a ninguno en el tiempo siguiente debido a que no se cuenta con información sobre ellos en ese período. • Cada pantalla permite editar los gráficos. Estadísticas: Este es un gráfico de barras. La misma posee las siguientes opciones: • • • • • • Cluster 2 D: Sólo se habilita si el archivo de entrada tiene 2 atributos.36 - . Se muestra gráficamente la evolución de cada cluster a través de las distintas UT.

En el período siguiente (se realiza 2 veces por año). Esta encuesta es un programa nacional e intercensal que se desarrolla en INDEC desde 1972 y conjuntamente con las DIRECCIONES PROVINCIALES DE ESTADISTICA (DPE) desde 1974. se tomaron distintas variables de distintos muestreos. En el tercer período se vuelve a remover un 25% de la población original.626 Un modelo de Clustering Temporal Octubre 2004 5 Experimentación 5. y eso es lo que forma lo que en el INDEC denominan onda. pero sólo se mostrarán impresos aquellos que aporten algún dato significativo al estudio del caso. Cuando se hace referencia a %Perdidos. y así sucesivamente. se realiza una introducción sobre el tipo de datos. Cuando se analizan los resultados con Matlab. se indica cual es el porcentaje de registros sobre los cuales no se cuenta con información sobre esos atributos. los mismos se imprimen tal cual se muestran en la pantalla de salida del programa (respetando formato y nombres en inglés) para que sea más fácil la identificación de los ejemplos. un mismo hogar fue encuestado cuatro veces.María Daniela Navas Padrón: 75.2 Caso de prueba 1 Nombre del archivo: INDEC_1996-1997 . que un valor del atributo esté perdido (missing) se representa con un signo de pregunta (?) Cuando se muestran los resultados de Weka. La forma de realizar la encuesta es la siguiente: se toma una muestra de cierta cantidad de hogares. A continuación se detallan los juegos de datos utilizados para probar el algoritmo.1 Casos de prueba El INDEC. 5. • • 5. Al finalizar cuatro ciclos u ondas. se puede hacer un seguimiento de atributo por atributo. se les asigna un código único a cada uno. En el archivo. los resultados obtenidos con el software Weka y la visualización de los mismos a través de Matlab.1 Consideraciones generales • Cuando se detallan los atributos.1.37 - . Para probar el algoritmo de Clustering Temporal. Tiene como fin relevar información socioeconómica del país.1. se remueve el 25% de los hogares de la muestra y se incorpora un 25% de hogares que todavía no se encuestaron. Instituto Nacional de Estadística y Censo realiza una encuesta semestral denominada Encuesta Permanente de Hogares (EPH).

38 - 19% 6 Cant. 1:SI 2:NO Si tiene o no instalación de baño 1:Tiene de uso exclusivo 2:Tiene de uso compartido 3:No tiene baño Régimen de tenencia de la vivienda: 1:Propietario de la vivienda y el terreno. Habitaciones Agua Numérico 19% 11 Nominal 19% 2 Electricidad Nominal 19% 2 Baño Nominal 19% 3 Tenencia Vivienda Nominal 20% 6 .María Daniela Navas Padrón: 75. Al tomar 4 ondas los rangos de fechas válidos son: *01/01/1996 al 01/07/1996 *02/07/1996 al 31/12/1996 *01/01/1997 al 01/07/1997 *02/07/1997 al 31/12/1997 %Perdidos 0% Valores distintos 717 Fecha Inicio Fecha 0% 4 Fecha Fin Fecha 0% 4 Tipo Vivienda Nominal 1:Casa 2:Departamento 3:Vivienda en lugar de trabajo 4:Inquilinato 5:Hotel o Pensión 6:Vivienda no destinada a fines habitacionales. 2:Propietario de la vivienda solamente. 7:Vivienda en villa 8:Otro Cantidad de habitaciones que tiene la vivienda Si tiene o no instalación de agua. 4:Ocupante con relación de . Fechas de Inicio y Fin de validez del registro.626 Un modelo de Clustering Temporal Octubre 2004 Cantidad de Registros: 2868 Cantidad de Atributos:12 Detalle de atributos Nombre ID Tipo Nominal Detalle Código único que identifica a la vivienda a través de las 4 ondas. 1:SI 2:NO Si tiene o no instalación de electricidad. 3:Inquilino de la vivienda.

) 4:Adobe 5:Chorizo. Figura 5. 5:Ocupante Gratuito 8:Otros Materiales Vivienda Nominal Tipo de materiales de la vivienda (predominante de paredes externas): 1:Mampostería(ladrillo. bloques.39 - .626 Un modelo de Clustering Temporal Octubre 2004 dependencia.txt y son los siguientes: Intervalo de tiempo perteneciente a la unidad temporal 1 Desde: Mon Jan 01 00:00:00 ART 1996 Hasta: Mon Jul 01 00:00:00 ART 1996 Intervalo de tiempo perteneciente a la unidad temporal 2 Desde: Tue Jul 02 00:00:00 ART 1996 Hasta: Tue Dec 31 00:00:00 ART 1996 Intervalo de tiempo perteneciente a la unidad temporal 3 Desde: Wed Jan 01 00:00:00 ART 1997 Hasta: Wed Jul 02 00:00:00 ART 1997 Intervalo de tiempo perteneciente a la unidad temporal 4 Desde: Thu Jul 03 00:00:00 ART 1997 Hasta: Thu Jan 01 00:00:00 ART 1998 Figura 5. paneles) 2:Madera 3:Metal o fibrocemento (chapas. Monto de ingreso per cápita mensual del hogar. las fechas de inicio y fin se reemplazan por una unidad temporal cuyo valor está entre 0 y 4. En la solapa de preproceso se carga el archivo correspondiente. cartón o desechos 8:Otros 19% 6 Ingreso Familiar Numérico Monto de ingreso total mensual del hogar. etc.2 . 2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros: • Crono: Día (3) • Número de Intervalos: 4 • Posición Fecha Fin:2 • Posición Fecha Inicio: 1 • Posición ID: 0 Al terminar de filtrar. Los rangos de fechas que corresponden a cada unidad temporal se guardan en el archivo IntervalosDeTiempo.María Daniela Navas Padrón: 75.1 15% 554 Ingreso Per Capita Numérico 19% 705 Proceso de prueba 1) Se ejecuta el sistema WEKA.

67 202.0 3-96-1-1137 3-96-1-0559 3-96-1-0692 1 1 2 2.0 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 700.00 Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 Cluster 3 1.00 .67 300.00 1000.50 333.María Daniela Navas Padrón: 75.33 Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 Cluster 3 2.0 3.Temporal_k_D_Median -N 3 Relation: INDEC-1996-1997_Temporal Instances: 2868 Attributes: 11 Temp ID TipoVivienda CantHabitaciones Agua Electricidad Banio TenenciaVivienda MaterialesVivienda IngresoFamiliar IngresoPerCapita Test mode: evaluate on training data === Clustering model (full training set) === Temporal_k_D_Median===== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 0.40 - .00 810.0 3-96-1-0178 3-96-1-0671 3-96-1-0020 1 1 2 3.0 2. se elige el algoritmo Temporal_k_d_Median con los siguientes parámetros: • • Número de clusters: 3 Modo de clustering: Use Training Set El resultado de la corrida después de 4 segundos es el siguiente: === Run information === Scheme: weka.0 1.0 3.00 500.0 3.00 266.0 1.clusterers.00 166.0 3.00 900.0 3.00 900.0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 500.0 2.00 175.00 166.00 575.0 3.67 300.0 0.00 800.0 3-96-1-0646 3-96-1-1030 3-96-1-0523 1 1 2 3.0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1150.626 Un modelo de Clustering Temporal Octubre 2004 Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal 3) En la solapa de Cluster.0 0.

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 3.0 3.0 3.0 3-96-1-0615 3-96-1-1030 3-96-1-0523 1 1 2 3.0 3.0 3.0 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 700.00 800.00 900.00 233.33 266.67 300.00

=== Evaluation on training set ===

Temporal_k_D_Median ====== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 0.0 0.0 0.0 3-96-1-0178 3-96-1-0671 3-96-1-0020 1 1 2 3.0 3.0 3.0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1150.00 500.00 900.00 575.00 166.67 300.00

Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 Cluster 3 1.0 1.0 1.0 3-96-1-1137 3-96-1-0559 3-96-1-0692 1 1 2 2.0 3.0 3.0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 500.00 810.00 1000.00 166.67 202.50 333.33

Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 Cluster 3 2.0 2.0 2.0 3-96-1-0646 3-96-1-1030 3-96-1-0523 1 1 2 3.0 3.0 3.0 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 700.00 800.00 900.00 175.00 266.67 300.00

Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 3.0 3.0 3.0 3-96-1-0615 3-96-1-1030 3-96-1-0523 1 1 2 3.0 3.0 3.0 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 700.00 800.00 900.00 233.33 266.67 300.00

Clustered Instances 0 2868 (100%)

Figura 5.3

Al finalizar este proceso, se ha creado en el directorio de ejecución de WEKA, el archivo INDEC-1996-1997_Temporal_C3_T4.csv. C3 indica que se realizaron 3 clusters. T4 indica que se trata de 4 unidades temporales.

4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo INDEC-19961997_Temporal_C3_T4.csv. Las opciones Gráficos 2D y Gráficos 3D están deshabilitadas ya que estamos trabajando con un número mayor de atributos.

- 41 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Análisis por Atributo
Como ya se observa en las tablas de resultados, hay algunos atributos que se mantienen constantes a lo largo de los 4 períodos.

TipoVivienda: Para el Cluster 1 y Cluster 2, el atributo se mantiene constante con valor = 1 (Casa) a lo largo del tiempo. Para el Cluster 3, también se mantiene constante pero con valor=2 (Departamento).

En el gráfico la evolución se observa como líneas rectas a través del tiempo.

Figura 5.4 Los atributos Agua, Electricidad, Banio, y MaterialesVivienda también se mantienen constantes con valor = 1 (Sí tienen agua, electricidad y baño de uso exclusivo, y el material de la vivienda es principalmente de mampostería), por lo que los gráficos son similares al anterior.

- 42 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

CantHabitaciones: La cantidad de habitaciones de la vivienda se mantiene prácticamente constante durante los distintos períodos con valor = 3, salvo en el momento 2 del Cluster 1, que baja a 2.

Figura 5.5

- 43 -

6 . Pero hay un grupo (Cluster 1) que en los primeros dos períodos es propietaria de la vivienda y en los dos períodos siguientes es inquilino (valor = 3). Figura 5. Esto coincide con el análisis anterior donde hay una variación en la Cantidad de Habitaciones.María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 TenenciaVivienda: Se observa que hay un grupo de gente que es propietaria de la vivienda y el terreno (valor = 1) y esto se mantiene durante los 4 períodos.44 - .

45 - . Figura 5. para luego estabilizarse en $700.7 . luego se observa un pico mínimo de $500 (probablemente por desempleo). De Habitaciones.626 Un modelo de Clustering Temporal Octubre 2004 IngresoFamiliar: El grupo de individuos perteneciente al Cluster 1 comienza con un ingreso alto (alrededor de $1200). Y por últimos los individuos del Cluster 3 se mantienen bastante estabilizados a través de los períodos. Esa depresión se corresponde con los cambios en la Tenencia de la Vivienda y en la Cant. Los individuos del Cluster 2 comienzan abajo ($500) para luego subir un poco y estabilizarse.María Daniela Navas Padrón: 75.

Figura 5.8 .María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 IngresoPerCapita: El ingreso Per Capita sigue una trayectoria similar que el Ingreso Total Familiar como se puede observar en el gráfico.46 - .

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Estadísticas
A continuación se muestran los gráficos de barras que representan como fue el intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos: El análisis indica que entre el Tiempo 1, 2 y 3 existen severos traspasos de individuos entre los Clusters 1 y 2, que en el tiempo final se estabilizan. Esto indica que estos clusters comienzan siendo muy similares pero paulatinamente comienzan a evidenciar diferencias de Ingresos que los sitúan en dos posiciones diferentes. Se observa también que los períodos finales el número de individuos del Cluster 1 (representante del sector de menores recursos) es considerablemente inferior al del Cluster 2 (de recursos promedios).

Figura 5.9

- 47 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Figura 5.10

Figura 5.11

- 48 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Individuos Perdidos En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que pasan de un cluster a otro, pero se agregan los que no pasaron a ningún cluster, o sea, que en ese período de tiempo, no se contaba con información para ese individuo. El motivo puede ser simplemente que no haya querido responder a la encuesta. En este gráfico se observa que un gran número de individuos no tienen información en el Tiempo 2, y sí la vuelve a tener en los tiempos siguientes. Esto puede explicar los violentos traspasos de individuos del Cluster 1 hacia otros clusters, ya que las condiciones originales de esta población variaron considerablemente.

Figura 5.12

- 49 -

13 Figura 5.14 .50 - .626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.María Daniela Navas Padrón: 75.

3 Caso de prueba 2 Nombre del archivo: INDEC_1996-1997_2D (Son los mismos individuos que el caso anterior. Como se puede observar. En el siguiente gráfico se muestra el tiempo que demora el proceso en finalizar.1. pero se tomaron sólo 2 atributos para permitir otro tipo de análisis) Cantidad de Registros: 2868 Cantidad de Atributos:5 Detalle de atributos Nombre ID Tipo Nominal Detalle Código único que identifica a la vivienda a través de las 4 ondas.16 15% 554 Ingreso Per Capita Numérico 19% 705 .María Daniela Navas Padrón: 75. Performance INDEC 1996-1997 Nº Clusters 8 6 4 2 0 1 2 3 4 5 6 Tiempo (segundos) Figura 5. Monto de ingreso per cápita mensual del hogar. Figura 5. hay muy poca variación de tiempo a medida que aumenta la cantidad de clusters. Al tomar 4 ondas los rangos de fechas válidos son: *01/01/1996 al 01/07/1996 *02/07/1996 al 31/12/1996 *01/01/1997 al 01/07/1997 *02/07/1997 al 31/12/1997 %Perdidos 0% Valores distintos 717 Fecha Inicio Fecha 0% 4 Fecha Fin Fecha 0% 4 Ingreso Familiar Numérico Monto de ingreso total mensual del hogar.15 5. Fechas de Inicio y Fin de validez del registro.51 - .626 Un modelo de Clustering Temporal Octubre 2004 Performance Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos.

2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros: • Chronon: Día (3) • Número de Intervalos: 4 • Posición Fecha Fin:2 • Posición Fecha Inicio: 1 • Posición ID: 0 Al terminar de filtrar.17 Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal 3) En la solapa de Cluster. En la solapa de preproceso se carga el archivo correspondiente.María Daniela Navas Padrón: 75.Temporal_k_D_Median -N 4 Relation: INDEC-1996-1997-2D-Temporal Instances: 2868 Attributes: 4 Temp ID IngresoFamiliar .txt y son los siguientes: Intervalo de tiempo perteneciente a la unidad temporal 1 Desde: Mon Jan 01 00:00:00 ART 1996 Hasta: Mon Jul 01 00:00:00 ART 1996 Intervalo de tiempo perteneciente a la unidad temporal 2 Desde: Tue Jul 02 00:00:00 ART 1996 Hasta: Tue Dec 31 00:00:00 ART 1996 Intervalo de tiempo perteneciente a la unidad temporal 3 Desde: Wed Jan 01 00:00:00 ART 1997 Hasta: Wed Jul 02 00:00:00 ART 1997 Intervalo de tiempo perteneciente a la unidad temporal 4 Desde: Thu Jul 03 00:00:00 ART 1997 Hasta: Thu Jan 01 00:00:00 ART 1998 Figura 5. se elige el algoritmo Temporal_k_d_Median con los siguientes parámetros: • • Número de clusters: 4 Modo de clustering: Use Training Set El resultado de la corrida después de 4 segundos es el siguiente: === Run information === Scheme: weka.clusterers. las fechas de inicio y fin se reemplazan por una unidad temporal cuyo valor está entre 0 y 4.52 - .626 Un modelo de Clustering Temporal Octubre 2004 Proceso de prueba 1) Se ejecuta el sistema WEKA. Los rangos de fechas que corresponden a cada unidad temporal se guardan en el archivo IntervalosDeTiempo.

00 Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 Cluster 4 3.0 1.0 0.00 720.50 Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 Cluster 3 Cluster 4 1.0 3-96-1-0594 3-96-1-0002 3-96-1-0695 3-96-1-0183 200.00 75.María Daniela Navas Padrón: 75.00 0.0 0.00 1600.00 1600.50 350.00 430.00 50.00 700.00 180.00 244.00 244.50 Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 1.626 Un modelo de Clustering Temporal Octubre 2004 IngresoPerCapita Test mode: evaluate on training data === Clustering model (full training set) === Temporal_k_D_Median===== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 Cluster 4 0.00 213.0 1.0 3.00 732.00 800.50 200.00 .00 1500.0 1.00 433.00 1570.0 2.00 === Evaluation on training set === Temporal_k_D_Median ====== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 Cluster 4 0.00 72.33 392.00 800.00 220.0 0.0 3-96-1-0196 3-96-1-0105 3-96-1-0432 3-96-1-1039 145.53 - .0 0.00 152.0 1.0 3-96-1-0001 3-96-1-0669 3-96-1-0560 3-96-1-0618 0.0 3-96-1-0196 3-96-1-0105 145.00 400.0 2.00 500.50 200.0 0.00 Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 Cluster 3 Cluster 4 2.00 732.00 305.0 3-96-1-0871 3-96-1-0091 3-96-1-0785 3-96-1-0608 300.00 305.00 0.0 2.0 3.00 215.0 0.00 72.00 400.00 640.33 220.0 3-96-1-0001 3-96-1-0669 3-96-1-0560 3-96-1-0618 0.00 1300.00 152.0 3.

00 720.0 3.20 se muestra este cluster ampliado para poder estudiarlo con mayor detalle.00 180.00 50.00 Clustered Instances 0 2868 (100%) Figura 5.0 3-96-1-0871 3-96-1-0091 3-96-1-0785 3-96-1-0608 300.00 Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 Cluster 3 Cluster 4 2. En un primer momento abarca cierto número de individuos. cuyas características son Ingreso familiar entre $100 y $500 e Ingreso Per Cápita entre $100 y $400.50 350.00 215.00 1300. se selecciona el Cluster 4 y se observa el comportamiento del mismo a través de los distintos tiempos. Por ejemplo.csv. y en la mayoría de los casos sólo una o dos. mostrando además que en cada hogar habitan no más de 3 personas.0 2.33 392.0 1.00 430.00 700.00 1570.00 75.csv. 4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo INDEC-19961997_Temporal_C3_T4. Gráficos 2D Este gráfico muestra para cada período (Tiempo) cómo es la distribución de los individuos según sus atributos.00 Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 Cluster 4 3.0 2.626 Un modelo de Clustering Temporal Octubre 2004 Cluster 3 Cluster 4 1.0 3.00 433. Las opciones de Gráficos 3D están deshabilitadas ya que estamos trabajando sólo con dos atributos. T4 indica que se trata de 4 unidades temporales.María Daniela Navas Padrón: 75. C4 indica que se realizaron 4 clusters.18 Al finalizar este proceso. el archivo INDEC-1996-1997-2D_Temporal_C4_T4. Cómo se trata de sólo dos atributos se puede realizar un gráfico bidimensional. se ha creado en el directorio de ejecución de WEKA.0 3-96-1-0432 3-96-1-1039 1500.54 - .0 3.33 220.00 220.00 213. En la Figura 5.00 640.0 2. .00 500.0 3-96-1-0594 3-96-1-0002 3-96-1-0695 3-96-1-0183 200.

20 .626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.María Daniela Navas Padrón: 75.55 - .19 Figura 5.

Figura 5. cede los de menor ingreso al Cluster 1. En la ampliación del cuadro (Figura 5.56 - . Se observa también que aunque sigue siendo indicador de las familias chicas. se observan las 4 rectas que representan el número de integrantes según la relación entre Ingreso Total y Per Capita.María Daniela Navas Padrón: 75. indicando que algunas de las familias tienen un nuevo integrante. si bien mantiene la mayoría de sus individuos. Por esta razón. se observa que el que el Ingreso Familiar del Cluster 4 aumenta (entre $200 y $650) haciéndose comparable con los valores del Cluster 2.21 .626 Un modelo de Clustering Temporal Octubre 2004 En el Tiempo 2 (6 meses después). el número máximo de integrantes no se limita a 3 sino a 4.22). y adopta muchos de los del Cluster 2.

que sigue siendo un fiel representante de las familias chicas. Cómo resultado de esto el Cluster 4 pasa a ser representativo de las familias de pocos miembros y de recursos limitados (en todo momento las familias de altos recursos están representadas por el Cluster 3).626 Un modelo de Clustering Temporal Octubre 2004 Figura 5. .57 - .se observa un importante crecimiento económico en el Cluster 4. el Cluster 4 no varía significativamente pero se observa una variación del Cluster 2 que pasa a representar a las familias más numerosas y de Ingreso limitado.María Daniela Navas Padrón: 75. En el Tiempo 4 (Figura 5.24) . estos pasan a formar parte del Cluster 4.23).22 En el Tiempo 3 (Figura 5. Al hacerse el Ingreso Familiar comparable con muchos individuos del Cluster 3.

24 .626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.23 Figura 5.María Daniela Navas Padrón: 75.58 - .

para el caso del Cluster 4 analizado anteriormente el gráfico se muestra en la figura siguiente.María Daniela Navas Padrón: 75.59 - . se observa un aumento inicial en el Ingreso Familiar. seguido de un enfoque del cluster en las familias con menor número de individuos (mayoritariamente entre 1 y 2 integrantes). Complementando el análisis anterior.25 . También hay que tener en cuenta que la escala entre un gráfico y otro cambia según los valores que se deseen graficar. Por ejemplo. Figura 5.626 Un modelo de Clustering Temporal Octubre 2004 Gráfico 2D Tiempo Este gráfico provee información similar al gráfico anterior pero vista desde otro punto de vista. para culminar con aumento sustancial en el Ingreso Familiar. se observa en un solo gráfico la evolución en el tiempo de un solo cluster.

Figura 5.60 - .María Daniela Navas Padrón: 75.26 .626 Un modelo de Clustering Temporal Octubre 2004 Análisis por Atributo IngresoFamiliar: Tanto los gráficos del Atributo 1 como los del Atributo 2 muestran que el Cluster 1 es representativo del sector de menor Ingreso Familiar. el Cluster 2 y el Cluster 4 representan al sector de Ingreso Familiar limitado y el Cluster 3 a los que perciben mayores ingresos. Las tendencias temporales son crecientes en los Clusters 1 y 4 y no varían significativamente en los dos restantes.

30). Entre el Tiempo 2 y 3 (Figura 5. .27 Estadísticas A continuación se muestran los gráficos de barras que representan cómo fue el intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos: Entre el Tiempo 1 y Tiempo 2 (Figura 5. el mayor cambio se observa en el Cluster 4 que como consecuencia de su crecimiento económico adopta un número importante de individuos del Cluster 3. el Ingreso Per Capita desciende hasta hacerse menor que en el Cluster 4.626 Un modelo de Clustering Temporal Octubre 2004 IngresoPerCapita: En este gráfico se observa que aunque el Ingreso Familiar es mayor en el Cluster 2 que en el 4. corroborando el aumento económico indicado anteriormente. al convertirse este paulatinamente en representante de las familias de mayor número.61 - .28) se observa que el Cluster 4 capta gran parte de los individuos del Cluster 2. Cómo ya se explicitó esto se corresponde con que el Cluster 2 pasa a representar a las familias de ingreso limitado y mayor número de integrantes.29) el cluster 4 no presenta grandes variaciones. Entre el Tiempo 3 y 4 (Figura 5. pero se observa el traspaso de individuos entre el Cluster 3 y el 4. Figura 5.María Daniela Navas Padrón: 75.

28 Figura 5.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.María Daniela Navas Padrón: 75.62 - .29 .

En este análisis queda evidenciado que en el Tiempo 2 no se cuenta con información sobre ciertos hogares.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.30 Individuos Perdidos En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que pasan de un cluster a otro. no se contaba con información para ese individuo. . que en un principio formaban parte del Cluster 1. o sea. El motivo puede ser simplemente que no haya querido responder a la encuesta.63 - . pero se agregan los que no pasaron a ningún cluster. que en ese período de tiempo.María Daniela Navas Padrón: 75.

64 - .María Daniela Navas Padrón: 75.31 Figura 5.32 .626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.

Como se puede observar prácticamente no hay variación de tiempo a medida que aumenta el número de clusters.34 . Performance INDEC 1996-1997 2D Nº Clusters 6 4 2 0 1 2 3 4 5 6 Tiempo (segundos) Figura 5. incluso menos que cuando se trataba de un juego de datos con más atributos.María Daniela Navas Padrón: 75.65 - . En el siguiente gráfico se muestra el tiempo que demora el proceso en finalizar.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.33 Performance Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos.

txt y son los siguientes: . En la solapa de preproceso se carga el archivo correspondiente. Fechas de Inicio y Fin de validez del registro.35 1% 94 Total Horas Trabajadas X Semana Ingreso Total Numérico 0% 139 Numérico 0% 252 Proceso de prueba 1) Se ejecuta el sistema WEKA. Al tomar 4 ondas los rangos de fechas válidos son: *01/01/1996 al 01/07/1996 *02/07/1996 al 31/12/1996 *01/01/1997 al 01/07/1997 *02/07/1997 al 31/12/1997 %Perdidos 0% Valores distintos 1099 Fecha Inicio Fecha 0% 4 Fecha Fin Fecha 0% 4 Edad Numérico Edad del miembro del hogar entrevistado Cantidad de horas totales que el individuo trabaja por semana. Ingreso Total Mensual del Individuo Figura 5. las fechas de inicio y fin se reemplazan por una unidad temporal cuyo valor está entre 0 y 4. y sólo se tomaron 3 atributos para permitir un análisis tridimensional) Cantidad de Registros: 4396 Cantidad de Atributos: 6 Detalle de atributos Nombre ID Tipo Nominal Detalle Código único que identifica a la vivienda a través de las 4 ondas.66 - .626 Un modelo de Clustering Temporal Octubre 2004 5.María Daniela Navas Padrón: 75.1.4 Caso de prueba 3 Nombre del archivo: PER_INDEC-2001-2002_3D (Este es otro juego de datos. referidos a las personas. 2) Se aplica al archivo el filtro CreateTemporalUnits con los siguientes parámetros: • Chronon: Día (3) • Número de Intervalos: 4 • Posición Fecha Fin:2 • Posición Fecha Inicio: 1 • Posición ID: 0 Al terminar de filtrar. Los rangos de fechas que corresponden a cada unidad temporal se guardan en el archivo IntervalosDeTiempo.

00 150.626 Un modelo de Clustering Temporal Octubre 2004 Intervalo de tiempo perteneciente a la unidad temporal 1 Desde: Mon Jan 01 00:00:00 ART 2001 Hasta: Mon Jul 01 00:00:00 ART 2001 Intervalo de tiempo perteneciente a la unidad temporal 2 Desde: Tue Jul 02 00:00:00 ART 2001 Hasta: Tue Dec 31 00:00:00 ART 2001 Intervalo de tiempo perteneciente a la unidad temporal 3 Desde: Wed Jan 01 00:00:00 ART 2002 Hasta: Wed Jul 02 00:00:00 ART 2002 Intervalo de tiempo perteneciente a la unidad temporal 4 Desde: Thu Jul 03 00:00:00 ART 2002 Hasta: Thu Jan 01 00:00:00 ART 2002 Figura 5.0 3-96-1-08761 2-01-1-09791 2-01-1-08672 2-01-1-01552 39.00 0.0 0.María Daniela Navas Padrón: 75.00 0.00 200.00 42.00 500.00 24.00 0.00 66.00 45.36 Ahora el archivo está listo para aplicarle el proceso de Clustering Temporal 3) En la solapa de Cluster.67 - .00 0. se elige el algoritmo Temporal_k_d_Median con los siguientes parámetros: • • Número de clusters: 5 Modo de clustering: Use Training Set El resultado de la corrida después de 4 segundos es el siguiente: === Run information === Scheme: weka.0 0.0 0.00 .Temporal_k_D_Median -N 5 Relation: PER_INDEC-2001-2002-Temporal Instances: 4396 Attributes: 5 Temp ID Edad TotalHorasTrabXSemana IngresoTotal Test mode: evaluate on training data === Clustering model (full training set) === Temporal_k_D_Median====== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 Cluster 4 0.clusterers.

00 0.0 2-01-1-09371 2-01-1-08351 44.00 0.00 22.0 2.0 3.00 0.00 42.00 69.00 0.00 70.00 Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 1.00 0.0 2-01-1-09652 2-01-1-08351 2-01-1-09573 2-01-1-07781 2-01-1-06064 42.00 41.00 0.0 2-01-1-10061 2-01-1-07791 2-01-1-06843 2-01-1-10811 2-01-1-03803 45.0 1.0 3.0 2-01-1-09652 2-01-1-08351 2-01-1-09573 2-01-1-07781 2-01-1-06064 42.00 800.00 10.626 Un modelo de Clustering Temporal Octubre 2004 Cluster 5 0.00 1000.00 === Evaluation on training set === Temporal_k_D_Median====== Cluster centroids for temporal unit 1: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 0.00 0.00 0.00 21.00 Cluster centroids for temporal unit 2: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 1.0 1.00 Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 2.00 0.00 48.00 0.0 0.0 0.00 0.0 2.María Daniela Navas Padrón: 75.00 66.00 0.00 .00 0.00 48.0 3.00 0.00 70.0 2-01-1-05552 11.00 1000.00 0.0 3-96-1-08761 2-01-1-09791 2-01-1-08672 2-01-1-01552 2-01-1-05552 39.00 Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 3.00 150.0 1.00 0.00 200.00 0.0 0.00 0.0 2.00 0.00 0.00 0.00 22.00 45.00 500.0 0.00 200.00 0.00 0.00 9.00 69.0 3.00 48.0 2-01-1-09371 2-01-1-08351 2-01-1-06054 2-01-1-07021 2-01-1-06065 44.00 0.00 41.0 1.00 20.0 1.00 11.00 41.00 1000.00 0.00 24.00 0.00 0.00 42.00 0.00 41.00 8.00 0.00 0.0 2.0 2.0 1.0 1.00 Cluster centroids for temporal unit 3: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 2.00 200.00 1000.00 0.00 48.0 1.00 0.00 10.68 - .00 0.00 0.00 200.00 150.00 45.00 0.00 0.00 174.00 0.

0 3.00 Clustered Instances 0 4396 (100%) Figura 5.00 0. Gráficos 3D Este gráfico muestra para cada período (Tiempo) cómo es la distribución de los individuos según sus atributos. C5 indica que se realizaron 5 clusters. Por esa razón.00 70. El Cluster 5 abarca los individuos de hasta 20 años.00 20. El Cluster 1 abarca los individuos entre 30 y 40 años que trabajan muy pocas horas.00 Cluster centroids for temporal unit 4: Cluster 1 Cluster 2 Cluster 3 Cluster 4 Cluster 5 3.00 0. El Cluster 4 abarca todos los individuos mayores a 40 años que trabajan muy pocas horas (desocupados y jubilados) y por último el Cluster 2 se distribuye en forma esférica entre todos los individuos que trabajan la mayor cantidad de horas.00 0. Este cluster representa claramente al promedio de la población que trabaja entre 40 y 100 horas semanales.0 3.37 Al finalizar este proceso. Como se trata de sólo tres atributos se puede realizar un gráfico tridimensional. En el gráfico 5. dividiéndose en distintas franjas de edades.María Daniela Navas Padrón: 75. El Cluster 3 abarca los individuos entre 20 y 30 años que trabajan hasta 50 horas semanales.00 150.00 9. Este cluster es altamente representativo del grupo de los desocupados.0 3.0 2-01-1-06054 2-01-1-07021 2-01-1-06065 21.00 0.38 (primer semestre del 2001) las estadísticas muestran una alarmante cantidad de desocupados.00 8. .00 0.00 45.00 174. excepto un pequeñísimo grupo cercano a los 20 años que trabaja hasta 50 horas semanales.csv Las opciones de Gráficos 2D están deshabilitadas ya que estamos trabajando con tres atributos. se ha creado en el directorio de ejecución de WEKA.csv.00 42. el archivo PER_INDEC-2001-2002-3D_Temporal_C5_T4.00 0. mayoritariamente 0.0 2.00 0. 4) Se ejecuta el programa Resultados desde MatLab y se abre el archivo PER_INDEC2001-2002-3D_Temporal_C5_T4.00 0. y percibe sueldos bajos.00 0. Se observa que en su gran mayoría ninguno trabaja ni percibe sueldo.00 0.0 3. 4 de los 5 clusters se ordenaron en la franja de Cantidad de horas trabajadas = 0. T4 indica que se trata de 4 unidades temporales.69 - .626 Un modelo de Clustering Temporal Octubre 2004 Cluster 3 Cluster 4 Cluster 5 2.00 0.00 800.0 2. Sin embargo el cluster abarca personas entre 20 y 65 años. y con horas trabajadas entre 10 y 120. Es de notar que el centroide se ubicó a los 42 años y 45 horas semanales.00 200.0 2-01-1-10061 2-01-1-07791 2-01-1-06843 2-01-1-10811 2-01-1-03803 45. con un ingreso promedio de $500.00 70.

Figura 5.38 En la Figura 5. que pasaron de tener 0 horas trabajadas a tener hasta 25 horas. cediendo los individuos de menor cantidad de horas trabajadas a los clusters 1.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.39 . El Cluster 2 evolucionó hacia mayor cantidad de horas trabajadas y mayor sueldo (el centroide está en 48 hs y sueldo cercano a $1000). 3 y 4. Se observa además que el Cluster 4 (individuos de edad avanzada) percibe ingresos superiores al período anterior. Por último el cluster 5 (individuos de hasta 18 años) no refleja ninguna variante. los clusters mantuvieron sus posiciones pero se observan leves mejoras en las horas trabajadas y en los sueldos percibidos.María Daniela Navas Padrón: 75.70 - .39 (segundo semestre del 2001).

Los clusters 1. (aproximadamente $800). en el segundo semestre del 2002 (Figura 5.40 Por último. la cantidad de horas trabajadas sigue siendo 0. . sin embargo. que los centroides de los tres clusters siguen estando en las 0 horas trabajadas. Figura 5.71 - . Cómo. indicando que sus individuos representativos son desocupados.41). las variaciones son muy leves. 3 y 4 ganan espacio en las horas trabajadas llegando hasta la franja de 40 horas.626 Un modelo de Clustering Temporal Octubre 2004 En la Figura 5. Es de notar. y el aumento de los ingresos del Cluster 1 (su centroide evolucionó de 0 a aproximadamente $150). este aumento indica la presencia de Planes Trabajar o Planes Jefes y Jefas de Hogar. destacándose únicamente el descenso en promedio de los ingresos percibidos del Cluster 2. sin embargo.40 (Tiempo 3: Primer semestre de 2002) se repite la tendencia anterior.María Daniela Navas Padrón: 75.

72 - . También hay que tener en cuenta que la escala entre un gráfico y otro cambia según los valores que se deseen graficar. vemos que se presentaron pequeñas oscilaciones pero el cluster en general se mantuvo bastante constante. Por ejemplo.41 Gráfico 3D Tiempo Este gráfico provee información similar al gráfico anterior pero vista desde otro punto de vista. En la figura siguiente se muestra en un solo gráfico el análisis que se hizo anteriormente paso por paso. se observa en un solo gráfico la evolución en el tiempo de un solo cluster.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5. para el Cluster 2.María Daniela Navas Padrón: 75. .

73 - .43 se observa la trayectoria del Cluster 4. por lo que se agruparon dentro un mismo cluster que representa a los desocupados.43 .María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.42 En la Figura 5. Acá se puede observar que hay un gran número de individuos cuyos ingresos son 0 o un valor muy bajo y la edad es mayor a 45 años. Figura 5.

Figura 5.626 Un modelo de Clustering Temporal Octubre 2004 Análisis por Atributo Edad: En este gráfico se observa que se agrupa en un mismo cluster a los individuos que tienen Edad similar.María Daniela Navas Padrón: 75. Se observa que por tratarse de variaciones muy leves de tiempo los centroides no se modifican considerablemente.74 - .44 .

45 . todos tienen sus centroides en 0 horas trabajadas. Este análisis se complementa con el del Grafico3D. Figura 5.75 - . Y es un indicador explícito de la desocupación que se vivió en la época analizada.626 Un modelo de Clustering Temporal Octubre 2004 Horas Trabajadas: Aquí se puede observar que excepto el Cluster 2.María Daniela Navas Padrón: 75.

626 Un modelo de Clustering Temporal Octubre 2004 Ingreso Mensual: El análisis de este atributo también concuerda con los otros dos. que muestra un descenso a $0 en el segundo y tercer período. para luego estabilizarse en un valor cercano a $150. Los individuos del Cluster 5 (Menores de 20) no tienen Ingresos.46 t . Figura 5. los del Cluster 4 (entre 50 y 95 años) tienen un Ingreso Bajo (seguramente se trata de jubilación o pensión ya que no cuentan con Horas Trabajadas) y el resto de los clusters cuentan con Ingresos acorde a sus características.María Daniela Navas Padrón: 75.76 - . El caso más grave es el del Cluster 1 (individuos entre 30 y 50 años que no trabajan). posiblemente por Planes otorgados ya que las horas trabajadas siguen siendo 0. El Cluster 2 representante del grupo de individuos con mayor horas trabajadas muestra una evolución de $500 a $1000 entre el primer y segundo período para luego mantenerse en ese valor y tener una leve disminución el cuarto período.

este aumento indica una tendencia positiva de la situación laboral.626 Un modelo de Clustering Temporal Octubre 2004 Estadísticas A continuación se muestran los gráficos de barras que representan como fue el intercambio de individuos entre un cluster y otro al transcurrir los distintos períodos: En los 4 períodos se observa que la gran mayoría de los individuos se mantienen en sus clusters. Ya que este cluster es representativo de las personas que trabajan.47 .María Daniela Navas Padrón: 75. sin embargo los pequeños cambios muestran una tendencia creciente en el Cluster 1 (individuos entre 30 y 50 años en situación de desocupación). El Cluster 2 se mantiene constante hasta el tercer período. registrando un leve aumento de individuos en el traspaso al último período.77 - . Figura 5.

no se contaba con información para ese individuo. o sea.49 Individuos Perdidos En los siguientes gráficos de barras se muestran las mismas estadísticas de individuos que pasan de un cluster a otro. El motivo puede ser simplemente que no hay querido responder a la encuesta.María Daniela Navas Padrón: 75.78 - . o puede ser algo más complejo como mudanza o fallecimiento.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5. pero se agregan los que no pasaron a ningún cluster. .48 Figura 5. que en ese período de tiempo.

en el primer período había individuos en los clusters 2 y 4. Figura 5.79 - . que en el Período 2 pasaron a formar parte de los clusters 2 y 3. Asimismo.María Daniela Navas Padrón: 75. sobre los que en el segundo período no se contaba información.51 .50 Figura 5.626 Un modelo de Clustering Temporal Octubre 2004 En el período 1 había una pequeña cantidad de individuos sobre los que no se contaba información. no existe ningún individuo sin información. Un comportamiento similar se observa durante los otros períodos. pero ya para el último Tiempo.

En el siguiente gráfico se muestra el tiempo que demora el proceso en finalizar. sí se nota un pequeño aumento en el tiempo comparando con el juego de datos INDEC 1996-1997 ya que se trata del doble de registros.5 1 2 3 4 5 6 Nº Clusters Tiempo (segundos) Figura 5. Como se puede observar prácticamente no hay variación de tiempo a medida que aumenta el número de clusters. Performance PER_INDEC 2001-2002 3D 6.María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 Figura 5.53 .52 Performance Se varía el parámetro Número de Clusters entre 2 y 7 para este juego de datos.80 - .5 5 4.5 6 5.

En particular.María Daniela Navas Padrón: 75.5.3. Las pruebas consistieron en aplicar el algoritmo Temporal_k-D-Median. At. y se pueden conocer estadísticas o trayectorias de los individuos.4. Nominales Numéricos 9 5 9 5 9 5 9 5 9 5 9 5 6 16 6 16 6 16 6 16 6 16 6 16 Figura 5. y los tiempos del algoritmo no variaron considerablemente entre un número de clusters y otro. Al utilizar distintas cantidades de individuos. a los juegos de datos y observar el tiempo transcurrido hasta la finalización del mismo. se obtuvieron luego de ejecutar el sistema WEKA en una PC con procesador Pentium III 733 Mhz. con 256 Mb de memoria RAM. para observar las ventajas de ejecutar el algoritmo temporal en forma completa.54 Valores Desconocidos Si Si Si Si Si Si Si Si Si Si Si Si Unidades Temporales 4 4 4 4 4 4 5 5 5 5 5 5 Los resultados que se describen a continuación. El algoritmo se ejecutó para formar distintas cantidades de clusters. con el Clustering Temporal se puede obtener la relación de los clusters a través de los distintos tiempos.1.6 y 7 clusters. Por un lado.626 Un modelo de Clustering Temporal Octubre 2004 5. se crearon 2.81 - . . es similar o incluso mayor al tiempo que se demora en ejecutar el algoritmo temporal. sí se observó una variación de la duración del procesamiento. También se aplicó el algoritmo k-D-Median (algoritmo no temporal) a cada una de las unidades temporales.5 Prueba de Performance A continuación se detallan los juegos de datos utilizados para probar la performance del algoritmo de Clustering Temporal: Dataset Cholesterol1 Cholesterol2 Cholesterol3 Cholesterol4 Cholesterol5 Cholesterol6 Eucalyptus1 Eucalyptus2 Eucalyptus3 Eucalyptus4 Eucalyptus5 Eucalyptus6 Instancias 1212 2424 9696 19392 37784 65536 1150 2300 9200 18400 36800 65500 Atributos 16 16 16 16 16 16 22 22 22 22 22 22 At. por lo que a continuación se transcribe el promedio de los tiempos obtenidos. la suma de los tiempos si se ejecuta por separado. pero lo más importante.

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Perform ance del Clustering Tem poral

50 45 40 35 Tiempo (segundos) 30 25 20 15 10 5 0 1000 Cholesterol Eucalyptus

11000

21000

31000

41000

51000

61000

Data Sets

Figura 5.55

- 82 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

6 Conclusiones
6.1 Conclusiones
El método de Clustering Temporal propuesto en la presente tesis, realiza el proceso de clustering en forma convencional (agrupa los individuos teniendo en cuenta sólo los atributos espaciales o “no temporales” de los mismos) para distintos momentos de tiempo. O sea, que a través de los atributos temporales de una base de datos es posible relacionar los clusters en los distintos tiempos. Esto nos permite observar la trayectoria de los objetos, ver cómo varían los clusters durante el transcurso del tiempo, y obtener distintas estadísticas sobre el movimiento de clusters y objetos. La aplicación de este algoritmo a datos temporales brinda información muy difícil de obtener aplicando sólo un algoritmo de clustering convencional. Además de la información que brinda, una importante ventaja del método propuesto es que funciona como un molde o framework: se basa en un algoritmo de clustering convencional, y a esto le agrega toda la funcionalidad necesaria para obtener la información temporal. Cómo el algoritmo de clustering a utilizar depende de la aplicación que se le quiera dar, este método permite utilizar cualquier otro algoritmo convencional, y poder asimismo obtener información relevante. Los resultados que se obtuvieron en la experimentación analizando datos del INDEC son muy útiles. Se pudo hacer un análisis exhaustivo de los hogares y de los miembros de los hogares, ver distintas estadísticas de los atributos, ver la evolución en el tiempo de esas variables, y todo eso con un mínimo esfuerzo y tiempo. La forma gráfica de ver los resultados también es importante, ya que es más fácil encontrar información: patrones de comportamiento, evolución, etc. Analizando los resultados numéricos también se podría llegar a estas conclusiones pero sería mucho más complicado. El análisis de performance también fue positivo, ya que se hicieron pruebas con mucha cantidad de registros, y los tiempos siguieron siendo muy satisfactorios.

6.2 Trabajo Futuro
La propuesta que se hace en este trabajo permite seguir investigando sobre el tema. En particular hay dos puntos fundamentales en los cuales enfocarse: a) Adaptación del algoritmo para clustering de grandes bases de datos temporales.

- 83 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Realizar el clustering de bases de datos muy grandes (millones de registros) ha emergido cómo una desafiante investigación. Ya existen algunos algoritmos que se han enfocado en el tema. Los procesos de clustering necesitan hacer múltiples recorridos sobre los datos para alcanzar convergencia y como en el caso de grandes bases de datos no se pueden tener todos los datos a la vez en memoria, se hace necesario hacer más lecturas del disco, lo cual es inmensamente costoso a nivel tiempo. El objetivo, entonces, es cómo acceder a los datos, sin que eso ocupe demasiado tiempo. Algunos métodos se basan en identificar regiones de datos que sean comprensibles y que se puedan mantener en memoria, y otras que pueden ser descartadas; otros utilizan índices temporales, pero todos se enfocan en el manejo más eficiente de memoria. El plan en nuestro caso, sería investigar qué procedimientos serían útiles tanto para adaptar el algoritmo interno (k-d-Median en este caso) tanto como para adaptar el proceso temporal.

b) Desarrollo de herramientas de visualización que faciliten el análisis de los resultados obtenidos. • En los últimos tiempos muchos paquetes de software han sido creados para facilitar la tarea de visualización de componentes gráficos, desde síntesis de sonido, estadísticas, investigaciones médicas, o cualquier otra aplicación que necesite mostrar resultados de una forma más intuitiva y amigable. La mayoría de estos paquetes hacen extensivo el uso de metáforas gráficas, abstracción de objetos y utilización de colores reduciendo la cantidad de elementos a mostrar, simplificando el análisis y brindando un detalle más exhaustivo de información. Sería útil aplicar estos conceptos para la visualización de los resultados del Clustering Temporal. Como los resultados que se muestran en el Clustering Temporal evolucionan en el tiempo, otro concepto útil para utilizar sería el de Series Temporales. Una serie temporal permite realizar análisis de una o muchas variables a la vez, se puede explorar un modelo estacionario o no estacionario, se pueden realizar estimaciones y predecir valores futuros.

- 84 -

.. 2584-2589). and Cybernetics (SMC'98) (pp. Man. Spatial and Spatio-Temporal Data Mining. India (ICDE 2003) [4] Estivill-Castro. J. & Argo. Data Mining and Knowledge Discover.. M. V. Classification of Behavior using Unsupervised Temporal Neural Networks. San Diego. Año 2001. A Fast and Robust General Purpose Clustering Algorithm. 303-360. [6] Estivill-Castro. pp 424-434. EIS-98. [10] Estivill-Castro. 216-242. 1199-1206.85 - . 2007. V. Computational Geometry Provides Techniques for Approximately Solving the p-Median Problem. February 11 . V. Año 1999. P.pp. USA. Vol.María Daniela Navas Padrón: 75. Pacific Rim International Conference on Artificial Intelligence. [2] Bittner. K.. Convex Group Clustering of Large Geo-referenced Data Sets. Bangalore. Spain. TSDM2000. pp 317-323. Cardiac image segmentation using spatio-temporal clustering. Printed Edition. [8] Estivill-Castro. V. Vol. Año 2001. & Murray. 9th ACM International Symposium on Advances in Geographic Information Systems (ACM-GIS 2001). Alpaydin. Tenerife. Lecture Notes in Artificial Intelligence. V. Springer-Verlag. 1. & Murray. T. A. (editor). & Houle. Techniques of Cluster Algorithms in Data Mining. USA November 9-10. In Proceedings of International Workshop on Temporal. The University of British Columbia.. G. 19th International Conference on Data Engineering. In Proceedings of SPIE Medical Imaging. A. & Yang. . & Zaniolo. Pacific Rim International Conference on Artificial Intelligence. S.. Algorithmica. France. In Proceedings of the IEEE International Conference on Systems. Vancouver. Fast Spatial Clustering with Different Metrics and in the Presence of Obstacles. [11] Galic. 30. V. 5-8 Marzo 2003. GA. Año 2002. & Lee.. Año 2001. 2001. pp 142-147. pp 208-218. S. [3] Chen. V. C. 1998. Robust Distance-Based Clustering with Application to Spatial Data Mining. C. Lyon. [9] Estivill-Castro. Hybrid Optimization for Clustering in Data Mining. A. E. Rough sets in spatio-temporal data mining. Spatial Clustering for Data Mining with Genetic Algorithms. The Pacifc Institute for the Mathematical Sciences. 5 Enero 2001. Canada. Año 2001. [5] Estivill-Castro. Año 2000..13. Proceedings of the International ICSC Symposium on Engineering of Intelligent Systems.626 Un modelo de Clustering Temporal Octubre 2004 Bibliografía [1] Adair. [7] Estivill-Castro. Walid G. & Kong. Año 2000. [12] Grabmeier. 6. J. Design and Implementation of a Temporal Extension of SQL. Aref (editor) ACM-Press. Año 1998. Canada. Atlanta. & Rudolph. I. & Loncaric.

S. Junio 2002.S. & Snodgrass. Eds. [22] Navas. R. Morgan Kaufmann Publishers. v. [27] Povinelli. CA. San Francisco. Temporal Pattern Identification of Time Series Data using Pattern Wavelets and Genetic Algorithms. C. pp. Miller and J. NY: Taylor and Francis. M.S.86 - . [16] Ian. & Ungar. Santiago.F. 513-547. Proceedings de X Congreso Argentino de Ciencias de la Computación (CACIC). Octubre 1994. & Sivasankaran. Unnikrishnan. & Soo. & Witten. T. PhD Thesis. Clustering and Identifying Temporal Trends in Document Databases. Han (eds.S. & Cliffor. C. Año 2002. pp. [14] Han.D. & Snodgrass. J. Octubre 2004. H. Año 1994.. In Proceedings of the 2nd International Conference on Knowledge Discovery and Data Mining. M. Año 1998. & Frank. Distances for Spatio-Temporal Clustering. SIGMOD Record. Clustering methods for spatio-temporal data. 1. & Han. [25] Popescul.T. ACM. C.. 311-352. & Fontaine. September 12--15. No. [18] Jensen. pp 144-155. Pattern Discovery in Temporal Databases: A Temporal Logic Approach. J. 2000.7. Research Issues on Data Mining and Knowledge Discovery. Vol.. Año 2000.K. I. K. S.21... SIGKDD Temporal Data Mining Workshop.T. Año 2001. A.María Daniela Navas Padrón: 75. J. SIGMOD Record. [23] Ng. & Feng. C. 25.. 173.3. & Snodgrass. R. Information Systems. Artificial Neural Networks in Engineering. M. Integrating Temporal. Chile proceedings. pp. B. R. Unifying Temporal Data Models. & Flake. K. Un modelo de Clustering Temporal. K. Yet Another Bibliography of Temporal. & Chen. X. Septiembre 1992. M. [20] Nanni. & Tuzhilin. Vol. A Fast Clustering Algorithm to Cluster Very Large Categorical Data Sets in Data Mining. & Kamber. [21] Nanni. 20th International Conference on Very Large Data Bases. M. An extensible Spatial-Temporal Model for Semantic Video Segmentation. & Xiong. & Ale. R. No. X. J. J. pp. Spatial Clustering Methods in Data Mining: A Survey. [28] Ramamritham. A Glossary of Temporal Databases Concepts.. [29] Roddick. R. Real-Time and Active Databases. Università di Pisa.). Proc. & Lee. 8-12. 167-175. & Lawrence. Dipartimento di Informatica. & Feng. Agosto 1996. Semantics of Time-Varying Information. Marzo 1996. M. A. In Proceedings of the IEEE Advances in Digital Libraries 2000 (ADL 2000). 4. J. Morgan Kaufmann.T. Vol.. & Stankovic. G. & Tung. .. 1994. Proceedings. R. Spatial and Spatio-Temporal Data Mining Research. R. Año 1996. & Gadia. P. Information Systems. & Hornsby. E. L. Geographic Data Mining and Knowledge Discovery. [19] Jensen. R.. Data Mining of Nonstationary Time Series Using Multiple Temporal Patterns.D..M. Data Mining: Practical machine learning tools with Java implementations. Año 2001. & Spiliopoulou. First International Forum on Multimedia and Image Processing. Proceedings.. A. H. Mayo 1998. & Towsley. pp 511-516. J. J. R. Anchorage. [26] Povinelli. Proceedings of Sistemi Evoluti per Basi di Dati (SEBD'02). pp 691696. Año 1997. D. L. J. & Segev.Efficient and Effective Clustering Methods for Spatial Data Mining. Mayo 22-24. Z.626 Un modelo de Clustering Temporal Octubre 2004 [13] Hammoud. and Uthurusamy. 21. San Francisco. No. [15] Huang. [17] Jensen. [24] Padmanabhan. D. A.19 n. . 2000. Alaska. Año 1999. Artificial Neural Networks in Engineering. M.

& Stankovic. M. Kluwer International. Paradigms For Spatial and Spatio-Temporal Data Mining. pp. Geographic Data Mining and Knowledge Discovery. Son. & Ramamritham. [31] Xiong. Año 1997. chapter 11.. Han (eds). & Towsley.-J. B.G. J.H. J. R.María Daniela Navas Padrón: 75. K. 2001. H. London: Taylor & Francis. Real-Time Systems: Issues and Applications. & Sivasankaran. Scheduling Access to Temporal Data in Real-Time Databases. 167--191. editors. Bestavros. Lin.626 Un modelo de Clustering Temporal Octubre 2004 [30] Roddick. K. . In A. & Lees.F. D.87 - . Miller and J. and S.

626 Un modelo de Clustering Temporal Octubre 2004 .88 - .María Daniela Navas Padrón: 75.

se puede apreciar con más claridad cuál es la funcionalidad básica de cada caso. es la persona encargada de realizar el proceso de data mining.1 Casos de Uso Para interpretar cuál es el objetivo de nuestra aplicación.1 se observa un diagrama de casos de uso.1 .89 - . El usuario. En el detalle de los casos de uso. “Procesar Clustering Temporal” y “Analizar Resultados”. Las acciones que realiza son “Preparar Datos”. Este diagrama indica las interacciones básicas entre el usuario y el sistema.626 Un modelo de Clustering Temporal Octubre 2004 Apéndices A1 Diseño del Código A1. Figura A1. en nuestro caso.María Daniela Navas Padrón: 75. en la Figura A1.

7) Recorrer el conjunto de registros. el archivo debe poseer: • Un atributo que indique Fecha de Inicio de validez del registro. * Si existe más de un registro por Id y por Intervalo. Acciones del actor 1) Cargar un archivo válido al sistema 2) Especificar parámetros: crono.2 Detalle de Casos de Uso Caso de Uso: Preparar Datos Breve explicación: Toma los datos de una base de datos temporal. 6) Determinar los rangos de fechas que componen cada intervalo. y asignarle dicho intervalo. 5) Determinar el tamaño de cada intervalo dividiendo la diferencia anterior por la cantidad de unidades temporales deseadas. .626 Un modelo de Clustering Temporal Octubre 2004 A1. pero en lugar de los atributos Fecha Inicio y Fecha Fin.90 - . no hay dato para un Id. especificados en un formato determinado.María Daniela Navas Padrón: 75. utilizar moda) * Si en un determinado Intervalo. de unidades temporales 3) Iniciar Filtrado Acciones del Sistema 4) Determinar la diferencia entre la primera fecha de inicio y la última fecha de fin. si es categórico. 10) Guardar el Nuevo archivo. Por ejemplo “2004-12-01 21:35:00” • Un atributo que indique Fecha de Fin de validez del registro. Por ejemplo “2004-1205 21:35:00” • Un atributo que sea un ID único. la misma debe tener el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. incluir la Unidad Temporal. realizar promedio. cada registro con su ID único igual en cada UT. PostCondiones: Archivo arff con la siguiente estructura: • Unidad temporal • ID • Atributos explícitos Este archivo tiene la misma cantidad de registros para cada Unidad Temporal (UT). y los asigna a Unidades Temporales según sus rangos de validez. combinarlos en un solo registro (si el atributo es numérico. crear un registro “vacío”. cant. y cada UT ordenada alfabéticamente por ID. que identifique al registro (puede haber mas de un registro para el mismo ID) • Uno o más atributos (numéricos o categóricos) que se compararán para realizar el clustering. 9) Devolver el archivo de entrada. 8) Ordenar los registros por Id y por Unidad Temporal (intervalo). Precondiciones: • El archivo de entrada debe cumplir con el formato de los archivos arff (Ver Detalle en Documentación) • Además. la misma debe tener el formato “yyyy-mm-dd hh:mm:ss” o “yyyy/mm/dd hh:mm:ss”. verificar dentro de que intervalo es válido (comparando Fecha de Inicio y de Fin con los rangos del intervalo).

Precondiciones: • El archivo de entrada debe cumplir con el formato de los archivos arff (Ver Detalle en Documentación) • Además. PostCondiones: Archivo . 11) Mostrar en pantalla la distribución de centroides. 10) Armar archivo de salida con información sobre cada registro.626 Un modelo de Clustering Temporal Octubre 2004 Caso de Uso: Procesar Clustering Temporal Breve explicación: Toma los datos preprocesados y los agrupa según similitudes en sus atributos.María Daniela Navas Padrón: 75. para cada UT. Acciones del actor 1) Cargar un archivo válido al sistema 2) Especificar parámetros: Cant.csv (comma separated values) con la siguiente estructura: • Detalle de los atributos explícitos de cada registro. 9) Calcular cuantos individuos pasaron de un cluster a otro y determinar el orden de los clusters en cada tiempo. • Número de cluster y UT a los que pertenece ese registro • Flag que indica si ese registro es un centroide o no (y en caso de qué sea de qué cluster). 5) Elegir al azar tantos centroides como clusters se deseen. En cada UT debe ser el mismo • Uno o más atributos (numéricos o categóricos) que se compararán para realizar el clustering. el archivo debe poseer: • Un atributo numérico que indique la Unidad Temporal (UT) • Un atributo que sea un ID único. 6) Dividir los individuos según método k-d-Median (Ver Documentación) 7) Recalcular los centroides de los nuevos clusters 8) Repetir pasos 6 al 8 hasta que no haya más cambios y los clusters sean definitivos. de clusters 3) Ejecutar proceso de clustering Acciones del Sistema 4) Transformar los atributos nominales en numéricos utilizando el método de la Documentación. que identifique al registro. .91 - .

* Si tiene 2 atributos. Por default están todas deshabilitadas. de qué cluster) Acciones del actor 1) Cargar archivo de resultados *. * Gráficos 2 D Tiempo: distribución de un mismo cluster a través de los distintos tiempos. • Número de cluster y UT a los que pertenece ese registro • Flag que indica si ese registro es un centroide o no(y en caso de qué sea. habilitar Gráficos 2D y Gráficos 2 D Tiempo * Si tiene 3 atributos.María Daniela Navas Padrón: 75. * Gráficos 3 D: distribución de las 3 variables en el hiperplano.626 Un modelo de Clustering Temporal Octubre 2004 Caso de Uso: Analizar Resultados Breve explicación: Toma el archivo de salida del proceso de clustering y brinda diferentes gráficos para analizar los resultados obtenidos. * Estadísticas de Individuos: Gráfico de barras que indica cuántos individuos pasaron entre un cluster y otro al cambiar de tiempo. PostCondiones: . Estadísticas de Individuos e Individuos Perdidos habilitarlas siempre. * Análisis por atributo: trayectoria que sigue el centroide de cada cluster a través de los distintos tiempos. * Individuos perdidos: Gráfico de barras que indica cuántos individuos no tienen información en un determinado tiempo.92 - . diferenciando los distintos clusters. 3) Seleccionar alguna de las opciones disponibles. Precondiciones: • Archivo . diferenciando los distintos clusters. * Gráficos 3 D Tiempo: distribución de un mismo cluster a través de los distintos tiempos.csv (comma separated values) con la siguiente estructura: • Detalle de los atributos explícitos de cada registro. 4) Mostrar en pantalla el gráfico correspondiente: * Gráficos 2 D: distribución de las 2 variables en el plano. habilitar Gráficos 3D y Gráficos 3 D Tiempo * Las opciones: Análisis por Atributo.csv Acciones del Sistema 2) Leer información del archivo y configurar opciones del programa.

Asociaciones y Visualización. se detallan algunos atributos y métodos.2 y A1. según distintos criterios: sacar o agregar atributos. Por ejemplo. esto es que una clase hija hereda el funcionamiento de su clase padre. En cada clase. De la clase “Panel de Preproceso” se desprende la clase Filtro. que es la madre de todas las clases que realizan un proceso de clustering.María Daniela Navas Padrón: 75. y tiene una estructura de clases. De la clase “Panel de Clustering” se desprende la clase Clusterer. Las flechas indican herencia. La función de un filtro es transformar las instancias del juego de datos. La clase principal se denomina Explorador (Explorer). que se agrupan en paquetes. modificar valores. Clustering. por ejemplo K-Means. etc. Como éste es un programa que ya está en funcionamiento. que reemplaza los valores desconocidos de un atributo por un valor válido. que es la clase genérica de la cuál heredan distintos filtros específicos. para dar una idea de la función de la misma dentro del sistema.3 se muestran las clases más representativas que pertenecen a la parte de Weka que nos interesa analizar.3 Estructura de Clases La implementación del modelo propuesto consistió en agregar el algoritmo de Clustering Temporal al sistema Weka. hubo que respetar la arquitectura del mismo. Weka está programado en Java. y es la que maneja las clases que representan a cada una de las solapas del programa: Preproceso.93 - . uno de los filtros más usados es AtributoPerdido (FilterMissingValues). Clasificación. de acuerdo a ciertas reglas. En el gráfico se puede ver cómo las clases “Panel de Preproceso” (PreprocessPanel). En las Figuras A1. y a su vez le puede agregar nuevas funcionalidades. “Panel de Clasificación” (ClasifierPanel) y “Panel de Clustering” (ClustererPanel) son hijas de la clase Explorador. .626 Un modelo de Clustering Temporal Octubre 2004 A1.

2 Diagrama de Clases .626 Un modelo de Clustering Temporal Octubre 2004 Figura A1.María Daniela Navas Padrón: 75.

626 Un modelo de Clustering Temporal Octubre 2004 Figura A1.95 - .María Daniela Navas Padrón: 75.3 Continuación Diagrama de Clases .

4 y A1. AtributoNumérico: Este filtro no se aplica por sí solo. Centroide_K_D_Median(): esté método es muy particular ya que es la implementación del algoritmo k-d-Median.626 Un modelo de Clustering Temporal Octubre 2004 A1. que heredan de la clase Filtro. Los métodos más representativos son EncontrarIntervalos(). habría que cambiar este método. Las mismas son: CrearUnidadTemporal y AtributoNumérico.4 Nuevas Clases En las Figuras A1. y Temporal k-d-Median que hereda de la clase Clusterer. ArmarCombinacion(): se utiliza luego de procesado el clustering. pero con color se agregaron las clases implementadas para realizar el proceso de Clustering Temporal. chequea si es necesario combinarlas o crear instancias vacías.5 se observa el mismo diagrama de clases. Si se desea cambiar este algoritmo base. que divide el intervalo de tiempo en subintervalos según los parámetros establecidos y MergeInstances() que luego que a cada instancia se le asigna la Unidad Temporal correspondiente. Los métodos más representativos son: buildClusterer() es el que divide el conjunto de todas las instancias en sus respectivos clusters. que justamente realiza esta transformación.María Daniela Navas Padrón: 75. Se le pasa como parámetro todos los individuos de un cluster. para encontrar la relación entre los clusters de los distintos tiempos. Desde este método se llama a otros que también son importantes: distance() : calcula la distancia Euclídea entre 2 puntos. El método más representativo es ExpansionAtributos(). .96 - . Su función es transformar los atributos nominales en numéricos para poder procesarlos con el método k-d-median. y devuelve el centroide. Temporal k-d-Median: Realiza el proceso de Clustering Temporal. A continuación se indican algunas peculiaridades de cada clase: CrearUnidadTemporal: Formatea los datos de entrada para poder procesarlos con el Clustering Temporal. sino que es llamado desde el proceso de Clustering Temporal.

97 - .626 Un modelo de Clustering Temporal Octubre 2004 Figura A1.4 Diagrama de Clases – Nuevos Filtros .María Daniela Navas Padrón: 75.

98 - .626 Un modelo de Clustering Temporal Octubre 2004 Figura A1.María Daniela Navas Padrón: 75.5 Diagrama de Clases – Nuevo Método de Clustering .

675 Mass Ave. MA 02139. either version 2 of the License..core.0 $ */ public class CreateTemporalUnits extends Filter implements UnsupervisedFilter. USA. import java.io.attribute. This program is distributed in the hope that it will be useful. //Detalle de los m_Chronon: . /** * Este filtro transforma las fechas de inicio y fin en una unidad temporal.ar) * @version $Revision: 1.filters. //Acá se guardan los cortes de los intervalos long [][] m_Intervalos.*. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. or (at your option) any later version. import java.*.*.99 - . import java.com. write to the Free Software Foundation.1 WEKA CreateTemporalUnits. /* * CreateTemporalUnits.java * Octubre 2004 María Daniela Navas * */ package weka.María Daniela Navas Padrón: 75. but WITHOUT ANY WARRANTY. you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.<p> * * * @author María Daniela Navas (mnavas@mnavas. Cambridge.*. Inc.626 Un modelo de Clustering Temporal Octubre 2004 A2 Código Fuente A2.lang. OptionHandler { // Números de intervalos a dividir protected int m_NumIntervalos=12.util. import weka. StreamableFilter.filters. You should have received a copy of the GNU General Public License along with this program. if not.*. See the GNU General Public License for more details. protected int m_Chronon=3.class /* * * * * * * * * * * * * * */ This program is free software. import weka.unsupervised.

"-A <col>")). "-T <num>")).626 Un modelo de Clustering Temporal Octubre 2004 // // // // // // 1: Año 2: Mes 3: Día 4: Hora 5.addElement(new Option( "\tIndique cuál es la posición del Atributo Identificador\n". 1.4(Hora). "I". "-I <col>")). * * -I Indique cuál es la posición de la Fecha Inicial * -F Indique cuál es la posición de la Fecha Final * -A Indique cuál es la posición del Atributo Identificador .addElement(new Option( "\tIndique cuál es la posición de la Fecha Inicial\n". protected Instances m_Instances.2(Mes). newVector.2(Mes). newVector.6(Segundo).4(Hora). "A". "F".100 - . 1. protected int m_PosId=2.elements().María Daniela Navas Padrón: 75. "-C <num>")). newVector.addElement(new Option( "\tIndique cuál es la posición de la Fecha Final\n".5(Minuto). } /** * Parsea los valores de los parametros: <p> * * -T Especifique el número de intervalos en que se dividirá el conjunto de datos".6(Segundo). * -C Indique cuál es la mínima unidad de tiempo (chronon) * Valores posibles: 1(Año).addElement(new Option( "\tEspecifique el número de intervalos en que se dividirá el conjunto de datos". return newVector.5(Minuto). "-F <col>")). protected int m_PosFechaFin=1. 1. 1. //se usa porque hay que hacer varios procesos sobre el conjunto de datos /** * Devuelve una enumeración de todos los parametros posibles * */ public Enumeration listOptions() { Vector newVector = new Vector(5). newVector.". 1. "C".addElement(new Option( "\tIndique cuál es la mínima unidad de tiempo (chronon)\n"+ "\tValores posibles: 1(Año). Minuto 6: Segundo protected int m_PosFechaIni=0. "T".3(Dia).3(Dia). newVector.

options). } //Setea la posicion de fecha inicial. options). int current = 0. } //Setea la posicion de fecha inicial.length() != 0) { setPosFechaFin(Integer.parseInt(id)-1).length() != 0) { setNumIntervalos(Integer.parseInt(Intervalos)). options).length() != 0) { setPosId(Integer. .getOption('I'.parseInt(fecha)-1). } else { setPosFechaIni(0). } //Setea la posicion de fecha inicial. } else { setNumIntervalos(10). } else { setPosFechaFin(1). } //Setea el chronon. options). } if (getInputFormat() != null) { setInputFormat(getInputFormat()).parseInt(fecha)-1). options[current++] = "-T " + getNumIntervalos().getOption('T'. if (chronon.length() != 0) { setPosFechaIni(Integer. por default 2 String id = Utils.María Daniela Navas Padrón: 75. por default 1 fecha = Utils.length() != 0) { setChronon(Integer. if (fecha. por default 3 (Día) String chronon = Utils. if (Intervalos. if (id.101 - .626 Un modelo de Clustering Temporal Octubre 2004 * */ public void setOptions(String[] options) throws Exception { //Setea el número de intervalos. } else { setChronon(3). por default 0 String fecha = Utils.getOption('F'.parseInt(Intervalos)).getOption('A'.getOption('C'. } else { setPosId(2). if (fecha. options). por default 12 String Intervalos = Utils. } } /** * Devuelve el seteo de los parametros * */ public String [] getOptions() { String [] options = new String [5].

0). int borrarId=0. while (current < options.María Daniela Navas Padrón: 75.length) { options[current++] = "". //Los dos atributos de fecha se transformarán en 1 solo numerico super. . if (borrarId > borrarF){ borrarId = borrarId -1. //Antes de borrar copio el atributo del ID Attribute nuevoAtributoId = instanceInfo. //corro un valor para la izquierda. si es menor no hago nada } outputFormat. para la UT Attribute nuevoAtributoT = new Attribute("Temp"). } /** * Setea el formato de las instancias de entrada * */ public boolean setInputFormat(Instances instanceInfo) throws Exception { int borrarF=0.insertAttributeAt(nuevoAtributoId.insertAttributeAt(nuevoAtributoT. if (m_PosFechaFin > m_PosFechaIni){ borrarF = m_PosFechaFin -1.102 - . //corro un valor para la izquierda.attribute(m_PosId). //Borro los atributos que indicaban fecha //Al borrar CADA atributo.deleteAttributeAt(m_PosFechaIni). } return options. //Creo un nuevo Atributo en la posición 0.626 Un modelo de Clustering Temporal Octubre 2004 options[current++] = "-C " + getChronon(). //corro un valor para la izquierda.deleteAttributeAt(borrarF). //Inserto el nuevo atributo numérico outputFormat. 0). se reordena la estructura!!! por eso los valores no son los mismos outputFormat. //Inserto el nuevo atributo numérico outputFormat. si es menor no hago nada } outputFormat.1). options[current++] = "-I " + getPosFechaIni(). // Se crea el buffer de salida Instances outputFormat = new Instances(instanceInfo. options[current++] = "-A " + getPosId(). si es menor no hago nada } if (m_PosId > m_PosFechaIni){ borrarId = m_PosId -1.setInputFormat(instanceInfo). options[current++] = "-F " + getPosFechaFin().deleteAttributeAt(borrarId).

return false. m_NewBatch = true. } bufferInput(instance).626 Un modelo de Clustering Temporal Octubre 2004 //Ahora creo los invervalos EncontrarIntervalos(instanceInfo). i++) { convertInstance(getInputFormat(). ahora las ordeno y junto si es necesario MergeInstances(m_Instances). } /** * Indica si el proceso batch ha terminado de filtrar * * @return true si hay instancias pendientes de filtrar */ public boolean batchFinished() { if (getInputFormat() == null) { throw new IllegalStateException("No input instance format defined"). } if (m_NewBatch) { resetQueue(). i < getInputFormat().0). } // Convierte las instancias de entrada pendientes for(int i = 0. } /** * Toma una instancia para filtrarla. } /** * Devuelve un string describiendo el filtro. m_NewBatch = false.numInstances().María Daniela Navas Padrón: 75. //Inicializo m_Instances m_Instances = new Instances(outputFormat. return true. * */ public String globalInfo() { .103 - . } //Ya tengo las unidades temporales. return (numPendingOutput() != 0). setOutputFormat(outputFormat).instance(i)). * * @return true si la instancia filtrada puede ser cargada en output() */ public boolean input(Instance instance) { if (getInputFormat() == null) { throw new IllegalStateException("No input instance format defined").

} /** * Setea la propiedad * */ public void setNumIntervalos(int numIntervalos) { m_NumIntervalos = numIntervalos.104 - ." . } /** * Setea la propiedad * */ public void setChronon(int Chronon) { m_Chronon = Chronon.". } /** * Devuelve la propiedad * */ public int getNumIntervalos() { return m_NumIntervalos.María Daniela Navas Padrón: 75. } /** * Devuelve el tip text para esta propiedad * */ public String NumIntervalosTipText() { return "Número de intervalos de tiempo a analizar. } /** * Devuelve el tip text para esta propiedad * */ public String ChrononTipText() { return "Mínima unidad de tiempo a tener en cuenta." . } /** * Devuelve la propiedad * */ public int getChronon() { return m_Chronon.626 Un modelo de Clustering Temporal Octubre 2004 return "Filtro que transforma los atributos de fechas en valores discretos. } /** .

" . } /** * Devuelve la propiedad */ public int getPosFechaFin() { return m_PosFechaFin.105 - . } /** * Devuelve la propiedad * */ public int getPosFechaIni() { return m_PosFechaIni." .María Daniela Navas Padrón: 75." . } /** * Devuelve la propiedad . del atributo identificatorio del registro. de la fecha de validez inicial del registro. } /** * Devuelve el tip text para esta propiedad * */ public String PosFechaFinTipText() { return "Posición dentro del rango de atributos.626 Un modelo de Clustering Temporal Octubre 2004 * Devuelve el tip text para esta propiedad * */ public String PosFechaIniTipText() { return "Posición dentro del rango de atributos. } /** * Setea la propiedad */ public void setPosFechaIni(int PosFechaIni) { m_PosFechaIni = PosFechaIni. } /** * Setea la propiedad */ public void setPosFechaFin(int PosFechaFin) { m_PosFechaFin = PosFechaFin. } /** * Devuelve el tip text para esta propiedad */ public String PosIdTipText() { return "Posición dentro del rango de atributos. de la fecha de validez final del registro.

UltimaFechaFin = (long) instances.106 - .numInstances()1). int Mes. Date Desde = new Date().value(m_PosFechaFin).txt"). el ultimo registro tiene la ultima fecha de inicio y fin instances. PrimerFechaInicio = (long) instances.626 Un modelo de Clustering Temporal Octubre 2004 * */ public int getPosId() { return m_PosId. Date Hasta = new Date().sort(m_PosFechaIni). long HastaI = 0.000 milisegundos .000 milisegundo // 1 minuto = 60. el primer registro tiene la primer fecha de inicio y fin instances. //Si ordeno por fecha de inicio. //Calculo el tamaño del intervalo double TamanioIntervalo = (UltimaFechaFin . //Armo el vector de unidades temporales y lo imprimo en un txt OutputStream Salida = new FileOutputStream("IntervalosDeTiempo.value(m_PosFechaIni). int Minuto.María Daniela Navas Padrón: 75. long DesdeI = PrimerFechaInicio. int Hora. //Si ordeno por fecha de fin. } /** * Encuentra los puntos de corte para la fecha inicio y fecha fin * */ protected void EncontrarIntervalos(Instances instances) throws Exception { //Inicializo las variables m_Intervalos = new long [m_NumIntervalos][2]. if ((m_NumIntervalos > 0) && (TamanioIntervalo > 0)) { for (int i=0. //esto guarda los cortes de los intervalos long PrimerFechaInicio.sort(m_PosFechaFin). int Segundo. } /** * Setea la propiedad */ public void setPosId(int PosId) { m_PosId = PosId.instance(instances.PrimerFechaInicio) / m_NumIntervalos. int Dia. i < m_NumIntervalos. String linea = null. int Anio. i++){ switch (m_Chronon){ // 1 segundo = 1.instance(0). long UltimaFechaFin.

Mes.Mes.getTime().536.1. HastaI = Hasta.000. .1). } HastaI = (long) (DesdeI + TamanioIntervalo) .626 Un modelo de Clustering Temporal Octubre 2004 // 1 hora = 3.1).000 mili //1 año = 31.getYear(). } HastaI = (long) (DesdeI + TamanioIntervalo) .000. Anio = Hasta.getTime().María Daniela Navas Padrón: 75. case 2: //mes //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + (long) 2. Anio = Hasta. //Recorto el HastaI Hasta =new Date(HastaI). Anio = Desde.1).592. Hasta = new Date(Anio. Mes = Desde.600.000 milisegundos //1 mes = 2.000 mili //1 día = 86.1. Mes = Hasta. Hasta =new Date(HastaI). } HastaI = (long) (DesdeI + TamanioIntervalo) .1536E10. case 3: //dia //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + 86400000. //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde.getYear(). //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde.getTime().getMonth(). //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI).getYear(). break.107 - . Desde = new Date(Anio.1).getTime(). Desde = new Date(Anio. Hasta = new Date(Anio.getYear().400. Anio = Desde. //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI). HastaI = Hasta.000 case 1: //año //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + (long) 3.getMonth().6784E9. break.

break. Desde = new Date(Anio.getMonth(). Anio = Hasta. } HastaI = (long) (DesdeI + TamanioIntervalo) .getTime(). } HastaI = (long) (DesdeI + TamanioIntervalo) .getDate(). //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde. HastaI = Hasta.getYear(). Hasta =new Date(HastaI).Mes. Hasta =new Date(HastaI).Mes.108 - . Dia = Hasta.getDate().getMonth().Dia).Hora. Dia = Hasta.Dia. Anio = Desde.1). Hora = Hasta.getHours(). Hasta = new Date(Anio.1). case 5: //minuto //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + 60000. Mes = Desde. Hora = Desde.getTime(). Desde = new Date(Anio. Hasta = new Date(Anio.Dia.getYear(). Dia = Desde.getDate().getDate(). Anio = Hasta.Hora.getYear().626 Un modelo de Clustering Temporal Octubre 2004 //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI).Dia). case 4: //hora //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + 3600000. //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI). //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde.Mes.getHours().getTime().Mes. Dia = Desde.María Daniela Navas Padrón: 75. . Mes = Desde. Anio = Desde. break. HastaI = Hasta.getTime().getMonth().getYear(). //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI). Mes = Hasta. Mes = Hasta.getMonth().

getSeconds(). Desde = new Date(Anio. HastaI = Hasta. //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde.109 - . HastaI = Hasta.getMinutes(). Hasta = new Date(Anio.Mes.getDate(). Hasta =new Date(HastaI). Hora = Hasta.getHours().getTime(). break. Hasta = new Date(Anio.getHours().Hora. break. Hora = Desde.Segundo). case 6: //segundo //Calculo el valor del intervalo if (i!=0) { //en el primer intervalo el desde es distinto DesdeI = HastaI + 1000. Anio = Hasta. Anio = Hasta.getSeconds().getTime().Minuto).getMinutes().getYear(). Minuto = Hasta.getYear(). Segundo = Desde.Dia.Mes.getHours(). Mes = Hasta. Hora = Desde.getDate().Minuto).getYear(). Minuto = Desde. }//switch //Archivo linea = "\n\nIntervalo de tiempo perteneciente a la unidad temporal " + (i+1).Dia.getYear(). Hora = Hasta. Hasta =new Date(HastaI).write(linea. Dia = Desde.Segundo).getMonth(). Dia = Desde.Hora.Mes. Dia = Hasta. Segundo = Hasta.Minuto.Dia. //Vuelvo a pasar a long los valores recortados a la unidad correspondiente DesdeI = Desde.getMinutes().Mes. Mes = Desde.getTime(). Minuto = Hasta.Hora. Mes = Hasta.getBytes()).getMonth().getHours().getDate().getMonth().626 Un modelo de Clustering Temporal Octubre 2004 Anio = Desde. Minuto = Desde. Salida.Dia.getDate().Minuto.María Daniela Navas Padrón: 75.getMonth(). } HastaI = (long) (DesdeI + TamanioIntervalo) . Anio = Desde. Dia = Hasta. Mes = Desde.Hora. //Utilizo solo las unidades que corresponden Desde =new Date(DesdeI).getMinutes().getTime(). Desde = new Date(Anio. .

write(linea.getBytes()).value(i).close(). } /** * Convierte una instancia y la agrega al final de la cola de salida */ protected void convertInstance(Instance instance) { //la instancia se puede convertir en tantas instancias como números de intervalos haya double [][] vals = new double [m_NumIntervalos][outputFormatPeek().value(m_PosFechaFin).value(i).110 - . i < getInputFormat(). Salida.toString().getBytes()). }else if (FechaIni < Int0 && FechaFin >= Int0 && FechaFin <= Int1){ vals[t][0]= t. vals[t][0]= -1.numAttributes()]. m_Intervalos[i][1] = HastaI.María Daniela Navas Padrón: 75. long FechaFin. t++){ //para todos los t tiene el mismo ID vals[t][1] = instance. int at=2. }else if (FechaIni < Int0 && FechaFin > Int1){ vals[t][0]= t.numAttributes(). Salida. . linea = " Hasta: " + Hasta. }else if (FechaIni >= Int0 && FechaIni <= Int1 && FechaFin > Int1){ vals[t][0]= t. } }//for t }//if else if (i==m_PosId){ for (t=0. t++){ Int0 = m_Intervalos[t][0].write(linea.626 Un modelo de Clustering Temporal Octubre 2004 //Lo guardo en el vector m_Intervalos[i][0] = DesdeI. linea = "\n Desde: " + Desde. i++) { //En la fecha inicio hago el cálculo y lo asigno al nuevo atributo Temp if (i==m_PosFechaIni){ FechaIni = (long) instance. }//for } Salida. long Int0. Int1 = m_Intervalos[t][1].toString(). FechaFin = (long) instance. long Int1. int i. //inicializo en este valor para saber si se le asigno un tiempo o no if (FechaIni >= Int0 && FechaFin <= Int1){ vals[t][0]= t. t < m_NumIntervalos. long FechaIni. int t. //Me fijo si hay un intervalo en el que esté integramente contenido for (t=0. //a partir de aca van los atributos "normales" // Copia y convierte los atributos for(i = 0. t < m_NumIntervalos.

for (t=0.numInstances(). t < m_NumIntervalos. } copyStringValues(inst. } //Ahora ordeno por el Id. getOutputFormat().instance(i)).add( instances. t++){ if (vals[t][0] != -1){ if (instance instanceof SparseInstance) { inst = new SparseInstance(instance.a.numDistinctValues(0).i.dataset(). Instances [] m_VectorInstancesFinal. vals[t]). for (t=0. }//fin if }//for Instance inst = null. } // Según el atributo 0 de la instancia en cuestión. double [] vals. //La cantidad de unidades temporales es la cantidad de valores distintos que tiene el atributo 0 m_NumTemporalUnits = instances.0). getOutputStringIndex()).111 - .instance(i). m_Instances. t++) { m_VectorInstances[t] = new Instances(instances. for (i = 0. } } }//fin metodo /** * Divido las instancias segun su UT */ protected void MergeInstances(Instances instances) { //Divido las instancias segun su UT Instances [] m_VectorInstances. }//for at++. t++){ //para todos los t tiene el mismo ID vals[t][at] = instance. i < instances. t < m_NumTemporalUnits . vals[t]).weight(). m_VectorInstancesFinal = new Instances [m_NumTemporalUnits]. i++) { pos = (int)instances.value(0).weight(). m_VectorInstances[pos]. getInputStringIndex(). inst.setDataset(getOutputFormat()). agrego el atributo // al vector de instancias en la posición que corresponda int pos. instance.value(i).626 Un modelo de Clustering Temporal Octubre 2004 }//for } else if (i != m_PosFechaFin){ for (t=0. m_VectorInstancesFinal[t] = new Instances(instances. int t.María Daniela Navas Padrón: 75. t < m_NumIntervalos.0).add(inst). int m_NumTemporalUnits. m_VectorInstances = new Instances [m_NumTemporalUnits]. cada posicion temporal . } else { inst = new Instance(instance. false.

626 Un modelo de Clustering Temporal Octubre 2004 for (t=0.value(0) == m_VectorInstances[t]. hago un merge if ((m_VectorInstances[t]. i=0.value(1) == m_VectorInstances[t]. no hago nada. }//if } }//for //Ahora vuelvo a recorrer todos los tiempos //Si coincide el ID con el menor. pierdo una posicion) } }//while }//for t //Ahora agrego intancias VACIAS. t++) { m_VectorInstances[t].numInstances()){ if (m_VectorInstances[t].instance(i). vals[1] = IdMenor. }else {//si el i no existe creo una nueva instancia //Creo una instancia con el mismo Id y Tiempo. for (a=2.Agregados[t]).Agregados[t]).delete(i+1).instance(i . t++) { if ( (i . t++) { if ( (i .Agregados[t]) < m_VectorInstances[t]. int [] Agregados = new int[m_NumTemporalUnits]. boolean converged = false.value(1) < IdMenor ){ IdMenor = m_VectorInstances[t].MAX_VALUE. }else { i++.instance(i).numInstances()){ NuevaInstancia = m_VectorInstances[t]. para que todos los tiempos tengan las //mismas instancias y esten ordenadas //Recorro cada grupo guardando el id mas chico.instance(i+1)).sort(1). pero vacìa vals = new double[m_VectorInstances[t].numAttributes() . creoInstancia = false. while (!converged) { //Recorro la misma instancia en todos los tiempos y guardo el menor valor for (t=0.instance(i+1). t < m_NumTemporalUnits .Agregados[t]) < m_VectorInstances[t].value(1))) { //merge m_VectorInstances[t]. //borro la instancia i +1 m_VectorInstances[t].numAttributes()]. while (i < m_VectorInstances[t]. double IdMenor = Double.María Daniela Navas Padrón: 75. sino inserto una instancia vacia en ese tiempo con ese ID //En ese caso no incremento el i (lo chequeo de nuevo para ver si esta todo ok for (t=0.instance(i+1).Agregados[t]).mergeInstance(m_VectorInstances[t].instance(i . Instance NuevaInstancia.instance(i . boolean creoInstancia = false.instance(i). a++) { vals[2] = 0.112 - . i=0. //Solo incremento la i si no borre nada (al borrar. t < m_NumTemporalUnits . } .value(1).numInstances()-1) { //si las UT son iguales y los ID son iguales. en los tiempos que faltan. vals[0] = t.value(0)) && (m_VectorInstances[t]. t < m_NumTemporalUnits . int instancias_creadas =0. a < m_VectorInstances[t].

add(NuevaInstancia).instance(i)). instancias_creadas =0.value(1) == IdMenor ){ m_VectorInstancesFinal[t]. NuevaInstancia = new Instance(1.numAttributes()]. Agregados[t]++.add(NuevaInstancia). }else { if (!creoInstancia){ //si no habia creado una instancia vacia la creo ahora //Creo una instancia con el mismo Id y Tiempo. a < m_VectorInstances[t].numInstances() -1). i++) { push(m_VectorInstancesFinal[t].113 - . } }//for if (instancias_creadas < m_NumTemporalUnits){ converged = false. t < m_NumTemporalUnits . a++) { NuevaInstancia. quiere decir que llegué al final converged = true. for (a=2. t++) { m_VectorInstancesFinal[t].numInstances().MAX_VALUE.0. }//for a creoInstancia = true. i < m_VectorInstancesFinal[t]. }//else //Ahora comparo si son iguales los valores. for (a=2.setMissing(a). t < m_NumTemporalUnits .María Daniela Navas Padrón: 75. Agregados[t]++. t++) { for (i = 0. vals[0] = t.setMissing(a).vals). }else if (instancias_creadas == m_NumTemporalUnits){ //si cree todas las instancias. i++. }//if m_VectorInstancesFinal[t]. vals[1] = IdMenor. } } }//fin metodo public static void main(String [] argv) { } } .vals). } } }//while //Al final las agrego a la cola con push for (t=0.numAttributes() . //Tengo que borrar las m_NumTemporalUnits ultimas instancias for (t=0.626 Un modelo de Clustering Temporal Octubre 2004 NuevaInstancia = new Instance(1. si acabo de agregar la instancia va a coincidir //asì que la agrego directamente if (NuevaInstancia.numAttributes() . pero vacìa vals = new double[m_VectorInstances[t].delete(m_VectorInstancesFinal[t].0. instancias_creadas ++. a++) { NuevaInstancia. a < m_VectorInstances[t]. }//for a instancias_creadas ++. IdMenor = Double.

*.María Daniela Navas Padrón: 75. if not. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. import weka.00 $ */ public class AtributosNumericos extends Filter implements UnsupervisedFilter. import weka. OptionHandler{ /** Guarda que columnas copiar */ protected Range m_CopyCols = new Range().ar) * @version $Revision: 1. /** * Matriz en donde se manejan las instancias */ . para utilizar con algoritmos que solo permitan atributos numéricos * * No necesita parámetros externos * * @author Maria Daniela Navas (mnavas@mnavas.class /* * * * * * * * * * * * * * */ This program is free software. you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. import java.java * Octubre 2004 Maria Daniela Navas * ****/ package weka.114 - .unsupervised. StreamableFilter. but WITHOUT ANY WARRANTY.util.io.filters. Inc.filters. /** * Contiene los indices de los atributos string de las instancias de entrada */ protected int [] m_InputStringIndex. Cambridge. or (at your option) any later version. either version 2 of the License.core. /** * Guarda los indices de los atributos seleccionados */ protected int [] m_SelectedAttributes.. write to the Free Software Foundation.*. /** * Un filtro de instancias que normaliza los valores y tranforma los atributos * nominales en numéricos. /**** * AtributosNumericos. You should have received a copy of the GNU General Public License along with this program.attribute. import java. See the GNU General Public License for more details. MA 02139. This program is distributed in the hope that it will be useful.626 Un modelo de Clustering Temporal Octubre 2004 AtributosNumericos.*.com.*. 675 Mass Ave. USA.

addElement(new Option( "\tInvierte selección (incluye las columnas no especificadas)". "-V")).addElement(new Option( "\tEspecifica una lista de columnas para incluir en el filtro. private double [] m_Max.626 Un modelo de Clustering Temporal Octubre 2004 protected double [][] MatrizInstancias. //para normalizar los atributos numéricos private double [] m_Min. First y last son validos..index2-index4. if (copyList. if (getInputFormat() != null) { setInputFormat(getInputFormat()).María Daniela Navas Padrón: 75. options).>")).. } /** * Parsea la lista de opciones * * -R index1..<br> * Especifica una lista de columnas para incluir en el filtro. options)).\n" +"\tindices. } setInvertSelection(Utils. } } /** * Devuelve el seteo actual del filtro */ public String [] getOptions() { String [] options = new String [3]..115 - .. newVector. newVector..getOption('R'. return newVector. "-R <indice1.indice2-indice4. (default none)". /** * para indicar la posicion de la matriz instancias */ private int pos=0. "V". 1. "R". First y last son validos * (default none)<p> * * -V<br> * nvierte selección (incluye las columnas no especificadas) * */ public void setOptions(String[] options) throws Exception { String copyList = Utils. . 0.length() != 0) { setAttributeIndices(copyList). /** * Devuelve una enumeracion de los parametros de entrada */ public Enumeration listOptions() { Vector newVector = new Vector(1).elements().getFlag('V'.

int current.length]. for (int i = 0. int [] inStrCopied = new int[m_SelectedAttributes. int CantValores. i < instanceInfo. } return options. options[current++] = getAttributeIndices().numAttributes()].numInstances().María Daniela Navas Padrón: 75.numAttributes()].0). int inStrCopiedLen = 0.numAttributes() .1). } for (int i = 0. m_CopyCols. m_Max = new double [instanceInfo.equals("")) { options[current++] = "-R". int dimensionSeleccionados=0. int dimensionActual=0. int SeleccionadoCorrido =0. i++) { m_Min[i] = m_Max[i] = Double. . double [][] MatrizAuxiliar. } if (!getAttributeIndices().length) { options[current++] = "". //vuelvo a cero la posición pos=0. } //******* Calculo la dimensión que va a tener la nueva matriz. i++) { updateMinMax(instanceInfo. double [][] MatrizExpansion.116 - . m_SelectedAttributes = m_CopyCols.instance(i).numAttributes()). if (getInvertSelection()) { options[current++] = "-V". int at. int [] m_SelectedAttributesCorridos.NaN.getSelection(). int Seleccionado =0.setUpper(instanceInfo. int dimension=0.626 Un modelo de Clustering Temporal Octubre 2004 int current = 0. // En output voy a guardar la salida Instances outputFormat = new Instances(instanceInfo. } /** * Setea el formato de las instancias de entrada * */ public boolean setInputFormat(Instances instanceInfo) throws Exception { super.instanceInfo. } while (current < options. i < instanceInfo.numAttributes().setInputFormat(instanceInfo). //******** NORMALIZACION *********++ //normalizo los atributos numéricos originales m_Min = new double [instanceInfo.

value(current)][k]. } }else{ //si no fue seleccionado dimension = dimension +1. at < instanceInfo. dimensionSeleccionados = dimensionSeleccionados + 1. } }//for i //Va a tener el valor que corresponda en las columnas seleccionadas y 0 en las otras MatrizInstancias = new double [instanceInfo.numDistinctValues(instanceInfo.numInstances()][dimension]. i++){ if (i == m_SelectedAttributes[Seleccionado]){ Seleccionado ++. los valores de reemplazo deben ser missing if (!instanceInfo. k++){ MatrizAuxiliar [j][k] = MatrizExpansion[(int)instanceInfo. }//for k } }//for j . } else{ //si es numerico dimension = dimension + 1.attribute(i)) -1. //lo incremento para que la próxima sea el próximo seleccionado con el que comparo if(instanceInfo.isMissingValue(instanceInfo.attribute(current).attribute(i)) -1.numAttributes(). MatrizExpansion = ExpansionAtributos(CantValores). m_SelectedAttributesCorridos = new int[dimensionSeleccionados]. sino copio directamente for (at= 0 . i< instanceInfo. k < CantValores -1.attribute(i).numDistinctValues(instanceInfo.instance(j).NOMINAL){ //Si es nominal.instance(j). tengo que hacer la operación.NOMINAL){ CantValores = instanceInfo. if (instanceInfo. k < CantValores -1. for (int j=0. at++){ //Si el atributo está seleccionado if (at == m_SelectedAttributes[Seleccionado]){ current = m_SelectedAttributes[Seleccionado].type()==Attribute. sumo la cantidad de valores distintos que tiene dimension = dimension + instanceInfo. //recorro los atributos. //CantValores = cantidad distinta de valores que tiene ese atributo //Creo una matriz del tamaño de CantValores x CantValores -1 MatrizExpansion = new double [CantValores][CantValores-1]. j < instanceInfo.numDistinctValues(instanceInfo. MatrizAuxiliar = new double [instanceInfo. dimensionSeleccionados = dimensionSeleccionados + instanceInfo.type()== Attribute.NaN. }//for k }else{ //si el valor era missing for( int k=0.626 Un modelo de Clustering Temporal Octubre 2004 for (int i= 0 .117 - . Seleccionado=0. j++){ //si el atributo era missing. SeleccionadoCorrido=0.María Daniela Navas Padrón: 75. k++){ MatrizAuxiliar [j][k] = Double.numAttributes().instance(j).numInstances().attribute(current)).numInstances()][CantValores-1].value(current))) { for( int k=0. Seleccionado ++. si es nominal.

insertAttributeAt((Attribute) nuevoAtributo.type()== Attribute.attribute(current). k++){ MatrizInstancias [j][k]= MatrizAuxiliar[j][k . } . i < CantValores -1.attribute(current).instance(j). } }else{ //las instancias quedan tal cual. SeleccionadoCorrido++. //Sumo las dimensiones correspondientes dimensionActual = dimensionActual + 1.dimensionActual]. //Acá inserta el atributo vacío outputFormat. } if(instanceInfo.deleteAttributeAt(dimensionActual).insertAttributeAt(nuevoAtributo.118 - . //Inserto el nuevo atributo numérico outputFormat. es seleccionado -1 porque ya lo incrementé m_SelectedAttributesCorridos[SeleccionadoCorrido] = dimensionActual +i. j < instanceInfo. for (int j=0.name()). j++){ //En lugar de guardar el valor numerico ya lo guardo normalizado MatrizInstancias [j][dimensionActual]= norm(instanceInfo. borro el anterior outputFormat. for (int j =0.attribute(current).1.María Daniela Navas Padrón: 75. //después de insertar los nuevos atributos. j < instanceInfo. } //Sumo las dimensiones correspondientes dimensionActual = dimensionActual + CantValores . }//for k }//for j //ahora se corrió la posición de los seleccionados.value(current).numInstances(). dimensionActual).attribute(current). j ++){ for( int k= dimensionActual.STRING){ inStrCopied[inStrCopiedLen++] = current.type()== Attribute.current). borro el anterior outputFormat.copy(). } if(instanceInfo. SeleccionadoCorrido++. sumo una dimensión más dimensionActual = dimensionActual +1.626 Un modelo de Clustering Temporal Octubre 2004 //Agrego los encabezados de los nuevos atributos for (int i =0. }//for j //Si es numerico el atributo no cambia ya m_SelectedAttributesCorridos [SeleccionadoCorrido]=dimensionActual. //después de insertar los nuevos atributos. i++){ Attribute nuevoAtributo = new Attribute("Atributo Numerico " + i + " de " + instanceInfo.NUMERIC){ Attribute nuevoAtributo = instanceInfo.numInstances().dimensionActual + i).deleteAttributeAt(dimensionActual). k < dimensionActual +CantValores -1.

System.length. } /**** * * Transforma los Atributos Categoricos a numericos con distancia = 1 entre todos los elementos * ****/ private double [][] ExpansionAtributos(int CantValores) { double [][] Matriz = new double[CantValores][CantValores -1]. for (int j = 3. j < i .value(j) > m_Max[j]) { .Matriz[0][0]. } else { if (instance. i++){ for (int j = 1.(Matriz[i][i-2]*Matriz[i][i-2])). } Matriz[i][i-2]=(2*((Matriz[2][1]*Matriz[2][1]) . } } return Matriz. j++){ Matriz [i][j] = Matriz [i-1][j].626 Un modelo de Clustering Temporal Octubre 2004 } //lo dejo por compatibilidad int [] origIndex = getInputStringIndex(). m_Max[j] = instance. Matriz [1][0] = . for (int i = 3.value(j) < m_Min[j]) { m_Min[j] = instance.119 - .isNaN(m_Min[j])) { m_Min[j] = instance. Matriz [0][0] = 0. Matriz[i][i-1]= Math.length). m_SelectedAttributes. if (CantValores > 2){ Matriz[2][1] = Math.María Daniela Navas Padrón: 75. i < CantValores. j++) { if (!instance. j++){ aux = aux + Matriz [j][j-2] * Matriz [j][j-2].value(j).arraycopy(origIndex. System. } /** * Modifica el mínimo y máximo valor de cada atributo */ private void updateMinMax(Instance instance. 0.2. 0. } double aux = 0.5. m_SelectedAttributesCorridos.isMissing(j)) { if (Double. System.j < numAttributes.arraycopy(m_SelectedAttributesCorridos. //reasigno los seleccionados m_SelectedAttributes = new int [dimensionSeleccionados]. m_InputStringIndex = new int [origIndex.sqrt(1 . int numAttributes) { for (int j = 0. 0. setOutputFormat(outputFormat).(Matriz [0][0] * Matriz [0][0])). 0.sqrt((Matriz [i-1][i-2] * Matriz [i-1][i-2]). origIndex.value(j).length).arraycopy(inStrCopied. inStrCopiedLen).length + inStrCopiedLen]. } else { if (instance. origIndex. m_InputStringIndex.value(j). 0.aux)-1)/(2* Matriz[i-1][i-2]). return true. m_InputStringIndex. j < i.

int i) { if (Double. m_InputStringIndex.m_Min[i])) { return 0.weight(). } copyStringValues(inst.value(j). } if (m_NewBatch) { resetQueue(). } } } } } } /** * Normaliza un valor dado * */ private double norm(double x.120 - . return true.626 Un modelo de Clustering Temporal Octubre 2004 m_Max[j] = instance.isNaN(m_Min[i]) || Utils. } . vals[i] = MatrizInstancias[pos][i]. } } /** * Filtra la instancia */ public boolean input(Instance instance) { if (getInputFormat() == null) { throw new IllegalStateException("No input instance format defined").m_Min[i]).numAttributes()].dataset().numAttributes(). } } pos = pos +1. } else { return x / (m_Max[i] . if (instance instanceof SparseInstance) { inst = new SparseInstance(instance. Instance inst = null. getOutputStringIndex()). vals). //Asigno los valores correspondientes de la matriz de instancias for (int i =0. }else{ vals[i] = instance.weight(). inst. double[] vals = new double[outputFormatPeek(). vals). } else { inst = new Instance(instance. i < outputFormatPeek(). getOutputFormat(). false. push(inst).María Daniela Navas Padrón: 75. instance.eq(m_Max[i]. i++){ if (i == m_SelectedAttributes[Seleccionado]){ Seleccionado++. } int Seleccionado = 0.setDataset(getOutputFormat()). m_NewBatch = false.value(i).

getRanges().setInvert(invert).relationName()).121 - . } /** * Toma el valor de la propiedad */ public String getAttributeIndices() { return m_CopyCols. } /** * Devuelve el tip text de esta propiedad */ public String invertSelectionTipText() { return "Sets copy selected vs unselected action. } } /** * Devuelve un string describiendo el filtro * */ public String globalInfo() { return "Un filtro de instancias que normaliza los valores numéricos " + "y tranforma los atributos nominales en numéricos.". } /** * Toma el valor de esta propiedad */ public boolean getInvertSelection() { return m_CopyCols.María Daniela Navas Padrón: 75. outputFormatPeek(). " + "para utilizar con algoritmos que solo permitan atributos numéricos"." + " If set to true. } /** * Devuelve el tip text de esta propiedad */ . } /** * Setea el valor de la propiedad */ public void setInvertSelection(boolean invert) { m_CopyCols.getInvert()." + " If set to false.setRelationName(outputFormat. only the specified attributes will be copied.626 Un modelo de Clustering Temporal Octubre 2004 /** * Seteo el formato de salida */ public void setOutputFormat(Instances outputFormat) { if (outputFormat != null) { super.setOutputFormat(outputFormat). non-specified attributes will be copied.

6-10. with" + " \"first\" and \"last\" valid values.626 Un modelo de Clustering Temporal Octubre 2004 public String attributeIndicesTipText() { return "Specify range of attributes to act on. E.setRanges(rangeList).g: \"first-3.5." + " This is a comma separated list of attribute indices. } public static void main(String [] argv) { } } . Specify an inclusive" + " range with \"-\".".last\".122 - .indicesToRangeList(attributes)). } /** * Setea los indices */ public void setAttributeIndicesArray(int [] attributes) throws Exception { setAttributeIndices(Range.María Daniela Navas Padrón: 75. } /** * Setea cuales atributos serán copiados y cuales no */ public void setAttributeIndices(String rangeList) throws Exception { m_CopyCols.

You should have received a copy of the GNU General Public License along with this program. if not. MA 02139.filters. either version 2 of the License. /** * Atributos luego de filtrados por AtributosNumericos . 675 Mass Ave. <p> * * @author María Daniela Navas (mnavas@mnavas..attribute.ar) * @version $Revision: 1.*.unsupervised.123 - . you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. Cambridge. weka.class /* * * * * * * * * * * * * * */ This program is free software.0 $ * @see Clusterer * @see OptionHandler */ public class Temporal_k_D_Median extends Clusterer implements OptionHandler { /** * Instancias del juego de datos */ private Instances m_instances. java.unsupervised. weka. weka. See the GNU General Public License for more details. but WITHOUT ANY WARRANTY.*.clusterers.java * Octubre 2004 María Daniela Navas * */ package weka.filters. Inc. * * Opciones válidas:<p> * * -N <numero de clusterss> <br> * Especifica el número de clusters a generar.io. java. without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. write to the Free Software Foundation.626 Un modelo de Clustering Temporal Octubre 2004 Temporal k-d-Median. /** * Archivo donde se guardan los resultados */ private String m_NombreArchivo.com. USA.*. weka.core.AtributosNumericos.lang.Filter.ReplaceMissingValues.María Daniela Navas Padrón: 75. /* * Temporal_k_D_Median.*. This program is distributed in the hope that it will be useful.attribute. or (at your option) any later version.filters. /** * Temporal k_D_Median clustering class. import import import import import import import java.util.

int [][][][] m_MatrixInestabilidad. } /** * Genera los clusters */ public void buildClusterer(Instances data) throws Exception { //Variables generales int t.626 Un modelo de Clustering Temporal Octubre 2004 */ private AtributosNumericos m_AtributosNumericos. int c. int a. } //Verifico que el primer atributo se llame Temp (significa que ya pasó por el filtro //CreateTemporalUnits .124 - . int j. /** * Número de clusters a generar */ private int m_NumClusters = 2. int i. private Instances [] m_VectorClusterCentroidsInterno. //Este es el de los cálculos intermedios //Matriz de CLusters asignados private int [][] m_MatrixClusterAssignments. /** * Devuelve un string con la informacion */ public String globalInfo() { return "Cluster data using the temporal k-D-Median algorithm". if (data. /*Matriz para guardar los centroides*/ private Instances [] m_VectorClusterCentroids. //Matriz donde guardo los pasajes de cluster para un tiempo dado //2da dimension: cluster origen //3era dimension : cluster destino double [][] m_MatrixFinal. /** * Número de Unidades Temporales */ private int m_NumTemporalUnits = 2.María Daniela Navas Padrón: 75. //Matriz para guardar las instancias en cada unidad de tiempo private Instances [] m_VectorInstances. private Instances [] m_VectorInstancesSinFiltro.checkForStringAttributes()) { throw new Exception("No se pueden manejar atributos String!"). //Vector que guardará que nro de cluster corresponde de un tiempo a otro int [] m_VectorCambioCluster.

} /* Según el atributo 0 de la instancia en cuestión. m_VectorInstancesSinFiltro[pos].value(0). } //La cantidad de unidades temporales es la cantidad de valores distintos que tiene el atributo 0 m_NumTemporalUnits = data. } //Vector para manejar los centroides para cada cluster de cada unidad temporal m_VectorClusterCentroidsInterno = new Instances [m_NumTemporalUnits]. } //Lleno el m_VectorInstancesSinFiltro con las instancias antes de pasarlas por el filtro numerico int pos. m_NombreArchivo = data.numInstances().relationName() + "_C" + m_NumClusters + "_T" + m_NumTemporalUnits.2".setOptions(options).instance(i)).María Daniela Navas Padrón: 75. t < m_NumTemporalUnits . i++) { pos = (int)data.name(). guardo el cluster asignado m_MatrixClusterAssignments = new int[m_NumTemporalUnits][]. t++) { m_VectorInstancesSinFiltro[t] = new Instances(data.value(0). //rango de atributos que EXCLUYO (porque invertì la selecciòn) //m_AtributosNumericos.name(). t++) { m_VectorInstances[t] = new Instances(m_instances. m_VectorInstances = new Instances [m_NumTemporalUnits].t++) { m_VectorClusterCentroidsInterno[t] = new Instances(m_VectorInstances[t].m_NumClusters). m_AtributosNumericos. //Invierto la seleccion options[0] = "-V".numDistinctValues(0). //rango de atributos options[1] = "-R". for (t= 0. }else if (!data. i < m_instances. //Inicializo los vectores de instancias sin filtro m_VectorInstancesSinFiltro = new Instances [m_NumTemporalUnits].attribute(0).instance(i)).125 - . m_MatrixClusterAssignments[t] = new int[m_VectorInstances[t]. para cada unidad temporal.attribute(1).numInstances(). for (i = 0.equals("ID")){ throw new Exception("Antes de realizar el cluster debe aplicar el filtro CreateTemporalUnits").instance(i).add( m_instances. agrego el atributo al vector de instancias en la posición que corresponda*/ for (i = 0. } m_AtributosNumericos = new AtributosNumericos(). for (t=0. m_instances = Filter.equals("Temp")) { throw new Exception("Antes de realizar el cluster debe aplicar el filtro CreateTemporalUnits"). i++) { pos = (int)m_instances.2"). m_VectorInstances[pos]. options[2] = "1.626 Un modelo de Clustering Temporal Octubre 2004 if (!data. m_AtributosNumericos). .setAttributeIndices("1.0). t < m_NumTemporalUnits .instance(i). //Matriz donde para cada instancia. String [] options = new String[3]. i < data.0).useFilter(data. m_AtributosNumericos.numInstances()].setInputFormat(data).add( data. t < m_NumTemporalUnits. for (t=0.

126 - . for (i = 0. t++){ for(a=2. } } //for c }//for t .getTime(). break.instance(instIndex ).nextInt()) % m_VectorInstances[0]. } }//for //Controlo también que no tenga ninguno de sus atributos missing (en ninguno de los tiempos if (!HayRepetidos){ for(t=0.abs(Random0.626 Un modelo de Clustering Temporal Octubre 2004 } //Uso como semilla la fecha actual Date Fecha = new Date(). t++){ for(a=2.abs(Random0. long m_Seed= Fecha. //Centroides iniciales //Asigno al azar los centroides del primer tiempo VectorIndices = new int [m_NumClusters].María Daniela Navas Padrón: 75. t < m_NumTemporalUnits.isMissingValue(m_VectorInstances[t]. a++){ if (m_VectorInstances[t].numAttributes(). Random Random0 = new Random(m_Seed).nextInt()) % m_VectorInstances[0].instance(instIndex). } } //for c }//for t }//if while (HayRepetidos){ //vuelvo a generar un indice instIndex = Math.instance(instIndex ).value(a))){ HayRepetidos = true.numInstances(). a < m_VectorInstances[t]. para evitar que haya repetidos int [] VectorIndices.isMissingValue(m_VectorInstances[t]. i < m_NumClusters.value(a))){ HayRepetidos = true. a < m_VectorInstances[t]. a++){ if (m_VectorInstances[t]. j++){ if (VectorIndices[j]== instIndex){ HayRepetidos = true. //Acá guardo los indices que voy eligiendo. for (j=0. i++) { instIndex = Math. j++){ if (VectorIndices[j]== instIndex){ HayRepetidos = true.numAttributes(). j < m_NumClusters.instance(instIndex). break. } }//for //Controlo también que no tenga ninguno de sus atributos missing (en ninguno de los tiempos if (!HayRepetidos){ for(t=0. break. boolean HayRepetidos=false. j < m_NumClusters. //vuelvo a preguntar HayRepetidos = false.numInstances(). for (j=0. int instIndex. break. t < m_NumTemporalUnits.

//Lo agrego a los indices VectorIndices[i] = instIndex.numInstances()][m_NumClusters][m_NumCluster s]. inestabilidad = true. newC = clusterProcessedInstance(toCluster.instance(instIndex)).numInstances(). Instances tempI[]. //Controlo la inestabilidad m_MatrixInestabilidad[t][j][m_MatrixClusterAssignments[t][j]][newC]++.626 Un modelo de Clustering Temporal Octubre 2004 }//if }//while //Agrego el centroide m_VectorClusterCentroidsInterno[0].add(m_VectorInstances[0]. while (!converged && !inestabilidad) { //reasigno las instancias converged = true. j++) { toCluster = m_VectorInstances[t]. /*Tengo un tempI por cada dimension temporal . Tengo que parar el algoritmo if (m_MatrixInestabilidad[t][j][m_MatrixClusterAssignments[t][j]][newC] > 3){ inestabilidad = false. inestabilidad = false. quiere decir que ya no converge //y se queda ahí. j < m_VectorInstances[t]. Instance toCluster. //Si alguna instancia pasa mas 3 veces del mismo cluster al mismo cluster. int newC. }//for m_VectorClusterCentroidsInterno[t] = new Instances(m_VectorInstances[t]. if (newC != m_MatrixClusterAssignments[t][j]) { converged = false. } }//if m_MatrixClusterAssignments[t][j] = newC.instance(j). for (j = 0.m_NumClusters). Tengo que parar el algoritmo m_MatrixInestabilidad = new int[m_NumTemporalUnits][m_VectorInstances[t].María Daniela Navas Padrón: 75. //Inicializo la matriz de Inestabilidad //Si alguna instancia pasa mas 3 veces del mismo cluster al mismo cluster. double vals[]. t < m_NumTemporalUnits. for ( t = 0.esto acumula los clusters*/ . t++) { converged = false.127 - .t). boolean inestabilidad. }//for i //*** COMIENZO EL PROCESO DE CLUSTERING TEMPORAL //Variables utilizadas boolean converged. quiere decir que ya no converge //y se queda ahí.

c++){ m_VectorClusterCentroidsInterno[t+1]. int dest.numInstances(). vals)).numAttributes()]. m_MatrixComb = ArmarCombinacion(m_MatrixComb. } //Normalizo la matriz final para que todos los valores estén en igualdad de condiciones for (i=0. double Total =0. c < m_NumClusters.value(1))). }//for c }//if }//for t //Una vez que tengo la matriz con las asignaciones. int [][] m_MatrixComb. //Lo hago acà para hacerlo una sola vez m_MatrixComb = new int [factorial(m_NumClusters)][m_NumClusters].instance((int)m_VectorClusterCentroidsInterno[t]. double CantMax=-1.numInstances(). for (c = 0.626 Un modelo de Clustering Temporal Octubre 2004 tempI = new Instances[m_NumClusters]. m_MatrixFinal[orig][dest] = m_MatrixFinal[orig][dest] + 1. dest = m_MatrixClusterAssignments[t+1][j].m_NumClusters). son los centroides del tiempo anterior if (t < (m_NumTemporalUnits -1)){ for (c=0. } for (j = 0. c++) { vals = new double[m_VectorInstances[t]. } for (c= 0.128 - . j++) { tempI[m_MatrixClusterAssignments[t][j]].1. c < m_NumClusters. j < m_VectorInstances[t]. i < m_NumClusters.add(new Instance(1. m_VectorClusterCentroidsInterno[t].add (m_VectorInstances[t]. int ClusterActual. int PosMax=0. i++){ //Sumo el total . double Resultado=0. //Armo las combinaciones posibles de intercambio de clusters. vals= Centroide_K_D_Median(tempI[c]). m_VectorClusterCentroids = new Instances [m_NumTemporalUnits].instance(c). t++){ //la creo cada vez para inicializarla m_MatrixFinal = new double[m_NumClusters][m_NumClusters]. int ClusterAnt.instance(j)). c++) { tempI[c] = new Instances(m_VectorInstances[t].j++){ orig = m_MatrixClusterAssignments[t][j].María Daniela Navas Padrón: 75. j < m_VectorInstances[t]. 0).0. creo la matriz final. }//for c }//while //Las semillas del tiempo siguiente. //Calculo de a un cambio de tiempo a la vez for (j= 0.add(m_VectorInstances[t]. con la cant de individuos que pasaron de un cluster a otro int orig. t < m_NumTemporalUnits . c < m_NumClusters. for (t= 0.

i < m_VectorInstancesSinFiltro[t]. j < m_NumClusters. i++){ m_VectorCambioCluster[i] = m_MatrixComb[PosMax][i]. }//if }//for }//for } //Ahora sumo de a una unidad temporal //Recorro las instancias.numInstances().add(m_VectorInstancesSinFiltro[t]. m_MatrixClusterAssignments[t+1][j]= ClusterActual.María Daniela Navas Padrón: 75.instance(i). PosMax = i. i++){ for (j=0.626 Un modelo de Clustering Temporal Octubre 2004 for (j=0.numInstances().instance(i)). }//for i for (i=0. para cambiar los clusters correspondientes //NuevoCluster =0. c++){ . i++){ //Comparo los ID de las instancias if (m_VectorClusterCentroidsInterno[t]. for (c=0. m_VectorClusterCentroids[t+1] = new Instances(m_VectorInstancesSinFiltro[t+1]. }//for j //Reemplazo esa fila for (j=0. for (c=0. i < factorial(m_NumClusters). c < m_NumClusters. i < m_NumClusters. }//for i m_VectorCambioCluster = new int [m_NumClusters]. ClusterActual = m_VectorCambioCluster[ClusterAnt].m_NumClusters).m_NumClusters). j ++ ){ Resultado = Resultado + m_MatrixFinal[m_MatrixComb[i][j]][j].agrego la que corresponde antes del filtro for (i= 0. j < m_NumClusters. j < m_NumClusters. }//for j Total =0. }//for i //Cambio las asignaciones y los centroides correspondientes al siguiente tiempo (El tiempo 0 está correcto) if (t==0){ m_VectorClusterCentroids[t] = new Instances(m_VectorInstancesSinFiltro[t].instance(c). c < m_NumClusters. for (j=0. } Resultado =0.value(1)== m_VectorInstancesSinFiltro[t]. }//for j int posicion=0. j++){ m_MatrixFinal[i][j] = m_MatrixFinal[i][j] / Total. c++){ //En lugar de agregar la instancia despues del filtro .129 - . }//for j if (Resultado > CantMax){ CantMax = Resultado.value(1)){ m_VectorClusterCentroids[t]. for (i=0. j++){ Total = Total + m_MatrixFinal[i][j]. j < m_VectorInstances[t+1]. j++){ ClusterAnt = m_MatrixClusterAssignments[t+1][j].

numInstances().numAttributes().getBytes()). //El primer renglón de lineas tine CantInstancias.instance(i). } //diferencio si es missing o no if (linea != ""){ if (!m_VectorInstancesSinFiltro[t]. } }else{ if (!m_VectorInstancesSinFiltro[t]. //solo imprimo los atributos distintos de Temp y Id missing = true. for (t= 0.value(j))){ missing = false. }else{ linea = "\n" + m_VectorInstancesSinFiltro[t]. cluster = "".value(j)." + m_NumClusters + ". i++){ if (m_VectorCambioCluster[i] == c){ posicion = i.isMissingValue(m_VectorInstancesSinFiltro[t].isMissingValue(m_VectorInstancesSinFiltro[t]. }else{ linea = linea + ".csv").write(linea. }//if }//for }//for } //Guardo la matriz en un excel: OutputStream Salida = new FileOutputStream(m_NombreArchivo + ".value(j))){ linea = "\n" + m_VectorInstancesSinFiltro[t]. String cluster = null.130 - .value(j))){ linea = linea + ". j < m_VectorInstancesSinFiltro[t]. i < m_VectorInstancesSinFiltro[t].agrego la que corresponde antes del filtro for (i= 0.instance(i)). NumUT linea = m_VectorInstancesSinFiltro[0].instance(i).toString(j). cual es el destino = c for(i=0. i++){ linea ="".NumClusters.value(1)){ m_VectorClusterCentroids[t+1].instance(i). t < m_NumTemporalUnits . i < m_VectorInstancesSinFiltro[t]. NumAtributos.add(m_VectorInstancesSinFiltro[t+1].instance(i). boolean missing. .numInstances() + ".instance(i). String linea = null." + m_VectorInstancesSinFiltro[t]. } }//for i //En lugar de agregar la instancia despues del filtro .instance(i ).626 Un modelo de Clustering Temporal Octubre 2004 //Busco entre la matriz de cambio cluster.isMissingValue(m_VectorInstancesSinFiltro[t]. for (j= 2.instance(i). i++){ //Comparo los ID de las instancias if (m_VectorClusterCentroidsInterno[t+1]. t++){ for (i= 0. Salida.instance(i).María Daniela Navas Padrón: 75." + (m_VectorInstancesSinFiltro[0].numAttributes()-2)+ ". j++){ if (!m_VectorInstancesSinFiltro[t].instance(i).instance(i ). i < m_NumClusters." + m_NumTemporalUnits." + m_VectorInstancesSinFiltro[t].toString(j).numInstances().instance(posicion).instance(i ).value(1)== m_VectorInstancesSinFiltro[t].value(j).

} public int clusterInstance(Instance instance) throws Exception { return 0. for (i = 0.María Daniela Navas Padrón: 75. if (dist < minDist) { minDist = dist. int t) { double minDist = Integer.value(1)== m_VectorInstancesSinFiltro[t]. //esto no hace nada.-2".-1". } /* *Proceso cada instancia pasada como parametro */ private int clusterProcessedInstance(Instance instance.instance(i)).626 Un modelo de Clustering Temporal Octubre 2004 } } } //Cuando copié todos los atributos.close(). c++){ //Comparo los ID de las instancias if (m_VectorClusterCentroids[t]. c < m_NumClusters. tiene que estar por compatibilidad con la clase padre!! } /** * Calcula la distancia entre 2 instancias */ . m_VectorClusterCentroidsInterno[t].instance(i). //Si es el centroide de algún cluster lo agrego. int i. i < m_NumClusters. Salida. } }//for c linea = linea + cluster." + c. } else if (cluster==""){ cluster = ". int bestCluster = 0. }//for i } Salida. }else{ linea = linea + ".value(1)){ cluster = ". agrego un -2 if (missing) { linea = linea + ".instance(c). sino asigno -1 for (c=0.getBytes()). agrego el cluster correpondiente //Si es missing." + t." + m_MatrixClusterAssignments[t][i] . bestCluster = i.write(linea. } } return bestCluster.131 - .MAX_VALUE. i++) { dist = distance(instance. double dist=0. } //Agrego la unidad temporal linea = linea + ".

}//for return Math. Instance second) { double distance = 0.numAttributes().val2. "-N <num>")). i++){ if ((!first. for (i=2.MAX_VALUE.isMissingValue(first.isMissingValue(val1) ||Instance. }else{ //si hay alguno o los dos missing.addElement(new Option("\tnumber of clusters. i < m_VectorInstances[0]. } /** * Calcula la diferencia entre 2 valores */ private double difference2(double val1. } distance += diff * diff.MAX_VALUE. }else{ diff= val1 .elements(). (default = 2). int i.sqrt(distance). return newVector. if (Instance.value(i)). newVector. double diff=Double.MAX_VALUE." . } /** * Describe las opciones posibles. devuelvo un nro grande diff = Double. } return diff. second. * * @return the number of clusters generated for a training dataset. <p> **/ public Enumeration listOptions () { Vector newVector = new Vector(1). devuelvo un nro muy grande diff=Double.value(i).value(i))) && (!second. double val2) { double diff= Double. * @exception Exception if number of clusters could not be returned * successfully */ public int numberOfClusters() throws Exception { return m_NumClusters.MAX_VALUE. 1.María Daniela Navas Padrón: 75.isMissingValue(first.isMissingValue(val2)){ //si alguno es missing.626 Un modelo de Clustering Temporal Octubre 2004 private double distance(Instance first. } .value(i)))){ //ninguno es Missing diff = difference2(first. } /** * Returns the number of clusters. "N".132 - .

while (current < options. options).María Daniela Navas Padrón: 75. } /** * Devuelve el numero de clusters */ public int getNumClusters() { return m_NumClusters. } /** * setea el número de clusters a generar */ public void setNumClusters(int n) { m_NumClusters = n.626 Un modelo de Clustering Temporal Octubre 2004 /** * Devuelve el tip text para esta propiedad */ public String numClustersTipText() { return "set number of clusters". } /** * Parsea la lista de opciones **/ public void setOptions (String[] options) throws Exception { String optionString = Utils. } return options.133 - .length() != 0) { setNumClusters(Integer. } /** * Devuelve un string describiendo el resultado del clustering */ public String toString() { StringBuffer temp = new StringBuffer(). options[current++] = "" + getNumClusters(). if (optionString.getOption('N'. int current = 0.append("\nTemporal_k_D_Median\n======\n"). .length) { options[current++] = "".parseInt(optionString)). temp. } } /** * Devuelve las opciones elegidas */ public String[] getOptions () { String[] options = new String[2]. options[current++] = "-N".

//Valor que da fin al algoritmo iterativo int Definicion = CantIndividuosOriginal.numAttributes().append("\n\n"). i++){ IndiceSeleccionados[i]=i. int []Indice. //Cantidad de individuos que se irán filtrando en las iteraciones. original //mente son todos int CantIndividuos = CantIndividuosOriginal. //Defino el k-means de los individuos que no fueron filtrados Instance xmeans = new Instance(IndividuosOriginal. //Individuos que resultarán de cada filtro. } } return temp. value((int)m_VectorClusterCentroids[t].numAttributes(). originalmente todos Instances Individuos = new Instances(IndividuosOriginal).append(" "+m_VectorClusterCentroids[t].instance(i). i++) { temp. for(int i=0. } // Inestabilidad: Si el sistema deja de filtrar luego de tres iteraciones //se da por terminado.append("\nCluster "+(i+1)+"\n\t"). i< CantIndividuosOriginal.attribute(j). //Cantidad de Atributos que tiene una instancia int CantAtributos = IndividuosOriginal.134 - . j++) { if (m_VectorClusterCentroids[t]. int Inestabilidad=0.626 Un modelo de Clustering Temporal Octubre 2004 for (int t = 0.toString(). .numAttributes()). j < m_VectorClusterCentroids[t].append(" "+m_VectorClusterCentroids[t]. int []IndiceOriginal.instance(i). SE DEBE REEMPLAZAR ESTA * FUNCION !!!! */ private double [] Centroide_K_D_Median(Instances IndividuosOriginal) { //Cantidad de individuos que tiene originalmente el vector Instances int CantIndividuosOriginal = IndividuosOriginal.value(j))). //Vector que guardará los indices de los individuos seleccionados int [] IndiceSeleccionados = new int [CantIndividuosOriginal].t++) { temp. } } temp. for (int i = 0. } else { temp.append("\n\nCluster centroids for temporal unit "+(t+1)+":\n"). } /****** * Encuentra el centroide de un grupo de individuos con el método k-d-Median * SI SE DESEA ENCONTRAR EL CENTROIDE CON OTRO METODO. i < m_NumClusters.numInstances().isNominal()) { temp.attribute(j). for (int j = 0.value(j)). //Cantidad de individuos que se comparan para realizar los cálculos int CantFiltros = 1. t < m_NumTemporalUnits.María Daniela Navas Padrón: 75.

meanOrMode(i). Instances NuevosIndividuos. . aux[1]=0. for (i=0. Individuos. Instances Individuo. double MinFW. //%%%Encontrar los "CantFiltros" individuos mas cercanos a XMeans //Genero un vector de doubles para guardar las distancias de los //individuos a xmeans dist = new double[CantIndividuos]. double val2. for (i = 2. double ValorGravityXmeans. for (i=0. aux).0. ContadorAuxiliar=0.626 Un modelo de Clustering Temporal Octubre 2004 //Variables generales int i. }//for //creo una instancia con los valores de los atributos xmeans = new Instance(1. Instances IndividuosAux. } //Me fijo cuál es la máxima distancia MaximoAuxiliar=0. i++) { aux[i] = Individuos. double ValorAuxiliar. double [] VectorDiferencia. //los voy a usar en los for double [] aux. double val1. double [][] Filtro. double MaximoAuxiliar. double [] ValoresGravity. i++) { dist[i] = distance(xmeans. i < CantAtributos. int [] IndiceIndividuo. double aux2. int IndiceMinFW.Media para cada atributo aux = new double[CantAtributos]. //los valores 0 y 1 no importan ya que no se comparan aux[0]=0.135 - . double [][] Gradiente. double [] ValoresFW.i++){ if (MaximoAuxiliar < dist[i]){ MaximoAuxiliar = dist[i].k.instance(i)).j. double norma. double distAux. i< CantIndividuos. i < CantIndividuos. double [] dist. int ContadorAuxiliar. //Comienza el proceso de iteración while ((Definicion > 6) & (Inestabilidad < 1)) { // Buscar Vector XMeans . int CantAnterior.María Daniela Navas Padrón: 75. int [] NuevoIndice. Instance OptimoFinal.

IndividuosOriginal. }//for j //Individuo son los "CantFiltros" más cercano a xmeans en este paso Individuo = new Instances(Individuos. for (j=0. for (j=0. ValorAuxiliar =0.IndividuosOriginal.instance(j)). dist[ContadorAuxiliar]=MaximoAuxiliar. } //% Calculo los Valores de FW para los individuos seleccionados y para xmeans ValoresGravity = new double[CantFiltros]. for (i=0.i++){ Individuo. i++){ ValoresGravity[i]=0. for (i=0. IndiceIndividuo[i] = IndiceSeleccionados[IndiceIndividuo[i]]. } ValorAuxiliar =0.add(Individuos. j < CantIndividuosOriginal. i++){ if(ValorAuxiliar < ValoresGravity[i]){ ValorAuxiliar = ValoresGravity[i]. if (ValorAuxiliar==1){ ValorAuxiliar = ValoresGravity[0]. i++) { if (dist[i] < ValorAuxiliar) { ValorAuxiliar = dist[i]. i < CantFiltros.instance(IndiceIndividuo[i]). for(i=0. j++){ ValorGravityXmeans = ValorGravityXmeans + distance(xmeans. j < CantIndividuosOriginal. . i <CantFiltros . for (i=0. ContadorAuxiliar =0. j++){ ValoresGravity[i] = ValoresGravity[i] + distance(IndividuosOriginal. i < CantIndividuos. for (i =1.j++){ ValorAuxiliar = MaximoAuxiliar.136 - .instance(j)). }//for j }//for i ValorGravityXmeans =0.626 Un modelo de Clustering Temporal Octubre 2004 ContadorAuxiliar = i.instance(IndiceIndividuo[i])).CantFiltros). ContadorAuxiliar = i. y en cada iteración encuentro //el mínimo valor y lo anulo(con el valor máximo) para que en la siguiente //vuelta el mínimo sea el siguiente valor IndiceIndividuo= new int[CantFiltros]. } } IndividuosAux = new Instances(Individuos.María Daniela Navas Padrón: 75. } } //Busco los "CantFiltros" mínimos del vector distancia //Recorro el vector "CantFiltros" veces.i<CantFiltros. ContadorAuxiliar=i. for (j=0. i++){ if(ValorGravityXmeans > ValoresGravity[i]){ ValorAuxiliar = 1.i<CantFiltros.CantFiltros). } } //for i IndiceIndividuo[j]=ContadorAuxiliar. j<CantFiltros.

j< CantFiltros. val2 = IndividuosOriginal. k < CantAtributos. k < CantAtributos. }//if // Encontrar el Gradiente Extendido para los Individuos Seleccionados Gradiente = new double[CantFiltros][CantAtributos]. . i++){ if (i == ContadorAuxiliar){ IndividuosAux.instance(i)). k < CantAtributos.instance(i). j++){ for ( i=0. }//for k }//if }//for i norma = 0.attribute(j) RestoIndividuosOriginal. k++){ Gradiente[j][k] = 0. j++){ for ( k=0.valueSparse(k). IndiceIndividuo[i] = -1. i < CantFiltros.María Daniela Navas Padrón: 75.IndividuosOriginal.add(xmeans). } } for (j=0.137 - . i < CantIndividuosOriginal.sqrt(norma). if (distAux > 0){ for ( k=2.k++){ //esto es lo que debería irGradiente[j] = Gradiente [j] + (Individuo. k++){ norma = norma + (Gradiente[j][k] * Gradiente[j][k]). //pero no puedo restar los atributos. for ( k = 2. //para anularlo }else{ IndividuosAux. por si son categoricos //Val1 y Val22 son los valores de los atributos a restar pasados a formato interno val1 = Individuo. } norma = Math.val2)/distAux. k++){ Gradiente[j][k] = aux2 * Gradiente[j][k].instance(j).add(Individuo.instance(i). } } Individuo = new Instances(IndividuosAux). Gradiente[j][k] = Gradiente [j][k] + difference2(val1. k < CantAtributos.valueSparse(k).1 / norma. }//for } else{ for ( k = 2. for (j=0.k++){ Gradiente[j][k]=0. k < CantAtributos. }//for k }//else }//for j // Calcular las Zonas de Filtrado: Filtro = new double [CantIndividuos][CantFiltros]. aux2 = 1 .attribute(j))/distAux. if (aux2 > 0 ){ for ( k = 2.i++){ distAux = distance(Individuo. VectorDiferencia = new double [CantAtributos].626 Un modelo de Clustering Temporal Octubre 2004 } }//for for (i=0.instance(i)).instance(j). j< CantFiltros.

VectorDiferencia[k] * Gradiente[i][k].valueSparse(k). } else{ Inestabilidad=0.instance(i)). val2 = Individuo.instance(i). //%%% Si durante 3 ciclos no se filtra ningún individuo. k ++){ //Val1 y Val22 son los valores de los atributos a restar pasados a formato interno val1 = Individuos.instance(i))..138 - . k ++){ Filtro[j][i] = Filtro[j][i] . CantIndividuos = ContadorAuxiliar.val2). NuevoIndice[ContadorAuxiliar]=IndiceSeleccionados[i]... j++){ for ( k=2. j < CantIndividuos..add(Individuos. Individuos. }//for k }//for j }//for i // Encuentro los Individuos que no fueron Filtrados. i++){ for ( j= 0 .. k < CantAtributos . ContadorAuxiliar). i++){ ValorAuxiliar=1.add(NuevosIndividuos. for (j=0.i++){ IndiceSeleccionados[i] = NuevoIndice[i].valueSparse(k). VectorDiferencia[k]=difference2(val1...626 Un modelo de Clustering Temporal Octubre 2004 for (i=0. } }//for j if (ValorAuxiliar==1){ NuevosIndividuos. j++){ if (Filtro[i][j]<0){ ValorAuxiliar =0. }//for k Filtro[j][i]=0. for (i=0. ContadorAuxiliar++.María Daniela Navas Padrón: 75.i<ContadorAuxiliar. } }//for i //Reasigno los valores CantAnterior= CantIndividuos. se sale del algoritmo iterativo. i < CantFiltros.0). NuevoIndice = new int[CantIndividuos].. k < CantAtributos . if(CantIndividuos==CantAnterior){ Inestabilidad=Inestabilidad+1. NuevosIndividuos = new Instances(Individuos. for ( k=2. } //reasigno IndiceSeleccionados IndiceSeleccionados = new int [ContadorAuxiliar]. j<CantFiltros. ContadorAuxiliar = 0. //reasigno los individuos Individuos = new Instances(NuevosIndividuos. i<CantIndividuos.instance(j). } . for (i=0.

ContadorAuxiliar=0. }//while if (Inestabilidad < 1){ //%%%%% Busco a mano los valores de FW para los individuos que quedaron.instance(IndiceMinFW)). i< CantIndividuos. j < CantIndividuosOriginal. i++) { if (dist[i] < ValorAuxiliar) { ValorAuxiliar = dist[i]. ValoresFW = new double [CantIndividuos]. } } ValorAuxiliar =MaximoAuxiliar. for (i=1.. for (i=0. IndiceMinFW = i. } else{ //si Inestabilidad es mayor o igual a 1 dist = new double[CantIndividuos]. i++){ if (ValoresFW[i] < MinFW ){ MinFW = ValoresFW[i]. i < CantIndividuos. for (i=0.i++){ if (MaximoAuxiliar < dist[i]){ MaximoAuxiliar = dist[i]. for (j=0. } }//for OptimoFinal = new Instance(Individuos. y en cada iteración encuentro //el mínimo valor y lo anulo(con el valor máximo) para que en la siguiente //vuelta el mínimo sea el siguiente valor MaximoAuxiliar=0.j++){ ValoresFW[i] = ValoresFW[i] + distance(Individuos.i++){ ValoresFW[i]=0. IndiceMinFW = 0..instance(i)).María Daniela Navas Padrón: 75. for (i=0.. } } //for i //no lo uso int IndiceFinal = IndiceSeleccionados[ContadorAuxiliar]. i< CantIndividuos. } } //%%% optimofinal: Valor de menor FW (obtenido manualmente //%%% luego del proceso de filtrado).139 - . Individuos.instance(j)). } //Busco los "CantFiltros" mínimos del vector distancia //Recorro el vector "CantFiltros" veces. ContadorAuxiliar = i.instance(i). MinFW = ValoresFW[0].IndividuosOriginal. ContadorAuxiliar = i. for (i=0. i < CantIndividuos. i++) { dist[i] = distance(xmeans.instance(ContadorAuxiliar)). //hay un solo elemento .626 Un modelo de Clustering Temporal Octubre 2004 Definicion=CantIndividuos. i < CantIndividuos. OptimoFinal = new Instance(Individuos.

d++){ if (d < i){ Matriz[(i*valor) + c][d] = MatrizNueva[c][d]. j++){ Matriz[(i*valor) + j][i] = tamanio -1.140 - .María Daniela Navas Padrón: 75. *donde N es el número de clusters.tamanio-1).626 Un modelo de Clustering Temporal Octubre 2004 }//else return OptimoFinal. i < tamanio. } /** *Factorial de un numero */ private int factorial(int x) { int fact=0. Matriz[1][1]=0. }//for j MatrizNueva = new int [valor][tamanio -1]. for (i=0. j. if (tamanio ==2){ Matriz[0][0]=0. d < tamanio. for (c=0.toDoubleArray(). Matriz[1][0]=1. c <valor.} else if (x == 1) {fact = 1. int i. }else if (d > i){ Matriz[(i*valor) + c][d] = MatrizNueva[c][d-1].} else {fact = x * factorial (x-1). i++){ for (j=0. */ private int [][] ArmarCombinacion(int [][] Matriz. int [][] MatrizNueva.} return fact.c++){ for(d=0.c. MatrizNueva = ArmarCombinacion (MatrizNueva. j < valor. Matriz[0][1]=1. } }//for d }//for c }//for i }//else return Matriz. }else { valor = factorial(tamanio-1). if (x == 0) { fact =1. int tamanio) { int valor. } /* *Arma una matriz con la combinatoria de posibilidades de una matriz de NxN.d. .

getMessage()).141 - .626 Un modelo de Clustering Temporal Octubre 2004 } public static void main (String[] argv) { try { System.println(ClusterEvaluation.out. e. } } } .María Daniela Navas Padrón: 75.println(e. } catch (Exception e) { System. evaluateClusterer(new Temporal_k_D_Median(). argv)).printStackTrace().out.

b2 = [b. 'axis1_ButtondownFcn'. %Para mostrar el Logo [a.g. % FEVAL switchyard catch disp(lasterr).626 Un modelo de Clustering Temporal Octubre 2004 A2. EVENTDATA. %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H. and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. % Last Modified by GUIDE v2. b2) axis off.142 - . e.ico').) invoke the named callback. and store it. HANDLES. . 1 1 1]. % Generate a structure of handles to pass to callbacks.0 15-May-2004 12:42:02 if nargin == 0 % LAUNCH GUI fig = openfig(mfilename. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'.b. % Augment colormap for background color (white). % Display new image imshow(uint8(d). end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}). 'slider2_Callback'. handles = guihandles(fig).m function varargout = AnalisisResultados(varargin) % RESULTADOS Application M-file for AnalisisResultados.fig % FIG = RESULTADOS launch AnalisisResultados GUI. guidata(fig.María Daniela Navas Padrón: 75. %| . % RESULTADOS('callback_name'. handles). This comment describes that mechanism. % Create new image for display. % Use the AND mask to mix the background and % foreground data on the new image d(c == 0) = a(c == 0).c] = imread('clustering.2 MATLAB Análisis Resultados.'reuse'). end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file.. if nargout > 0 varargout{1} = fig.. d = ones(size(a)) * (length(b2) . %| 'figure1_CloseRequestFcn'.1).

'Enable'. Atributos=MatrizCompleta(1.'on'). set(handles.María Daniela Navas Padrón: 75. guidata(handles.4). handles.txtNombreArchivo.slider2.'Enable'.'Enable'.IntervalosTiempo = IntervalosTiempo.cmdGraficos3DTiempo.csv'. handles. before the final %| closing parenthesis. set(handles.pname] = uigetfile('*.fname).'Enable'. eventdata. . e.cmdGraficos3D. %| %| HANDLES is a structure containing handles of components in GUI using %| tags as fieldnames.'string'.'off').'Seleccione el archivo a utilizar'). %| %| EVENTDATA is empty. Call guidata(h. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. handles. handles.Individuos = Individuos.'off'). if(Atributos==2) set(handles.143 - .cmdGraficos3DTiempo.'on').'on').handles). A copy of the structure %| is passed to each callback. You can store additional information in %| this structure at GUI startup.'on').CantClusters = CantClusters.'off'). Type "help guihandles" and "help guidata" for more %| information.'Enable'.cmdGraficos2D. Individuos=MatrizCompleta(1. varargin) [fname.cmdGraficos2DTiempo. CantClusters=MatrizCompleta(1. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. set(handles.'on').figure1. set(handles.cmdGraficos2D. handles.'off'). set(handles. handles. By default.cmdGraficos3D. gcbo.cmdAtributo.2). set(handles. end if(Atributos==3) set(handles.'Enable'. handles. and you can change the structure %| during callbacks. guidata(gcbo)) %| Add any extra arguments after the last argument.cmdGraficos2DTiempo.3).g. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA.626 Un modelo de Clustering Temporal Octubre 2004 %| H is the callback object's handle (obtained using GCBO).'Enable'.'Enable'. but reserved for future use. GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'. [].fname]).Atributos = Atributos.Figura.MatrizCompleta = MatrizCompleta. function varargout = cmdAbrir_Callback(h. %Creo las variables y las guardo como globales MatrizCompleta=csvread([pname. Specify the extra arguments by editing the callback %| property in the inspector. %Habilito o deshabilito los botones segun corresponda set(handles. IntervalosTiempo=MatrizCompleta(1.1).'Enable'. handles. end set(handles.

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

set(handles.cmdPerdidos,'Enable','on'); set(handles.cmdIndividuos,'Enable','on');

function varargout = cmdGraficos2D_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = GRAFICOS2D;

function varargout = cmdGraficos3D_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = GRAFICOS3D; function varargout = cmdGraficos2DTiempo_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = GRAFICOS2DTiempo; function varargout = cmdGraficos3DTiempo_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = GRAFICOS3DTiempo;

function varargout = cmdAtributo_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = ATRIBUTOS;

function varargout = cmdIndividuos_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = ESTADISTICAS;

function varargout = cmdPerdidos_Callback(h, eventdata, handles, varargin) setappdata(handles.Figura,'handles',handles); fig = PERDIDOS; function varargout = txtNombreArchivo_Callback(h, eventdata, handles, varargin)

- 144 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

Graficos2D.m function varargout = Graficos2D(varargin) % GRAFICOS2D Application M-file for Graficos2D.fig % FIG = GRAFICOS2D launch Graficos2D GUI. % GRAFICOS2D('callback_name', ...) invoke the named callback. % Last Modified by GUIDE v2.0 12-May-2004 22:35:32 if nargin == 0 % LAUNCH GUI fig2 = openfig(mfilename,'reuse'); set(fig2,'Color',get(0,'defaultUicontrolBackgroundColor')); % Generate a structure of handles to pass to callbacks, and store it. handles2 = guihandles(fig2); handlesAnt = getappdata(1,'handles'); handles2.MatrizCompleta = handlesAnt.MatrizCompleta; handles2.Individuos = handlesAnt.Individuos; handles2.Atributos = handlesAnt.Atributos; handles2.CantClusters = handlesAnt.CantClusters; handles2.IntervalosTiempo = handlesAnt.IntervalosTiempo; %este i se va a usar para contar handles2.i=0; guidata(fig2, handles2); if nargout > 0 varargout{1} = fig2; end

elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}); % FEVAL switchyard catch disp(lasterr); end end

%| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file, and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. This comment describes that mechanism. %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H, EVENTDATA, HANDLES, VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_', e.g. 'slider2_Callback', %| 'figure1_CloseRequestFcn', 'axis1_ButtondownFcn'. %| %| H is the callback object's handle (obtained using GCBO). %| %| EVENTDATA is empty, but reserved for future use. %|

- 145 -

María Daniela Navas Padrón: 75.626

Un modelo de Clustering Temporal Octubre 2004

%| HANDLES is a structure containing handles of components in GUI using %| tags as fieldnames, e.g. handles.figure1, handles.slider2. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA. A copy of the structure %| is passed to each callback. You can store additional information in %| this structure at GUI startup, and you can change the structure %| during callbacks. Call guidata(h, handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. Type "help guihandles" and "help guidata" for more %| information. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. Specify the extra arguments by editing the callback %| property in the inspector. By default, GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>', gcbo, [], guidata(gcbo)) %| Add any extra arguments after the last argument, before the final %| closing parenthesis.

% -------------------------------------------------------------------function varargout = cmdTiempoSiguiente_Callback(h, eventdata, handles2, varargin) set(handles2.txtMensaje,'Visible','off'); i = handles2.i +1; set (handles2.txtTiempo,'String',i);

for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1) if (handles2.MatrizCompleta(k,3)~=-2) matriz = [matriz; handles2.MatrizCompleta(k,[1:handles2.Atributos])]; end end %tengo que excluir los que vienen con -2 for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1) if (handles2.MatrizCompleta(k,3)~=-2) colores = [colores; handles2.MatrizCompleta(k,3)]; end end matriz1=handles2.MatrizCompleta([(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1)],5); for k=(2+(i-1)*handles2.Individuos):(i*handles2.Individuos+1) if (handles2.MatrizCompleta(k,3)~=-2) %si es -2 lo excluyo if (handles2.MatrizCompleta(k,5)==-1) %si es -1 no es centroide medidas = [medidas;10]; else % si no es -1 es centroide, y lo dibujo mas grande medidas = [medidas;50]; end end end

auxiliar1=find(matriz1==-1); %Dibujo primero los centroides matriz2 = []; colores2=[]; auxiliar2 = find(matriz1 ~= -1);

- 146 -

colores2 = [colores2.'Enable'.colores2). handles2.medidas. leg=[]. for k=1:handles2.Individuos) + auxiliar2(k). end . %cuando termino.'Enable'.Atributos])].[1:handles2. set (handles2.b). for k=(2+(i-1)*handles2. handles2.matriz2(:.CantClusters b = num2str(k).cmdTiempoSiguiente. medidas2 = ones(handles2.1).MatrizCompleta(k.medidas2.'Enable'. leg=[leg.Individuos) +auxiliar2(k).CantClusters matriz2 = [matriz2. end legend(leg). %deshabilito el boton si no hay mas tiempos siguientes if (i==handles2.MatrizCompleta((1+(i-1)*handles2.CantClusters. else set(handles2. handles2.'off').handles2). else set(handles2.'off').'bold').Individuos+1) if (handles2.axes1. varargin) i = handles2. xlabel('Atributo 1').MatrizCompleta((1+(i-1)*handles2.'Enable'. % -------------------------------------------------------------------function varargout = cmdTiempoAnterior_Callback(h. handles2.cmdTiempoAnterior.'on').'on').3)].IntervalosTiempo) set(handles2. eventdata.txtTiempo.1).'FontWeight'.1) * 50.i -1. hold on.2).626 Un modelo de Clustering Temporal Octubre 2004 for k=1:handles2.i).3)~=-2) matriz = [matriz.matriz(:. guidata(gcbo.i = i. scatter(matriz(:. %Armo la leyenda con los centroides a='Cluster-'. hold off. c= strcat(a.147 - . scatter(matriz2(:.MatrizCompleta(k.2).cmdTiempoSiguiente.'String'.c].[1:handles2.Atributos])].Individuos):(i*handles2.cmdTiempoAnterior. ylabel('Atributo 2'). end %ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda colores2 = sort(colores2). guardo el nuevo i (para la proxima) handles2. end set(handles2.María Daniela Navas Padrón: 75.colores). end if (i==1) set(handles2.

guardo el nuevo i (para la proxima) handles2.Atributos])].1). y lo dibujo mas grande medidas = [medidas.handles2). guidata(gcbo. end end matriz1=handles2.MatrizCompleta(k.matriz2(:.Individuos):(i*handles2.c].5)==-1) %si es -1 no es centroide medidas = [medidas.María Daniela Navas Padrón: 75. end legend(leg).10].CantClusters b = num2str(k). handles2.50].MatrizCompleta(k. handles2.3)]. end %ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda colores2 = sort(colores2).CantClusters.Individuos):(i*handles2.Individuos+1)].MatrizCompleta((1+(i-1)*handles2.CantClusters matriz2 = [matriz2.medidas.5). for k=(2+(i-1)*handles2.2). %Armo la leyenda con los centroides a='Cluster-'. %cuando termino. %deshabilito el boton si no hay mas tiempos siguientes . auxiliar2 = find(matriz1 ~= -1). leg=[leg.MatrizCompleta((1+(i-1)*handles2. hold on. leg=[].3)~=-2) %si es -2 lo excluyo if (handles2.matriz(:.2). for k=1:handles2. colores2=[].Individuos):(i*handles2. colores2 = [colores2.colores).b). medidas2 = ones(handles2. hold off.3)].Individuos+1) if (handles2.MatrizCompleta([(2+(i-1)*handles2.MatrizCompleta(k.colores2). for k=1:handles2.MatrizCompleta(k.Individuos) + auxiliar2(k). else % si no es -1 es centroide. scatter(matriz(:.[1:handles2.148 - . %Dibujo primero los centroides matriz2 = []. end end end auxiliar1=find(matriz1==-1).3)~=-2) colores = [colores. scatter(matriz2(:.Individuos+1) if (handles2. c= strcat(a.i = i. handles2.1) * 50.626 Un modelo de Clustering Temporal Octubre 2004 end %tengo que excluir los que vienen con -2 for k=(2+(i-1)*handles2.medidas2.Individuos) +auxiliar2(k).1).

María Daniela Navas Padrón: 75. else set(handles2. end if (i==1) set(handles2.'off').IntervalosTiempo) set(handles2.'Enable'. ylabel('Atributo 2').'bold'). end set(handles2.'Enable'. else set(handles2.'FontWeight'.axes1.'Enable'.cmdTiempoAnterior.626 Un modelo de Clustering Temporal Octubre 2004 if (i==handles2.cmdTiempoSiguiente.149 - . xlabel('Atributo 1').'on').cmdTiempoAnterior.'on').'off').'Enable'.cmdTiempoSiguiente. .

% FEVAL switchyard catch disp(lasterr).Atributos = handlesAnt. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file.150 - .. handles5. handles5). %| 'figure1_CloseRequestFcn'.IntervalosTiempo.Individuos. e. if nargout > 0 varargout{1} = fig5. handles5. %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H. handles5 = guihandles(fig5).0 15-May-2004 17:42:26 if nargin == 0 % LAUNCH GUI fig5 = openfig(mfilename. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}). handles5. % GRAFICOS2DTIEMPO('callback_name'.'defaultUicontrolBackgroundColor')).IntervalosTiempo = handlesAnt.. .Individuos = handlesAnt. HANDLES. 'slider2_Callback'. set(fig5. 'axis1_ButtondownFcn'.g.fig % FIG = GRAFICOS2DTIEMPO launch Graficos2DTiempo GUI.CantClusters = handlesAnt. and store it.i=0.'handles'). %| %| H is the callback object's handle (obtained using GCBO).MatrizCompleta = handlesAnt. handles5.get(0. EVENTDATA. %este i se va a usar para contar handles5.CantClusters. % Generate a structure of handles to pass to callbacks.María Daniela Navas Padrón: 75.MatrizCompleta.) invoke the named callback. but reserved for future use. and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. guidata(fig5. handlesAnt = getappdata(1.Atributos. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'. handles5.m function varargout = Graficos2DTiempo(varargin) % GRAFICOS2DTIEMPO Application M-file for Graficos2DTiempo. % Last Modified by GUIDE v2.626 Un modelo de Clustering Temporal Octubre 2004 Graficos2DTiempo.'Color'. %| %| HANDLES is a structure containing handles of components in GUI using .'reuse'). %| %| EVENTDATA is empty. This comment describes that mechanism.

c= strcat(a. [].g.4). . handles. A copy of the structure %| is passed to each callback.'Visible'.MatrizCompleta).slider2. leg=[].i +1.'off').MatrizCompleta). e. auxiliar=auxiliar(1). leg=[leg.b). GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'.626 Un modelo de Clustering Temporal Octubre 2004 %| tags as fieldnames.MatrizCompleta([2:auxiliar]. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA.:). auxiliar=find(handles5.figure1. You can store additional information in %| this structure at GUI startup. set (handles5. Type "help guihandles" and "help guidata" for more %| information. %| %| VARARGIN contains any extra arguments you have passed to the %| callback.IntervalosTiempo b = num2str(k).MatrizCompleta([2:auxiliar1]. auxiliar1=auxiliar1(1). medidas=10*ones(auxiliar. medidas(auxiliar1)=50. auxiliar=size(matriz). hold on. %Dibujo primero los centroides medidas2 = ones(handles5.1))*1. % -------------------------------------------------------------------function varargout = cmdClusterSiguiente_Callback(h. auxiliar=auxiliar(1).colores2). handles.4). matriz=matriz(auxiliar.handles5.1. colores2=Clusters(:. eventdata. Clusters=matriz(auxiliar1.1). i = handles5.Atributos+1)==(i-1)). scatter(Clusters(:.[1:handles5.Clusters(:. end legend(leg). %inserto la leyenda a='Tiempo-'.1. axis([0 Eje1 0 Eje2]). gcbo. auxiliar=size(handles5.1). auxiliar1=find(matriz(:. for k=1:handles5.Atributos+3)==(i-1)). guidata(gcbo)) %| Add any extra arguments after the last argument. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. Eje1=max(handles5.'String'.c]. auxiliar1=size(handles5.IntervalosTiempo.MatrizCompleta([2:auxiliar]. handles5.:).handles5.2). varargin) set(handles5.medidas2. before the final %| closing parenthesis. matriz=handles5.Atributos+3]).MatrizCompleta([2:auxiliar1].txtCluster. colores=matriz(:.María Daniela Navas Padrón: 75.1) * 50. and you can change the structure %| during callbacks.txtMensaje. By default. Call guidata(h. Eje2=max(handles5.i).2))*1.151 - . Specify the extra arguments by editing the callback %| property in the inspector.

eventdata.'Enable'.Clusters(:.4).Atributos+3)==(i-1)). auxiliar=size(handles5.2).MatrizCompleta([2:auxiliar]. colores=matriz(:.txtCluster.'String'.handles5.2)).2). %deshabilito el boton si no hay mas tiempos siguientes if (i==handles5.2))*1.'Enable'.MatrizCompleta).cmdClusterAnterior. .axes1. auxiliar1=auxiliar1(1).'FontWeight'. medidas(auxiliar1)=50.cmdClusterAnterior.Atributos+3]). scatter(Clusters(:.María Daniela Navas Padrón: 75. end set(handles5.MatrizCompleta([2:auxiliar1]. auxiliar1=find(matriz(:.MatrizCompleta([2:auxiliar1]. else set(handles5. handles5.handles5.IntervalosTiempo. matriz=handles5. end hold off.626 Un modelo de Clustering Temporal Octubre 2004 %fin leyenda scatter(matriz(:. matriz=matriz(auxiliar.1).[1:handles5.medidas2. else set(handles5.CantClusters) set(handles5.'on').152 - . ylabel('Atributo 2').matriz(:. auxiliar=auxiliar(1).1). auxiliar1=size(handles5. % -------------------------------------------------------------------function varargout = cmdClusterAnterior_Callback(h.'bold'). end if (i==1) set(handles5. xlabel('Atributo 1'). set (handles5. Clusters=matriz(auxiliar1. auxiliar=size(matriz).Clusters([j:j+1].4). auxiliar=auxiliar(1).colores2).MatrizCompleta). auxiliar=find(handles5.:). medidas=10*ones(auxiliar.Atributos+1)==(i-1)).'off'). varargin) i = handles5. Eje1=max(handles5.cmdClusterSiguiente.i).'Enable'.i -1.IntervalosTiempo-1) line(Clusters([j:j+1]. guardo el nuevo i (para la proxima) handles5.1).'on').'off'). axis([0 Eje1 0 Eje2]).'Enable'. Eje2=max(handles5.colores).1.1) * 50.1. colores2=Clusters(:. %Dibujo primero los centroides medidas2 = ones(handles5. for j=1:(handles5. %cuando termino.:).medidas.handles5). guidata(gcbo.1))*1.1).MatrizCompleta([2:auxiliar].cmdClusterSiguiente.i = i.

'off'). guidata(gcbo.626 Un modelo de Clustering Temporal Octubre 2004 hold on.axes1. ylabel('Atributo 2').colores). leg=[]. %inserto la leyenda a='Tiempo-'.'on').2)). else set(handles5.b). %cuando termino.Clusters([j:j+1]. for j=1:(handles5. for k=1:handles5. . end legend(leg). end if (i==1) set(handles5. end set(handles5. %deshabilito el boton si no hay mas tiempos siguientes if (i==handles5.handles5).'Enable'.medidas.CantClusters) set(handles5.'on'). end hold off.cmdClusterAnterior.1).cmdClusterSiguiente. xlabel('Atributo 1').'Enable'.2).'FontWeight'.153 - .IntervalosTiempo b = num2str(k).i = i.c].'bold').matriz(:.'Enable'.cmdClusterSiguiente.María Daniela Navas Padrón: 75. else set(handles5.'off').1).cmdClusterAnterior. guardo el nuevo i (para la proxima) handles5.IntervalosTiempo-1) line(Clusters([j:j+1]. %fin leyenda scatter(matriz(:. leg=[leg.'Enable'. c= strcat(a.

and %| sets objects' callback properties to call them through the FEVAL %| switchyard above.CantClusters. .Atributos.fig % FIG = GRAFICOS3D launch Graficos3D GUI.'Color'.get(0.626 Un modelo de Clustering Temporal Octubre 2004 Graficos3D.Individuos = handlesAnt.MatrizCompleta. handles6).g.IntervalosTiempo. % FEVAL switchyard catch disp(lasterr). %| 'figure1_CloseRequestFcn'.0 16-May-2004 23:17:36 if nargin == 0 % LAUNCH GUI fig6 = openfig(mfilename.. handles6.i=0.Individuos. if nargout > 0 varargout{1} = fig6.154 - . handles6. handles6. %| %| EVENTDATA is empty. 'slider2_Callback'. 'axis1_ButtondownFcn'. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}).'reuse'). %| %| H is the callback object's handle (obtained using GCBO). %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H. e. %este i se va a usar para contar handles6. handles6. % GRAFICOS3D('callback_name'. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file. and store it. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'. guidata(fig6.Atributos = handlesAnt. set(fig6.) invoke the named callback. % Last Modified by GUIDE v2. HANDLES. handlesAnt = getappdata(1. EVENTDATA.MatrizCompleta = handlesAnt. This comment describes that mechanism. handles6 = guihandles(fig6).'handles').'defaultUicontrolBackgroundColor')). handles6.IntervalosTiempo = handlesAnt. % Generate a structure of handles to pass to callbacks.. %| %| HANDLES is a structure containing handles of components in GUI using .CantClusters = handlesAnt.María Daniela Navas Padrón: 75.m function varargout = Graficos3D(varargin) % GRAFICOS3D Application M-file for Graficos3D. but reserved for future use.

for k=(2+(i-1)*handles6.MatrizCompleta(k.'off').4)]. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA. handles. else % si no es -1 es centroide.155 - . auxiliar2 = find(matriz1 ~= -1). end end end auxiliar1=find(matriz1==-1). gcbo. colores2=[].MatrizCompleta(k.txtMensaje.handles6. handles6.MatrizCompleta(k. i = handles6. guidata(gcbo)) %| Add any extra arguments after the last argument. set (handles6. and you can change the structure %| during callbacks.MatrizCompleta([(2+(i1)*handles6.g. end end for k=(2+(i-1)*handles6. end end matriz1=handles6. y lo dibujo mas grande medidas = [medidas.4)~=-2) colores = [colores. eventdata. You can store additional information in %| this structure at GUI startup.figure1. %Dibujo primero los centroides matriz2 = []. GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'.626 Un modelo de Clustering Temporal Octubre 2004 %| tags as fieldnames.slider2.4)~=-2) %si es -2 lo excluyo if (handles6.Individuos):(i*handles6. Call guidata(h. for k=(2+(i-1)*handles6. handles6. e.MatrizCompleta(k. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. varargin) set(handles6.Individuos+1)].MatrizCompleta(k.Atributos])].10]. % -------------------------------------------------------------------function varargout = cmdTiempoSiguiente_Callback(h. handles.6)==-1) %si es -1 no es centroide medidas = [medidas.'String'.Atributos+3).Individuos):(i*handles6.50].MatrizCompleta(k.[1:handles6.Individuos+1) if (handles6. A copy of the structure %| is passed to each callback. By default. . before the final %| closing parenthesis. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates.Individuos):(i*handles6.txtTiempo.Individuos+1) if (handles6. handles6.i).i +1.4)~=-2) matriz = [matriz.'Visible'.María Daniela Navas Padrón: 75. Type "help guihandles" and "help guidata" for more %| information.Individuos+1) if (handles6. Specify the extra arguments by editing the callback %| property in the inspector. [].Individuos):(i*handles6.

varargin) i = handles6.'bold').3). scatter3(matriz(:.matriz2(:.i -1.txtTiempo.[1:handles6.CantClusters b = num2str(k).medidas2.matriz2(:. end if (i==1) set(handles6. end set(handles6.colores2).matriz(:.'off').Individuos) + auxiliar2(k).i = i. leg=[leg. leg=[]. else set(handles6.4)~=-2) matriz = [matriz. scatter3(matriz2(:.'off'). handles6.MatrizCompleta(k. xlabel('Atributo 1'). %Armo la leyenda con los centroides a='Cluster-'. .matriz(:. %cuando termino.Individuos+1) if (handles6.María Daniela Navas Padrón: 75.2).i). end %ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda colores2 = sort(colores2). guidata(gcbo. for k=(2+(i-1)*handles6.3).4)]. c= strcat(a.'FontWeight'.handles6).MatrizCompleta(k.'on').colores).1).'Enable'.axes1.Atributos])].CantClusters matriz2 = [matriz2. handles6. for k=1:handles6.cmdTiempoAnterior. zlabel('Atributo 3'). set (handles6.Individuos) + auxiliar2(k). handles6.1).medidas.b). ylabel('Atributo 2'). %deshabilito el boton si no hay mas tiempos siguientes if (i==handles6. hold on.cmdTiempoSiguiente.626 Un modelo de Clustering Temporal Octubre 2004 for k=1:handles6.cmdTiempoSiguiente. handles6. guardo el nuevo i (para la proxima) handles6.MatrizCompleta((1+(i-1)*handles6.'Enable'.2).IntervalosTiempo) set(handles6.MatrizCompleta((1+(i-1)*handles6. colores2 = [colores2. hold off.Individuos):(i*handles6.[1:handles6.'on').'String'.156 - .c]. eventdata.'Enable'.cmdTiempoAnterior.1) * 50. else set(handles6.CantClusters.'Enable'. medidas2 = ones(handles6. % -------------------------------------------------------------------function varargout = cmdTiempoAnterior_Callback(h. end legend(leg).Atributos])].

i = i. leg=[].4)~=-2) colores = [colores. handles6.Atributos])].626 Un modelo de Clustering Temporal Octubre 2004 end end for k=(2+(i-1)*handles6. colores2=[]. medidas = []. hold on.3).157 - .50].CantClusters b = num2str(k).MatrizCompleta([(2+(i1)*handles6.b). %Dibujo primero los centroides matriz2 = []. handles6. end %ordeno colores2 sino me dibuja en cualquier orden y pone mal la leyenda colores2 = sort(colores2). colores2 = [colores2. handles6. scatter3(matriz2(:.1) * 50. hold off.4)~=-2) %si es -2 lo excluyo if (handles6. end end matriz1=handles6.María Daniela Navas Padrón: 75. guardo el nuevo i (para la proxima) handles6.Individuos) +auxiliar2(k).MatrizCompleta((1+(i-1)*handles6.medidas2. else % si no es -1 es centroide. auxiliar2 = find(matriz1 ~= -1).MatrizCompleta(k.10].MatrizCompleta(k.medidas.Atributos+3).CantClusters matriz2 = [matriz2.matriz(:.matriz2(:. leg=[leg.Individuos+1) if (handles6. end end end auxiliar1=find(matriz1==-1).colores2).3).Individuos+1)]. end legend(leg).[1:handles6.CantClusters.MatrizCompleta((1+(i-1)*handles6.2).matriz(:. %Armo la leyenda con los centroides a='Cluster-'.MatrizCompleta(k. for k=1:handles6.6)==-1) %si es -1 no es centroide medidas = [medidas.Individuos):(i*handles6.c].Individuos):(i*handles6.handles6.matriz2(:. . for k=1:handles6.4)]. c= strcat(a.1).1).Individuos):(i*handles6.Individuos) + auxiliar2(k). y lo dibujo mas grande medidas = [medidas. %cuando termino.4)].2). scatter3(matriz(:.Individuos+1) if (handles6. medidas2 = ones(handles6.colores). for k=(2+(i-1)*handles6.MatrizCompleta(k.

cmdTiempoAnterior.'bold'). ylabel('Atributo 2').cmdTiempoSiguiente.'Enable'.IntervalosTiempo) set(handles6. %deshabilito el boton si no hay mas tiempos siguientes if (i==handles6.'Enable'.'Enable'.'FontWeight'.handles6).158 - .axes1.cmdTiempoAnterior.'on'). end if (i==1) set(handles6. else set(handles6.'on'). xlabel('Atributo 1').María Daniela Navas Padrón: 75. end set(handles6.'Enable'. zlabel('Atributo 3').'off').cmdTiempoSiguiente.'off').626 Un modelo de Clustering Temporal Octubre 2004 guidata(gcbo. . else set(handles6.

MatrizCompleta. %este i se va a usar para contar handles7.) invoke the named callback. .Individuos. This comment describes that mechanism.m function varargout = Graficos3DTiempo(varargin) % GRAFICOS3DTIEMPO Application M-file for Graficos3DTiempo.'handles').CantClusters = handlesAnt.Individuos = handlesAnt.MatrizCompleta = handlesAnt.626 Un modelo de Clustering Temporal Octubre 2004 Graficos3DTiempo. 'axis1_ButtondownFcn'. %| %| H is the callback object's handle (obtained using GCBO).0 16-May-2004 23:39:47 if nargin == 0 % LAUNCH GUI fig7 = openfig(mfilename. %| %| HANDLES is a structure containing handles of components in GUI using . handles7 = guihandles(fig7). %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H. handles7. handles7).CantClusters. HANDLES. %| 'figure1_CloseRequestFcn'. % GRAFICOS3DTIEMPO('callback_name'. %| %| EVENTDATA is empty. set(fig7. guidata(fig7.IntervalosTiempo. handles7. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}). handles7. and store it.g. 'slider2_Callback'.'defaultUicontrolBackgroundColor')). handles7.María Daniela Navas Padrón: 75.'reuse'). e. if nargout > 0 varargout{1} = fig7. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'.IntervalosTiempo = handlesAnt. % Generate a structure of handles to pass to callbacks. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file.i=0. handlesAnt = getappdata(1. % FEVAL switchyard catch disp(lasterr).get(0. % Last Modified by GUIDE v2.. but reserved for future use.159 - . and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. handles7..Atributos.'Color'. EVENTDATA.Atributos = handlesAnt.fig % FIG = GRAFICOS3DTIEMPO launch Graficos3DTiempo GUI.

You can store additional information in %| this structure at GUI startup. This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA.[1:handles7. auxiliar=size(matriz).IntervalosTiempo-1) line(Clusters([j:j+1]. auxiliar=auxiliar(1). handles.1).Clusters([j:j+1]. gcbo. %fin leyenda scatter3(matriz(:.'String'.figure1. By default. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. A copy of the structure %| is passed to each callback.1) * 50. GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'.2). Clusters=matriz(auxiliar1.3)). auxiliar1=size(handles7.handles7.g. % -------------------------------------------------------------------function varargout = cmdClusterSiguiente_Callback(h.160 - . hold on. matriz=matriz(auxiliar.'Visible'. before the final %| closing parenthesis.MatrizCompleta). for k=1:handles7. colores=matriz(:. .i). handles.Clusters(:.3).c]. handles7. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. colores2=Clusters(:.:).MatrizCompleta([2:auxiliar1]. varargin) set(handles7.5).medidas. Call guidata(h.matriz(:. and you can change the structure %| during callbacks. i = handles7. auxiliar1=auxiliar1(1).Clusters(:.colores2).626 Un modelo de Clustering Temporal Octubre 2004 %| tags as fieldnames. for j=1:(handles7. %inserto la leyenda a='Tiempo-'. leg=[].'off').Clusters([j:j+1]. auxiliar=find(handles7.txtCluster.b).2). c= strcat(a. end legend(leg). medidas=10*ones(auxiliar.1).Atributos+3)==(i-1)). Type "help guihandles" and "help guidata" for more %| information. set (handles7.slider2.2).Atributos+2).Atributos+1)==(i-1)). guidata(gcbo)) %| Add any extra arguments after the last argument.handles7.txtMensaje.colores).handles7. leg=[leg.IntervalosTiempo b = num2str(k).matriz(:. auxiliar1=find(matriz(:. Specify the extra arguments by editing the callback %| property in the inspector. eventdata. []. medidas(auxiliar1)=50. matriz=handles7. %Dibujo primero los centroides medidas2 = ones(handles7. e.i +1. scatter3(Clusters(:.:).1).MatrizCompleta([2:auxiliar1].María Daniela Navas Padrón: 75.1).Atributos+3]).medidas2.IntervalosTiempo.3).

cmdClusterAnterior. guidata(gcbo. varargin) i = handles7. auxiliar=find(handles7.2). c= strcat(a.:). else set(handles7. guardo el nuevo i (para la proxima) handles7. xlabel('Atributo 1').'String'.cmdClusterAnterior.IntervalosTiempo b = num2str(k).CantClusters) set(handles7.'bold').c].Atributos+1)==(i-1)). % -------------------------------------------------------------------function varargout = cmdClusterAnterior_Callback(h.María Daniela Navas Padrón: 75.handles7.IntervalosTiempo. eventdata. auxiliar1=size(handles7. colores=matriz(:. end set(handles7.'Enable'.[1:handles7. leg=[leg. colores2=Clusters(:. medidas(auxiliar1)=50. %inserto la leyenda a='Tiempo-'.:).5).'Enable'.Clusters(:.'on').MatrizCompleta([2:auxiliar1].MatrizCompleta([2:auxiliar1].'off'). auxiliar=auxiliar(1).1).axes1.i-1.Atributos+3]). end if (i==1) set(handles7.txtCluster.cmdClusterSiguiente. %cuando termino.colores2). matriz=handles7.'FontWeight'.handles7.1).3).cmdClusterSiguiente.626 Un modelo de Clustering Temporal Octubre 2004 end hold off.handles7). medidas=10*ones(auxiliar. auxiliar=size(matriz).'Enable'. auxiliar1=auxiliar1(1).'off'). ylabel('Atributo 2').medidas2.'Enable'. end . Clusters=matriz(auxiliar1.'on').1) * 50. leg=[].Atributos+3)==(i-1)). auxiliar1=find(matriz(:. zlabel('Atributo 3'). else set(handles7. matriz=matriz(auxiliar.Atributos+2). set (handles7. %deshabilito el boton si no hay mas tiempos siguientes if (i==handles7. handles7.b).i = i.i). %Dibujo primero los centroides medidas2 = ones(handles7. scatter3(Clusters(:.161 - .Clusters(:. for k=1:handles7.handles7. hold on.MatrizCompleta).

626 Un modelo de Clustering Temporal Octubre 2004 legend(leg).'off').Clusters([j:j+1].'off').IntervalosTiempo-1) line(Clusters([j:j+1].3). %cuando termino. for j=1:(handles7.cmdClusterSiguiente. %fin leyenda scatter3(matriz(:.axes1.cmdClusterAnterior.'bold'). %deshabilito el boton si no hay mas tiempos siguientes if (i==handles7.cmdClusterAnterior.1).'Enable'.colores). else set(handles7.'on'). end hold off.cmdClusterSiguiente.matriz(:. guardo el nuevo i (para la proxima) handles7.162 - .2).'FontWeight'.matriz(:.3)).medidas.'Enable'. end set(handles7. end if (i==1) set(handles7.'Enable'. .María Daniela Navas Padrón: 75.'Enable'. ylabel('Atributo 2').Clusters([j:j+1].1).2). else set(handles7. guidata(gcbo. zlabel('Atributo 3').'on'). xlabel('Atributo 1').handles7).CantClusters) set(handles7.i = i.

%| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H.IntervalosTiempo = handlesAnt.IntervalosTiempo.Atributos = handlesAnt.. HANDLES.0 15-May-2004 16:12:12 if nargin == 0 % LAUNCH GUI fig3 = openfig(mfilename. % Last Modified by GUIDE v2.fig % FIG = ATRIBUTOS launch Atributos GUI. handles3. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'. and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. % Generate a structure of handles to pass to callbacks.i=0.Individuos = handlesAnt. %| %| EVENTDATA is empty. guidata(fig3. % FEVAL switchyard catch disp(lasterr). % ATRIBUTOS('callback_name'. and store it.MatrizCompleta. e. %| %| H is the callback object's handle (obtained using GCBO).MatrizCompleta = handlesAnt. but reserved for future use. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}). handles3. set(fig3. handles3.get(0.g.CantClusters. %este i se va a usar para contar handles3.'handles'). This comment describes that mechanism.María Daniela Navas Padrón: 75. %| %| HANDLES is a structure containing handles of components in GUI using . 'slider2_Callback'.. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file. %| 'figure1_CloseRequestFcn'.'defaultUicontrolBackgroundColor')). 'axis1_ButtondownFcn'. . handles3.) invoke the named callback.'Color'. handles3). handles3. EVENTDATA.'reuse'). handlesAnt = getappdata(1.Atributos.Individuos.CantClusters = handlesAnt.163 - . handles3 = guihandles(fig3). if nargout > 0 varargout{1} = fig3.626 Un modelo de Clustering Temporal Octubre 2004 Atributos.m function varargout = Atributos(varargin) % ATRIBUTOS Application M-file for Atributos.

[1:handles3.'Enable'. end if (i==1) set(handles3.Atributos) set(handles3. auxiliar1=auxiliar1(1). end set(handles3.cmdAtributoSiguiente.626 Un modelo de Clustering Temporal Octubre 2004 %| tags as fieldnames. eventdata.txtMensaje.:. Type "help guihandles" and "help guidata" for more %| information.cmdAtributoAnterior. GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'.Atributos]).'String'.'on'). auxiliar1=size(handles3.handles3).'Enable'. xlabel('Tiempo').'off').cmdAtributoSiguiente.'Enable'. i = handles3. before the final %| closing parenthesis.i = i.IntervalosTiempo.handles3. %| %| VARARGIN contains any extra arguments you have passed to the %| callback. A copy of the structure %| is passed to each callback.[1:handles3. guardo el nuevo i (para la proxima) handles3.Atributos+3)==(j-1)). [].'on'). handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. matriz=handles3. matriz1=matriz(auxiliar.MatrizCompleta([2:auxiliar1].'bold'). guidata(gcbo)) %| Add any extra arguments after the last argument. % -------------------------------------------------------------------function varargout = cmdAtributoSiguiente_Callback(h. guidata(gcbo.'Visible'. Centroides=zeros(handles3. end end plot(Centroides(:. %cuando termino. Call guidata(h. e.'off'). else set(handles3.j.handles3. handles3.CantClusters. set (handles3. Centroides(:.txtAtributo.figure1.Atributos+3]).'Enable'.MatrizCompleta). .i +1.CantClusters auxiliar=find(matriz(:. Specify the extra arguments by editing the callback %| property in the inspector.Atributos). and you can change the structure %| during callbacks. gcbo. varargin) set(handles3.IntervalosTiempo for j=1:handles3. handles. ylabel('Atributo').'off').María Daniela Navas Padrón: 75.axes1.i).:)=matriz1.i)). You can store additional information in %| this structure at GUI startup. handles. By default.164 - . This %| structure is created at GUI startup using GUIHANDLES and stored in %| the figure's application data using GUIDATA.cmdAtributoAnterior. for k=1:handles3.slider2. else set(handles3. %deshabilito el boton si no hay mas tiempos siguientes if (i==handles3.g.'FontWeight'.handles3.

cmdAtributoSiguiente. leg=[].CantClusters b = num2str(k).i = i.c].Atributos) set(handles3. leg=[].j.IntervalosTiempo for j=1:handles3.'on').axes1. Centroides(:.txtAtributo. c= strcat(a.'Enable'.handles3. end legend(leg).handles3.b). end set(handles3. auxiliar1=auxiliar1(1).MatrizCompleta).i)).MatrizCompleta([2:auxiliar1].handles3).i). end if (i==1) set(handles3.cmdAtributoSiguiente.CantClusters auxiliar=find(matriz(:. ylabel('Atributo').'off').'FontWeight'.Atributos).María Daniela Navas Padrón: 75.'Enable'. else set(handles3. % -------------------------------------------------------------------function varargout = cmdAtributoAnterior_Callback(h. leg=[leg. matriz=handles3. Centroides=zeros(handles3. %cuando termino. leg=[leg. else set(handles3.cmdAtributoAnterior.:)=matriz1.'Enable'. guardo el nuevo i (para la proxima) handles3.'off'). eventdata.handles3. for k=1:handles3. end end plot(Centroides(:.CantClusters.[1:handles3. set (handles3. guidata(gcbo.c].Atributos]).:.626 Un modelo de Clustering Temporal Octubre 2004 a='Cluster-'.165 - . %deshabilito el boton si no hay mas tiempos siguientes if (i==handles3.'on'). matriz1=matriz(auxiliar. for k=1:handles3. for k=1:handles3. auxiliar1=size(handles3.CantClusters b = num2str(k). c= strcat(a. varargin) i = handles3.[1:handles3.IntervalosTiempo.b).'String'.Atributos+3]).'bold').Atributos+3)==(j-1)).cmdAtributoAnterior. handles3. a='Cluster-'. end .'Enable'.i -1. xlabel('Tiempo').

166 - .María Daniela Navas Padrón: 75. .626 Un modelo de Clustering Temporal Octubre 2004 legend(leg).

if nargout > 0 varargout{1} = fig4.María Daniela Navas Padrón: 75. % FEVAL switchyard catch disp(lasterr).CantClusters = handlesAnt. handles4. and store it.g. %| %| H is the callback object's handle (obtained using GCBO).figure1.i=0. % Generate a structure of handles to pass to callbacks. 'slider2_Callback'. %| %| EVENTDATA is empty. .CantClusters.IntervalosTiempo = handlesAnt. This comment describes that mechanism. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}).626 Un modelo de Clustering Temporal Octubre 2004 Estadisticas.Atributos. e. and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. e.Individuos = handlesAnt. but reserved for future use.m function varargout = Estadisticas(varargin) % ESTADISTICAS Application M-file for Estadisticas.MatrizCompleta = handlesAnt. handles. %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H.167 - .MatrizCompleta.fig % FIG = ESTADISTICAS launch Estadisticas GUI. %| %| HANDLES is a structure containing handles of components in GUI using %| tags as fieldnames.g. handles4. set(fig4.Atributos = handlesAnt. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'. handles. % Last Modified by GUIDE v2. handles4.IntervalosTiempo.'handles'). guidata(fig4. % ESTADISTICAS('callback_name'..'defaultUicontrolBackgroundColor')).'reuse'). handlesAnt = getappdata(1. %este i se va a usar para contar handles4.get(0.slider2. 'axis1_ButtondownFcn'.'Color'. This %| structure is created at GUI startup using GUIHANDLES and stored in . handles4).) invoke the named callback. handles4. HANDLES.Individuos. %| 'figure1_CloseRequestFcn'. handles4. EVENTDATA.. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file.0 15-May-2004 17:06:49 if nargin == 0 % LAUNCH GUI fig4 = openfig(mfilename. handles4 = guihandles(fig4).

GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'.Individuos)]. By default.k)= GraficoBarras(matriz1(j)*handles4.i)'. % -------------------------------------------------------------------function varargout = cmdTiempoSiguiente_Callback(h. auxiliar1=size(handles4.'String'.txtTiempoOrigen.Individuos if ((matriz1(j) == -2) & (matriz2(j) ~= -2)) %Esta operacion va en el otro grafico else if ((matriz1(j) ~= -2) & (matriz2(j) == -2)) %Esta operación va en el otro gráfico else %los 2 tiempos son distintos de -2 if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2)) GraficoBarras(matriz1(j)*handles4.CantClusters.(handles4.k)+1. end end end end end GraficoAuxiliar=zeros(handles4. for j=1:handles4.CantClusters+1):j*handles4.IntervalosTiempo1)). handles4. GraficoAuxiliar(j.CantClusters+matriz2(j)+1. auxiliar1=auxiliar1(1). set (handles4. GraficoBarras(matriz1(j)*handles4. %| %| VARARGIN contains any extra arguments you have passed to the %| callback.:)=GraficoBarras([((j-1)* handles4.'String'.IntervalosTiempo-1) matriz1=matriz([(1+(k-1)*handles4.i).CantClusters+matriz2(j)+1.Atributos+2]). i = handles4.CantClusters].CantClusters+matriz2(j)+1. end bar3(GraficoAuxiliar).txtTiempoDestino.k)+1. GraficoBarras=zeros(handles4.CantClusters).'Visible'. .i +1. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates. and you can change the structure %| during callbacks. matriz2=matriz([(1+(k)*handles4.1).Individuos):(k*handles4.CantClusters+matriz2(j)+1.k)= GraficoBarras(matriz1(j)*handles4. gcbo. Specify the extra arguments by editing the callback %| property in the inspector. varargin) set(handles4.'off').MatrizCompleta([2:auxiliar1].txtMensaje. before the final %| closing parenthesis. []. guidata(gcbo)) %| Add any extra arguments after the last argument.María Daniela Navas Padrón: 75.i+1).CantClusters*handles4.Individuos].626 Un modelo de Clustering Temporal Octubre 2004 %| the figure's application data using GUIDATA. matriz=handles4. Call guidata(h.[handles4.1). Type "help guihandles" and "help guidata" for more %| information.CantClusters. for k=1:(handles4.168 - . You can store additional information in %| this structure at GUI startup.MatrizCompleta).Individuos):(k+1)*handles4. eventdata. set (handles4. for j=1:handles4. A copy of the structure %| is passed to each callback.Atributos+1:handles4.

1). for k=1:(handles4. auxiliar1=size(handles4.IntervalosTiempo -1)) set(handles4.169 - .Individuos):(k+1)*handles4.'String'. end set(handles4.1).IntervalosTiempo1)).CantClusters+matriz2(j)+1.i+1).cmdTiempoSiguiente. auxiliar1=auxiliar1(1).CantClusters+matriz2(j)+1. end if (i==1) set(handles4.'on'). for j=1:handles4. varargin) i = handles4.[handles4.cmdTiempoAnterior. else set(handles4.k)+1.i = i.handles4).CantClusters.'off'). matriz=handles4. else set(handles4.Individuos):(k*handles4.cmdTiempoAnterior. xlabel('Cluster Final').'off'). GraficoBarras(matriz1(j)*handles4.'on'). matriz2=matriz([(1+(k)*handles4.CantClusters.MatrizCompleta).Individuos)].CantClusters).CantClusters*handles4.i -1.txtTiempoDestino.Atributos+1:handles4.'Enable'.'Enable'.María Daniela Navas Padrón: 75.'FontWeight'.:)=GraficoBarras([((j-1)* .'bold'). set (handles4. set (handles4.(handles4.k)= GraficoBarras(matriz1(j)*handles4.626 Un modelo de Clustering Temporal Octubre 2004 %cuando termino.'String'. guardo el nuevo i (para la proxima) handles4.k)= GraficoBarras(matriz1(j)*handles4. % -------------------------------------------------------------------function varargout = cmdTiempoAnterior_Callback(h. handles4.IntervalosTiempo-1) matriz1=matriz([(1+(k-1)*handles4. GraficoBarras=zeros(handles4. %deshabilito el boton si no hay mas tiempos siguientes if (i==(handles4. eventdata.CantClusters+matriz2(j)+1.CantClusters+matriz2(j)+1. for j=1:handles4.'Enable'.txtTiempoOrigen.Individuos if ((matriz1(j) == -2) & (matriz2(j) ~= -2)) %Esto va en el otro grafico else if ((matriz1(j) ~= -2) & (matriz2(j) == -2)) %esto va en el otro grafico else %los 2 tiempos son distintos de -2 if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2)) GraficoBarras(matriz1(j)*handles4. GraficoAuxiliar(j.Atributos+2]).MatrizCompleta([2:auxiliar1].Individuos].i).'Enable'. ylabel('Cluster Inicial'). end end end end end GraficoAuxiliar=zeros(handles4.axes1.k)+1. guidata(gcbo.cmdTiempoSiguiente.

i)'.cmdTiempoSiguiente.cmdTiempoSiguiente.'bold').cmdTiempoAnterior.axes1.170 - . else set(handles4. guidata(gcbo.CantClusters]. else set(handles4. ylabel('Cluster Inicial').'off'). . end bar3(GraficoAuxiliar).626 Un modelo de Clustering Temporal Octubre 2004 handles4.'on').CantClusters+1):j*handles4.María Daniela Navas Padrón: 75. end if (i==1) set(handles4.'on'). %deshabilito el boton si no hay mas tiempos siguientes if (i==(handles4.handles4). end set(handles4.'Enable'. xlabel('Cluster Final').'Enable'. %cuando termino. guardo el nuevo i (para la proxima) handles4.'off').'Enable'.i = i.'FontWeight'.'Enable'.cmdTiempoAnterior.IntervalosTiempo -1)) set(handles4.

.MatrizCompleta = handlesAnt. handles8 = guihandles(fig8). .g. %| 'figure1_CloseRequestFcn'.Atributos = handlesAnt. % FEVAL switchyard catch disp(lasterr). %este i se va a usar para contar handles8.m function varargout = Perdidos(varargin) % PERDIDOS Application M-file for Estadisticas.626 Un modelo de Clustering Temporal Octubre 2004 Perdidos.CantClusters = handlesAnt. %| %| H is the callback object's handle (obtained using GCBO). % Last Modified by GUIDE v2. This %| structure is created at GUI startup using GUIHANDLES and stored in . handles8).CantClusters. e.figure1.'handles'). set(fig8.i=0.slider2.fig % FIG = PERDIDOS launch Estadisticas GUI. handles. handles.0 15-May-2004 17:06:49 if nargin == 0 % LAUNCH GUI fig8 = openfig(mfilename. handles8.get(0. %| %| Each callback subfunction declaration has the following form: %| <SUBFUNCTION_NAME>(H.MatrizCompleta.Individuos = handlesAnt. and store it. handles8.. EVENTDATA. guidata(fig8.171 - . handlesAnt = getappdata(1.'Color'.IntervalosTiempo. % PERDIDOS('callback_name'.) invoke the named callback.IntervalosTiempo = handlesAnt.Individuos. and %| sets objects' callback properties to call them through the FEVAL %| switchyard above. e.'reuse').g. handles8. handles8.Atributos.María Daniela Navas Padrón: 75. end end %| ABOUT CALLBACKS: %| GUIDE automatically appends subfunction prototypes to this file. HANDLES. % Generate a structure of handles to pass to callbacks. %| %| EVENTDATA is empty. VARARGIN) %| %| The subfunction name is composed using the object's Tag and the %| callback type separated by '_'. 'slider2_Callback'. but reserved for future use. handles8. end elseif ischar(varargin{1}) % INVOKE NAMED SUBFUNCTION OR CALLBACK try [varargout{1:nargout}] = feval(varargin{:}). This comment describes that mechanism. 'axis1_ButtondownFcn'. %| %| HANDLES is a structure containing handles of components in GUI using %| tags as fieldnames.'defaultUicontrolBackgroundColor')). if nargout > 0 varargout{1} = fig8.

Individuos):(k*handles8. GUIDE sets the property to: %| <MFILENAME>('<SUBFUNCTION_NAME>'. matriz=handles8. gcbo.txtTiempoDestino. end end end end end GraficoAuxiliar=zeros(handles8.Individuos].CantClusters +1) + matriz2(j)+1. varargin) set(handles8. i = handles8.'off'). auxiliar1=auxiliar1(1). eventdata. matriz2=matriz([(1+(k)*handles8.k)=GraficoPerdidos(matriz1(j)* (handles8.:)=GraficoPerdidos([((j-1)* .IntervalosTiempo-1)). [].txtTiempoOrigen. A copy of the structure %| is passed to each callback.k)= GraficoPerdidos(matriz1(j)* (handles8. before the final %| closing parenthesis. else %los 2 tiempos son distintos de -2 if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2)) GraficoPerdidos(matriz1(j)* (handles8.i+1).CantClusters)* (handles8.MatrizCompleta). % -------------------------------------------------------------------function varargout = cmdTiempoSiguiente_Callback(h.i +1.k)+1.k)+1. handles8. Call guidata(h. for j=1:handles8.CantClusters + 1).1). else if ((matriz1(j) ~= -2) & (matriz2(j) == -2)) GraficoPerdidos(matriz1(j)* (handles8.[handles8.María Daniela Navas Padrón: 75. GraficoAuxiliar(j.CantClusters+matriz2(j)+1.CantClusters+matriz2(j)+1. Type "help guihandles" and "help guidata" for more %| information. auxiliar1=size(handles8.(handles8.Individuos if ((matriz1(j) == -2) & (matriz2(j) ~= -2)) GraficoPerdidos((handles8.k)=GraficoPerdidos((handles8.txtMensaje.172 - .'Visible'.MatrizCompleta([2:auxiliar1].i). set (handles8. By default. Specify the extra arguments by editing the callback %| property in the inspector.IntervalosTiempo-1) matriz1=matriz([(1+(k-1)*handles8.CantClusters +1) +handles8.CantClusters+1.626 Un modelo de Clustering Temporal Octubre 2004 %| the figure's application data using GUIDATA.CantClusters +1) +matriz2(j)+1. GraficoPerdidos = zeros((handles8.CantClusters +1)* (handles8. for k=1:(handles8. and you can change the structure %| during callbacks.'String'.k)= GraficoBarras(matriz1(j)*handles4. for j=1:(handles8.CantClusters + 1).Individuos)].CantClusters + 1).CantClusters)* (handles8.Atributos+1:handles8. You can store additional information in %| this structure at GUI startup. guidata(gcbo)) %| Add any extra arguments after the last argument. GraficoBarras(matriz1(j)*handles4. set (handles8. handles) after changing your %| copy to replace the stored original so that subsequent callbacks see %| the updates.CantClusters + 1) + matriz2(j)+1.k)+1.CantClusters + 1) + matriz2(j)+1.CantClusters +1) + handles8.Individuos):(k+1)*handles8. %| %| VARARGIN contains any extra arguments you have passed to the %| callback.Atributos+2]).1).k)+1.CantClusters+1.'String'.

Atributos+1:handles8.'Enable'.c). % -------------------------------------------------------------------function varargout = cmdTiempoAnterior_Callback(h.IntervalosTiempo-1) matriz1=matriz([(1+(k-1)*handles8.1).CantClusters+1).'off'). else set(handles8.cmdTiempoSiguiente. matriz2=matriz([(1+(k)*handles8.173 - . %deshabilito el boton si no hay mas tiempos siguientes if (i==(handles8.Individuos].'String'.CantClusters+1)+1):j*(handles8.i)'. end bar3(GraficoAuxiliar).CantClusters+matriz2(j)+1. ley = strcat(ley.txtTiempoDestino. %cuando termino.i = i.CantClusters+matriz2(j)+1.626 Un modelo de Clustering Temporal Octubre 2004 (handles8.k)+1. eventdata.CantClusters+1).CantClusters+1)].k)= GraficoBarras(matriz1(j)*handles4. auxiliar1=size(handles8.Atributos+2]).'String'. %Eje y a= 'Cluster Inicio('.cmdTiempoSiguiente.i+1). end if (i==1) set(handles8.Individuos if ((matriz1(j) == -2) & (matriz2(j) ~= -2)) . c='=Sin Cluster)'.cmdTiempoAnterior.axes1.Individuos):(k*handles8. c='=Sin Cluster)'.cmdTiempoAnterior.i). set (handles8.1). for k=1:(handles8. b=num2str(handles8. else set(handles8.'on'). GraficoBarras(matriz1(j)*handles4.Individuos):(k+1)*handles8. auxiliar1=auxiliar1(1). end set(handles8. GraficoPerdidos = zeros((handles8.María Daniela Navas Padrón: 75. for j=1:handles8.b).CantClusters + 1). varargin) i = handles8. xlabel(ley).txtTiempoOrigen. guidata(gcbo. set (handles8. guardo el nuevo i (para la proxima) handles8.handles8).(handles8.MatrizCompleta).'FontWeight'.i -1.'bold').'Enable'.b). b=num2str(handles8.'on'). matriz=handles8.Individuos)].'Enable'. ylabel(ley). ley = strcat(a.[handles8.IntervalosTiempo-1)).c). handles8.'Enable'. ley = strcat(ley.IntervalosTiempo -1)) set(handles8.CantClusters +1)* (handles8. %Eje x a= 'Cluster Final('.'off'). ley = strcat(a.MatrizCompleta([2:auxiliar1].

ley = strcat(a.CantClusters)* (handles8. %deshabilito el boton si no hay mas tiempos siguientes if (i==(handles8.c). guidata(gcbo.'off').CantClusters +1) +matriz2(j)+1.k)=GraficoPerdidos(matriz1(j)* (handles8.k)=GraficoPerdidos((handles8.CantClusters+1)]. ley = strcat(ley. b=num2str(handles8. else %los 2 tiempos son distintos de -2 if ((matriz1(j) ~= -2) & (matriz2(j) ~= -2)) GraficoPerdidos(matriz1(j)* (handles8.IntervalosTiempo -1)) set(handles8. b=num2str(handles8. .'off'). ley = strcat(ley.k)+1.'Enable'.CantClusters+1). c='=Sin Cluster)'.cmdTiempoAnterior. else set(handles8. ylabel(ley). end set(handles8.'FontWeight'. else if ((matriz1(j) ~= -2) & (matriz2(j) == -2)) GraficoPerdidos(matriz1(j)* (handles8.'bold').626 Un modelo de Clustering Temporal Octubre 2004 GraficoPerdidos((handles8.'Enable'.i)'.c). GraficoAuxiliar(j. for j=1:(handles8.CantClusters+1).:)=GraficoPerdidos([((j1)*(handles8. ley = strcat(a.k)+1.CantClusters + 1).CantClusters +1) + matriz2(j)+1. guardo el nuevo i (para la proxima) handles8. c='=Sin Cluster)'.handles8). end bar3(GraficoAuxiliar).i = i.'Enable'.CantClusters + 1) + matriz2(j)+1.b). end end end end end GraficoAuxiliar=zeros(handles8.174 - .CantClusters + 1).cmdTiempoSiguiente.'on'). %cuando termino.CantClusters +1) + handles8. %Eje y a= 'Cluster Inicio('.CantClusters+1.CantClusters+1.cmdTiempoAnterior.axes1.María Daniela Navas Padrón: 75.CantClusters + 1) + matriz2(j)+1.cmdTiempoSiguiente.'Enable'. else set(handles8. end if (i==1) set(handles8.k)=GraficoPerdidos(matriz1(j)* (handles8.k)+1. xlabel(ley).CantClusters+1)+1):j*(handles8.CantClusters +1) +handles8.CantClusters)* (handles8.'on').b). %Eje x a= 'Cluster Final('.

Además contiene el archivo weka.java) se encuentran en este directorio.arff preparados para ser utilizados con la aplicación weka. Ejemplos: contiene archivos *.175 - .jar.4. que indica la Unidad Temporal correspondiente.arff que ya fueron filtrados con CreateTemporalUnits. o Con UnidadesTemporales: contiene archivos *.jar.María Daniela Navas Padrón: 75. Estructura del CD de instalación Weka: Weka 3.626 Un modelo de Clustering Temporal Octubre 2004 A3 Instructivo de Instalación y Manual de Usuario A3. Por lo tanto. Análisis Resultados: contiene los fuentes y ejecutables que hay que utilizar para visualizar los resultados del clustering. Tesis: contiene el presente documento de la tesis. Código Fuente Weka: para ver el código fuente de Weka.1: contiene los archivos necesarios para instalar el programa Weka estándar. Instructivo de instalación: contiene el instructivo de instalación. Matlab: Matlab 6. A estos archivos se les puede aplicar directamente el proceso de clustering temporal. Para poder aplicarle a estos archivos el proceso de clustering temporal es necesario antes aplicarles el filtro CreateTemporalUnits.arff que tienen como atributos Fecha de Inicio y Fecha de Fin en cada registro. por lo que en lugar de tener los atributos Fecha de Inicio y Fecha de Fin tienen un único atributo Temp. hay que descomprimir el archivo weka-scr. Esta carpeta contiene dos subidrectorios: o Con Fechas: contiene archivos *. Los nuevos archivos implementados (*. cómo se explica en el manual de uso. CACIC 2004: contiene el paper sobre Clustering Temporal que se presentó en el X Congreso Argentino de Ciencias de la Computacion. es necesario tener configuradas las dos aplicaciones para poder apreciar todas las funcionalidades del mismo.1 Instructivo de Instalación El software que realiza el Clustering Temporal se divide en dos partes.0: contiene los archivos necesarios para instalar el programa Matlab. Ejemplos: contiene archivos *.csv que son resultados de procesos de clustering realizados anteriormente. una realizada en Weka y la otra en Matlab. . que incluye las modificaciones agregadas a dicho programa en esta implementación.

txt).1 del CD. 4) Copiar los archivos de Weka\Ejemplos en un directorio a elección (este paso es optativo. y REEMPLAZARLOS por los archivos del mismo nombre en directorio Weka\Weka 3. .626 Un modelo de Clustering Temporal Octubre 2004 Instalación de Weka 1) Ejecutar el archivo weka-3-4-1jre. 5) Ejecutar el archivo RunWeka. pero en caso de fallar la instalación (depende de la versión de Windows instalada). Ingresar a la opción Explorer.0\Setup.exe (el número de serie se encuentra en el archivo serial. 3) Copiar los archivos de Matlab\Ejemplos a un directorio de su elección (este paso es optativo. que se encuentra en Weka\Weka 3. el instalador solicita insertar el CD con los archivos del Help. se puede acceder a los archivos de ejemplo directamente desde el CD). Instalación de Matlab 1) Ejecutar el archivo de instalación en Matlab\MatLab 6. también se debe instalar el JRE desde el archivo j2re-1_4_2_05-windows-i586-p. dichos archivos no se encuentran en el CD por lo que es necesario Cancelar la instalación en este punto. se puede acceder a los archivos de ejemplo directamente desde el CD). 4) Ejecutar el archivo <matlabR12>\bin\win32\matlab.exe para abrir la aplicación (o desde el menú Inicio de Windows).1.4. o de tener problemas al momento de ejecutar el programa Weka.María Daniela Navas Padrón: 75. y seguir las instrucciones. 2) Copiar la carpeta Matlab\Análisis Resultados y todo su contenido a un directorio de su elección.4).bat en el directorio en donde se instaló Weka (generalmente C:\Archivos de Programa\Weka 3.bat para abrir el programa Weka (o ejecutarlo desde el Menù Inicio). Cuando se ejecutó aproximadamente el 70 % de la instalación. 2) El archivo anterior también instala el JRE (Java RunTime Enviroment) necesario para ejectutar la aplicación.176 - . y seguir las instrucciones.exe (instalador de Weka).jar y RunWeka.exe 3) Buscar los archivos weka.4.

María Daniela Navas Padrón: 75. la carpeta “Analisis Resultados” Figura A3.1 .1.177 - .626 Un modelo de Clustering Temporal Octubre 2004 5) Elegir como directorio de trabajo .

2 . Figura A3.178 - .626 Un modelo de Clustering Temporal Octubre 2004 6) En la ventana de comandos tipear Resultados.1. y automáticamente se ejecuta la aplicación.María Daniela Navas Padrón: 75.

2 Manual de Usuario Como ya se indicó anteriormente el proceso de clustering temporal consta de 2 etapas: la generación del archivo temporal y el Clustering temporal propiamente dicho. Una vez abierto el archivo. donde los datos de entrada se dividen en grupos o clusters.María Daniela Navas Padrón: 75. según su unidad de tiempo. abrir un archivo *. Para ello hay que elegir el filtro en Filter\Unsupervised\Attribute\CreateTemporalUnits .1 A este archivo hay que aplicarle el Filtro “CreateTemporalUnits”. etc. El formato del archivo debe cumplir con las normas para los archivos arff y además cada registro debe tener un atributo que lo identifique y un rango de tiempo en el que sean válidos sus atributos especificados.179 - .2.arff. cantidad de instancias. se mostrarán en el Panel de Preproceso las características del mismo (Cantidad y tipo de atributos. Generación del archivo temporal En el panel de Preproceso.) Figura A3.626 Un modelo de Clustering Temporal Octubre 2004 A3.

PosId: Posición del atributo que indica el ID del registro. Reemplaza a los rangos de las fechas. En lugar de tener Fecha Inicio Fecha Fin Los registros tienen los atributos: Temp: es un número entero que va de 0 a la cantidad de intervalos que se hayan elegido. por medio de este parámetro se indica con qué precisión tratar las fechas.María Daniela Navas Padrón: 75. . PosFechaFin: Posición del atributo que indica la Fecha de Fin. o se puede Guardar el archivo (mediante el botón SAVE). NumIntervalos: Cantidad de intervalos en los que se desea dividir el período completo. Los valores posibles son: • 1 : Año • 2: Mes • 3: Día • 4: Hora • 5: Minuto • 6: Segundo Luego de configurar los parámetros. y a veces esto no es necesario. Una vez aplicado el filtro.2. se observará que se actualiza el encabezado de los atributos.2 Es importante configurar bien los parámetros del filtro para que el proceso realice lo que se espera de él. Los parámetros del filtro son: • • • • • PosFechaIni : Posición del atributo que indica la Fecha de Inicio. eligiendo nombre y ubicación del mismo. Cuando termina de procesar. Chronon: esta es la unidad de medida.180 - . se debe aplicar el filtro mediante el botón Apply.626 Un modelo de Clustering Temporal Octubre 2004 Figura A3. se puede trabajar con el clustering temporal. Como las fechas tienen precisión hasta milisegundos. cargándolo en otra oportunidad para trabajar directamente sin necesidad de aplicar el filtro.

María Daniela Navas Padrón: 75.3 Luego de aplicado el filtro los registros del archivo arff quedan de la siguiente forma: . que se guarda en el directorio en donde corre la aplicación.181 - . indicando a que intervalo de tiempo real equivale cada unidad de tiempo Temp.2.626 Un modelo de Clustering Temporal Octubre 2004 Este proceso genera automáticamente un archivo llamado IntervalosTiempo.txt. A continuación se muestra un ejemplo de dicho archivo: Intervalo de tiempo perteneciente a la unidad temporal 0 Desde: Mon Mar 01 00:00:00 ART 2004 Hasta: Sun Mar 07 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 1 Desde: Mon Mar 08 00:00:00 ART 2004 Hasta: Sun Mar 14 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 2 Desde: Mon Mar 15 00:00:00 ART 2004 Hasta: Sun Mar 21 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 3 Desde: Mon Mar 22 00:00:00 ART 2004 Hasta: Sun Mar 28 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 4 Desde: Mon Mar 29 00:00:00 ART 2004 Hasta: Sun Apr 04 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 5 Desde: Mon Apr 05 00:00:00 ART 2004 Hasta: Sun Apr 11 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 6 Desde: Mon Apr 12 00:00:00 ART 2004 Hasta: Sun Apr 18 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 7 Desde: Mon Apr 19 00:00:00 ART 2004 Hasta: Sun Apr 25 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 8 Desde: Mon Apr 26 00:00:00 ART 2004 Hasta: Sun May 02 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 9 Desde: Mon May 03 00:00:00 ART 2004 Hasta: Sun May 09 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 10 Desde: Mon May 10 00:00:00 ART 2004 Hasta: Sun May 16 00:00:00 ART 2004 Intervalo de tiempo perteneciente a la unidad temporal 11 Desde: Mon May 17 00:00:00 ART 2004 Hasta: Sun May 23 00:00:00 ART 2004 Figura A3.

2.4 En el directorio donde corre la aplicación. Si por el particionamiento elegido existe más de un registro para el mismo ID. También se puede aplicar en forma complementaria cualquier otro filtro definido en WEKA. por ejemplo.182 - .626 Un modelo de Clustering Temporal Octubre 2004 • • • • • Existen tantas Unidades Temporales (UT) como intervalos de tiempo se parametrizaron. para cada UT. se genera automáticamente un archivo con el nombre del archivo ingresado + _C + Nro de Clusters + _T + Nro de Unidades Temporales. Al finalizar. Este algoritmo sólo tiene un parámetro que indica la cantidad de clusters que se desean generar. se crea un registro “vacío” o “perdido”. se debe elegir el algoritmo Temporal_k_D_Median. instancias. Si por el particionamiento elegido en alguna UT no existe ningún registro con determinado ID. Cada UT tiene la misma cantidad de registros o individuos. Clustering temporal En la solapa de Clustering. El filtro CreateTemporalUnits se puede aplicar tantas veces como se desee al archivo origen. con . se muestra en la pantalla lateral un resumen de cuáles son los individuos centroides de cada cluster. En los resultados finales se puede apreciar el comportamiento de estos registros. se repite en cada UT. El mismo registro. con el mismo ID aunque con valores de atributos distintos (o no). Al presionar el botón START comienza el proceso de clustering. los mismos se conjugan en un solo registro.María Daniela Navas Padrón: 75. Figura A3. para filtrar atributos. generando distintas salidas según la configuración de los parámetros. etc.

183 - . Estos archivos contienen toda la información necesaria para la visualización de los resultados mediante Matlab. Figura A3.626 Un modelo de Clustering Temporal Octubre 2004 extensión csv (Por ej. Análisis de Resultados Una vez cargado el programa.csv).María Daniela Navas Padrón: 75. presionar el botón Abrir y elegir un archivo de resultados (*.csv).5 A continuación se habilitarán o deshabilitarán los botones según las características del archivo elegido: . NombreArchivo_C4_T6.2.

Figura A3.María Daniela Navas Padrón: 75.626 Un modelo de Clustering Temporal Octubre 2004 Cluster 2D: Sólo se habilita si el archivo de entrada tiene 2 atributos.184 - .2.6 . Se muestra gráficamente la representación de los clusters en cada UT.

Se muestra gráficamente la evolución de cada cluster a través de las distintas UT. Figura A3.626 Un modelo de Clustering Temporal Octubre 2004 Cluster 2 D Tiempo: Solo se habilita si el archivo de entrada tiene 2 atributos.2.María Daniela Navas Padrón: 75.7 .185 - .

María Daniela Navas Padrón: 75.2.8 .626 Un modelo de Clustering Temporal Octubre 2004 Cluster 3 D: Sólo se habilita si el archivo de entrada tiene 3 atributos. Figura A3.186 - . Se muestra gráficamente la representación de los clusters en cada UT.

626 Un modelo de Clustering Temporal Octubre 2004 Cluster 3 D Tiempo: Sólo se habilita si el archivo de entrada tiene 3 atributos.María Daniela Navas Padrón: 75.9 . Figura A3.187 - . Se muestra gráficamente la evolución de cada cluster a través de las distintas UT.2.

2. y a su vez la comparación del mismo atributo en los distintos clusters.626 Un modelo de Clustering Temporal Octubre 2004 Análisis por Atributo: esta opción está habilitada siempre. Muestra atributo por atributo.María Daniela Navas Padrón: 75.188 - . la evolución del centroide del cluster a través del tiempo.10 . Figura A3.

626 Un modelo de Clustering Temporal Octubre 2004 Estadísticas: Este es un gráfico de barras.189 - .2.María Daniela Navas Padrón: 75. que muestra cuántos individuos cambiaron de cluster en el pasaje de un tiempo al siguiente. y Cluster Destino indica la cantidad de individuos que tienen esos clusters en el tiempo siguiente.11 . Figura A3. Cluster Origen muestra la cantidad de individuos para cada cluster en un determinado tiempo.

María Daniela Navas Padrón: 75. Cortar. También poseen un Menú.12 Operación en cada Figura Las pantallas que se abren al presionar los botones de la pantalla principal poseen el mismo comportamiento. los individuos que pertenecían a algún cluster en un tiempo dado. que habilita una barra de herramientas que permite ampliar. Una opción interesante es Menu Tools. Pegar. Tienen 2 botones ==> y <== . leyendas.2. Y también se puede editar la figura agregando etiquetas. etc. reducir o girar los gráficos. Copiar. según corresponda. con opciones generales como Guardar. para trasladarse a través de las distintas UT o los distintos clusters.Edit Plot. y no pertenecen a ninguno en el tiempo siguiente. Imprimir. .190 - .626 Un modelo de Clustering Temporal Octubre 2004 Individuos Perdidos: Muestra en un gráfico de barras. Figura A3.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->