12 febrero 2013

TALLY TABLE: una excelnte alternativa a ciclos en SQL

Este post lo voy a dedicar a una alternativa poco conocida a la utilización de los ciclos en SQL, la TALLY TABLE. Como siempre en mis post no me gusta dar toda la información, en la red hay demasiada información como para repetir lo mismo una y otra vez. La intención es dar a conocer el uso de este recurso y fomentar la investigación y la imaginación.

Ciclos; en algún momento de nuestro trabajo debemos de utilizarlos ya que son una estructura de programación básica. Pero en consultas SQL no siempre son la mejor opción al momento de codificar una rutina, podrían ralentizar nuestro proceso, tal vez en escenarios con pocos datos todo marche sobre ruedas, pero al momento de realizar pruebas con altos volúmenes de información puede afectarnos gravemente. Alternativas, bueno pues en realidad depende mucho de lo que se vaya a realizar, pero una muy buena son las TALLY TABLES.

Bueno, y a todo esto que son las TALLY TABLE. Las TALLY TABLE son tablas que cuentan con una sola columna, la cual se recomienda indexar. En esta columna se ingresan números en forma ordenada a partir de 0 o 1, hasta un número que nos sea de utilidad. Ejemplo: si trabajaremos con una rutina que necesite recorrer todos los caracteres de un campo varchar, deberíamos de llenarla del 1 hasta el 8000, que es el número máximo de valores que puede ser ingresado en este campo con este tipo de datos, no es recomendable llenarla de más.

Basta de rollo y vamos a la acción.

Antes de ejemplificar como emplear estas tablas debemos de crearlas y llenarlas. En Internet hay muchos recursos en los cuales están documentados como crear de manera muy eficiente estas tablas, aquí les dejo una, igual y se les ocurre una forma mejor.


Para llenarla podríamos utilizar un ciclo, pero ¿qué no es lo que estamos tratando de evitar? por lo tanto vamos a llenarla utilizando un CROSS JOIN

SELECT TOP 8000 --cantidad de caracteres máximo en un campo varchar
     IDENTITY(INT,1,1) AS N
INTO dbo.Tally
FROM Master.dbo.SysColumns sc1,
    Master.dbo.SysColumns sc2

Agregamos el indice cluster a la tabla.

ALTER TABLE dbo.Tally
ADD CONSTRAINT PK_Tally_N
PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100


Listo, ya tenemos nuestra tabla llena, vamos a ponerla en práctica y a compararla con un ciclo normal.

Ejemplo 1

Obtener las posiciones de un caracter en especifico en una cadena

Primero hagamoslo con un ciclo normal


DECLARE @Variable VARCHAR(8000)
SET @Variable = ',Elemento01,Elemento02,Elemento03,Elemento04,Elemento05,'
DECLARE @N INT
SET @N = 1      

WHILE @N <= LEN(@Variable)
  BEGIN
      IF SUBSTRING(@Variable,@N,1) = ','
         BEGIN
               SELECT @N, SUBSTRING(@Variable,@N,1)
         END
           SET @N = @N + 1
  END


Si analizamos el proceso veremos que el select se ejecuta 6 veces, una vez por cada coma que se encuentre en la cadena. Ahora hagamos el ejemplo con una TALLY TABLE.


DECLARE @Variable VARCHAR(8000)
SET @Variable = ',Elemento01,Elemento02,Elemento03,Elemento04,Elemento05,'

 SELECT N, SUBSTRING(@Variable,N,1)
   FROM dbo.Tally
  WHERE N <= LEN(@Variable)
    AND SUBSTRING(@Variable,N,1) = ','
  ORDER BY N


Con esta solución solamente ejecutamos el select una sola vez. La tabla se utiliza para recorrer cada uno de los caracteres del parámetro y despliega las filas que contienen el carácter buscado.

Ejemplo 2

Hagamos con esto algo más interesante, realicemos el split de la cadena separada por comas.

DECLARE @Variable VARCHAR(8000)
SET @Variable = 'Elemento01,Elemento02,Elemento03,Elemento04,Elemento05'
set @Variable = ',' + @Variable + ','

SELECT SUBSTRING(@Variable,N+1,CHARINDEX(',',@Variable,N+1)-N-1)
FROM dbo.Tally
WHERE N < LEN(@Variable)
AND SUBSTRING(@Variable,N,1) = ',' 

Ejemplo 3

Si con este ejemplo no quedamos convencidos les invito a hacer uno con más registros y veremos la magia.

Les voy a ayudar un poco, les dejo el ejemplo con la TALLY TABLE, les queda hacer el ejemplo con un While, que no creo que batallen y comparen el tiempo


DECLARE @Variable VARCHAR(8000)
SET @Variable = 'Elemento01,Elemento02,Elemento03,Elemento04,Elemento05,'
SET @Variable = REPLICATE('Element01,Element02,Element03,Element04,Element05,',159)
set @Variable = ',' + @Variable 
SELECT SUBSTRING(@Variable,N+1,CHARINDEX(',',@Variable,N+1)-N-1)
FROM dbo.Tally
WHERE N < LEN(@Variable)
AND SUBSTRING(@Variable,N,1) = ',' 


¿Muy impresionante no? No tarda ni un segundo, la TALLY TABLE realmente ayuda a realizar más rápido este tipo de procesos. ¿Tienen alguna aplicación para una TALLY TABLE? ponganlo en los comentarios y compartan con los demás.

Espero les haya gustado este post y les sea de utilidad.

Si les gusta compartenlo.

Hasta la próxima semana.

Carlos E. Rodríguez

02 febrero 2013

CROSS APPY SQL 2005 Y 2008

El día de hoy comparto con ustedes una instrucción de SQL Server 2005 que me ha sido de mucha ayuda al momento de crear tablas compuestas: CROSS APPLY.

La finalidad de este articulo es mostrar algunas de sus aplicaciones, dando oportunidad al lector investigar a fondo la instrucción. Al final del articulo dejo algunas ligas de interés con más información al respecto.

Como habremos de imaginar por su nombre, la instrucción CROSS APPLY nos permite crear una tabla compuesta (un set de resultados combinando columnas de dos o más tablas ).

La principal caracteristica de esta instrucción a diferencia de las instrucciones JOIN (CROSS JOIN, INNER JOIN, OUTER JOIN) es que nos permite generar una tabla compuesta a partir de una tabla y una función de tipo tabla.

¿Y esto para que me sirve dirían muchos?, pues de bastante, pongo un ejemplo bastante sencillo que creo que se demostrará la capacidad de esta instrucción.

Ejemplo


Tabla: ModificacionesFactura
Factura FechaCreacion FechaCorte
1001 10/10/2012 10/10/2011
1001 11/10/2012 10/10/2013
1003 12/10/2012 10/10/2012

Supongamos que necesitamos obtener la fecha menor entre el campo FechaCreacion y el campo FechaCorte:

Para lograrlo podríamos hacer algo así


select Factura,
case when FechaCreacion < FechaCorte then FechaCreacion
else FechaCorte end FechaMenor
From ModificacionesFactura
Hasta aquí todo bien, sin problemas. Ahora a poner una pequeña traba, ¿qué pasa si queremos hacer algo más con la FechaMenor que acabamos de obtener?, como por ejemplo saber la diferencia de días entre el día de hoy y la fecha menor. En este caso tendríamos que repetir la instrucción para obtener de nuevo la fecha menor y obtendríamos algo como esto:


select Factura
case when FechaCreacion &lt FechaCorte then FechaCreacion
else FechaCorte end FechaMenor,
DATEDIFF(dd,case when FechaCreacion < FechaCorte then FechaCreacion
else FechaCorte end FechaMenor, GETDATE()) Diferencia
From ModificacionesFactura

Alternativa con CROSS APPLY

Con el uso de CROSS APPLY podríamos reducir la consulta anterior de esta manera:


SELECT Factura,
FechaMenor,
DATEDIFF(dd, A.FechaMenor, GETDATE()) Diferencia
FROM ModificacionesFactura
CROSS APPLY
(
     SELECT case when FechaCreacion < FechaCorte then FechaCreacion            
     else FechaCorte end FechaMenor
) A

De esta manera queda más limpio nuestro SELECT ya que pasamos al cálculo de la fecha menor al CROSS APPLY. Incluso podemos utilizar el campo A.FechaMenor en la clausula Group By directamente lo cual, de otra manera nos llevaría muchas más lineas de código.

La instrucción CROSS APPLY ejecuta para cada  registro de la tabla, la función de tipo tabla que especificamos. En este caso la función regresa un solo registro para cada registro de la tabla, pero podría darse el caso en el que regrese más de uno. Incluyo una liga donde se puede ver el ejemplo fácilmente:

http://www.sqlteam.com/article/using-cross-apply-in-sql-server-2005


Limpiando todavía más la consulta

Esta instrucción puede quedar todavía más limpia si pasamos la lógica para obtener la fecha menor a una función de tipo tabla.

La cual podría quedar de la siguiente manera:


CREATE FUNCTION dbo.ObtenerFechaMenor(@Fecha1 as datetime, @Fecha2 as datetime)
RETURNS Table
AS
RETURN
SELECT case when @Fecha1 < @Fecha2 then @Fecha1
             else @Fecha2 end FechaMenor
GO 

Nuestro query podría quedar de la siguiente manera:


SELECT Factura,
            FechaMenor,
            DATEDIFF(dd, A.FechaMenor, GETDATE()) Diferencia
FROM ModificacionesFactura
CROSS APPLY dbo.ObtenerFechaMenor(FechaCreacion, FechaCorte) A

Alguien podría decir, ¿para que uso funciones definidas por el usuario si no son muy óptimas al momento de consultar grandes cantidades de registros?, y esto es verdad, pero un detalle interesante de la instrucción CROSS APPLY es que, las instrucciones dentro de la función se toman al generar el plan de ejecución de nuestro query, lo cual aumenta la velocidad de nuestra consulta en la mayoria de los casos. Cabe aclarar que siempre debemos realizar pruebas de desempeño comparando diversas opciones para que tengamos argumentos de porque realizamos la consulta de tal o cual manera.

Espero que les haya gustado este breve artículo y les haya dado curiosidad para investigar más acerca de esta instrucción. Para mi ha sido muy útil al momento de reutilizar y reducir código, algo que a veces en SQL Server es un poco complicado de hacer. 

Si les gusta compartan este articulo y dejen sus puntos de vista.

Hasta luego.

Carlos E. Rodríguez

ligas de interés:

http://geeks.ms/blogs/lfranco/archive/2011/09/26/funciones-escalares-en-tsql-joins-cross-apply-y-la-madre-que-pari-243-al-topo.aspx

http://social.msdn.microsoft.com/Forums/en/transactsql/thread/796821b0-ba48-49b4-ba42-1783061d8c41 

http://amby.net/2010/03/29/ejemplo-de-empleo-de-clausula-cross-aply-en-t-sql-2005-y-superior/ 

http://msdn.microsoft.com/es-es/library/ms175156%28v=sql.105%29.aspx 


17 diciembre 2010

Proyecto Final

En esta entrada publico que ya subí el vídeo en youtube.com mi proyecto final, el cual realiza un análisis del módulo de circulación del sistema CÓDICE, haciendo uso de las herramientas vistas en la materia "Sistemas de soporte a la toma de decisiones".

Espero les sea de utilidad.

Saludos.



15 diciembre 2010

Visualización de datos

Esta entrada esta dedicada a la visualización de datos.

La visualización es una herramienta importante para la toma de desciciones ya que nos permite comprender la información de una forma clara y más rapida, ver tendencias, factores anomalias o posibles problemas. Actualmente existen diversas herramientas para la visualisación de información, unas más potentes y flexibles que otras.

Para demostrar el uso de estas herramientas utilice el progama R para mostrar la información correspondiente a los prestamos realizados durante el año 2009 para cada una de las bibliotecas de la UANL que utilizan el sistema automatizado para realizar los prestamos. También utilice la información de la cantidad de material que contiene cada biblioteca.

En la siguiente gráfica podemos observar una gráfica de burbujas, en donde el tamaño de la burbuja representa la cantidad de material de la biblioteca en relación a las demas bibliotecas, cuanto más grande la burbuja más grande la cantidad de materiales que contiene. La altura de la burbuja (o sea el eje y) representa la cantidad de prestamos realizados en el año2009 por la biblioteca, este valor también se encuentra en el centro de la burbuja. El nombre de las bibliotecas los omití intencionalmente.



De la gráfica anterior podemos observar que las bibliotecas con mayor cantidad de materiales no son las que tienen mayor tráfico de prestamo de material, siendo una de las bibliotecas pequeñas la que tiene el mayor trafico de prestamos.

Les dejo la liga del articulo del cual tomé la información para realizar la gráfica

14 diciembre 2010

Algoritmos en línea

Los algoritmos en línea son aquellos en los cuales la información se va ingresando parte por parte, por lo que no se conoce toda la información y se debe de decir en el momento en el que llega la información lo que se va a hacer sin conocer las entradas futuras. Estos algoritmos a diferencia de los algoritmos fuera de línea, que si conocen toda la información del sistema desde un inicio, no garantizan que se encuentre una solución óptima. El estudio de estos algoritmos se centra en la calidad de la decisión tomada al momento de que llega información nueva.

Aplicación en sistemas de alarmas contra desastres naturales

La aplicación de algoritmos en línea para redes de señales de alarmas de desastres naturales podría ser la de buscar los caminos más rápidos a los nodos que todavía no se les ha informado la noticia considerando que algunos de los nodos pueden sufrir desperfectos o estar deshabilitados. Cuando se vaya visitando los nodos para informar la advertencia se podría analizar los nodos vecinos y tomar una decisión sobre cuál es la mejor opción y diseminar el mensaje más rápido.

Los algoritmos en línea considerados para resolver problemas de redes usan la idea de asociar con cada vínculo un costo que es exponencial a la fracción de la capacidad del vínculo asignado a los circuitos salientes. El costo asociado con un vínculo en la red puede ser visto como el valor a la variable dual asociada con el vínculo mismo. El algoritmo entonces enruta cada solicitud a un costo mínimo.

Algoritmos genéticos

Los algoritmos genéticos fueron creados asimilando el comportamiento de la evolución de los seres vivos la cual plantea que los seres con mejores cualidades o mejor adaptados son los que tienen mayor oportunidad de sobrevivir, y por lo tanto, de generar una mayor y mejor preparada descendencia. Los algoritmos genéticos caben dentro de la rama de la inteligencia artificial.
Los algoritmos genéticos están basados en probabilidad y pueden ayudarnos a encontrar soluciones en problemas que no tienen una función específica para su solución. Y su campo de uso es muy amplio.
El proceso que el algoritmo genético intenta imitar es el de la selección natural en el cual a partir de una muestra aleatoria de una población en donde los ejemplares, que son las posibles soluciones que se pueden dar al problema, con mejores características o mejor ponderados son los que tendrán mayor probabilidad de cruzarse. El resultado del cruce de estos individuos creará una generación con mejores características que sus ancestros, lo que en teoría deberá acercarnos cada vez más a una solución óptima. Este ciclo se repite cierta cantidad de veces hasta que se considere que se llega a una solución óptima. Algunos algoritmos evolutivos más complejos pueden irse mejorando conforme se vayan realizando las iteraciones para cada generación, lo que permite tener un algoritmo inteligente que va aprendiendo de acuerdo a su experiencia.
Es importante hacer notar que debemos de tener una función que nos deberá ponderar de manera efectiva cuales son los ejemplares con mejores cualidades, para que tengan una mejor oportunidad de crear nuevas generaciones. Estas funciones deberán de “castigar” las peores soluciones y “premiar” las mejores.
El algoritmo genético simple tiene la siguiente estructura:
BEGIN
                Generar una población inicial
                Computar la función de evaluación de cada individuo
                WHILE NOT Terminado DO
                BEGIN–producir una nueva generación
                               FOR Tamaño población
                               BEGIN    --ciclo reproductivo
                                    Seleccionar dos individuos de la generación anterior para el cruce
(probabilidad de selección proporcional a la función de evaluación del
individuo
Cruzar con cierta probabilidad los dos individuos obteniendo dos
descendientes
Mutar los dos descendientes con cierta probabilidad
Computar la función de los dos descendientes mutados
Insertar los dos descendientes mutados en la nueva población
                               END
                               IF la población ha convergido THEN
                                               Terminado = True
                               END IF
                END
END
La aplicación de los algoritmos evolutivos tienen las siguientes aplicaciones:
  • Diseño automatizado de equipo industrial
  • Diseño de sistemas de distribución de agua
  • Aprendizaje de comportamiento de robots
  • Optimización de estructuras moleculares
  • Predicción
  • Diseño de topología de redes computacionales
  • Problema del viajante
  • Etc.

Sistemas Expertos


Los sistemas expertos son llamados así porque emulan el comportamiento de un experto en un dominio concreto y en ocasiones son usados por éstos. Con los sistemas expertos se busca una mejor calidad y rapidez en las respuestas dando así lugar a una mejora de la productividad del experto.
Para nuestro interés un sistema experto es un conjunto de programas que, sobre una base de conocimientos, posee información de uno o más expertos en un área específica. 
Puede entenderse como una rama de la inteligencia artificial, donde el poder de resolución de un problema en un programa de computadora viene del conocimiento de un dominio específico. 
Estos sistemas imitan las actividades de un humano para resolver problemas de distinta índole (no necesariamente tiene que ser de inteligencia artificial). También se dice que un sistema experto se basa en el conocimiento declarativo (hechos sobre objetos, situaciones) y el conocimiento de control (información sobre el seguimiento de una acción).
Para que un sistema experto sea herramienta efectiva, los usuarios deben interactuar de una forma fácil, reuniendo dos capacidades para poder cumplirlo:
Explicar sus razonamientos o base del conocimiento: los sistemas expertos se deben realizar siguiendo ciertas reglas o pasos comprensibles de manera que se pueda generar la explicación para cada una de estas reglas, que a la vez se basan en hechos.
Adquisición de nuevos conocimientos: son mecanismos de razonamiento que sirven para modificar los conocimientos anteriores. Sobre la base de lo anterior se puede decir que los sistemas expertos son el producto de investigaciones en el campo de la inteligencia artificial ya que ésta no intenta sustituir a los expertos humanos, sino que se desea ayudarlos a realizar con más rapidez y eficacia todas las tareas que realiza.
Las tareas que realiza un sistema experto son:
Monitorización: La monitorización es un caso particular de la interpretación, y consiste en la comparación continua de los valores de las señales o datos de entrada y unos valores que actúan como criterios de normalidad o estándares
Diseño: Diseño es el proceso de especificar una descripción de un artefacto que satisface varias características desde un número de fuentes de conocimiento.
Planificación: La planificación es la realización de planes o secuencias de acciones y es un caso particular de la simulación. Está compuesto por un simulador y un sistema de control. El efecto final es la ordenación de un conjunto de acciones con el fin de conseguir un objetivo global.
Control: Un sistema de control participa en la realización de las tareas de interpretación, diagnóstico y reparación de forma secuencial. Con ello se consigue conducir o guiar un proceso o sistema.
Simulación: El empleo de los SE para la simulación viene motivado por la principal característica de los SE, que es su capacidad para la simulación del comportamiento de un experto humano, que es un proceso complejo.
Instrucción: Un sistema de instrucción realizara un seguimiento del proceso de aprendizaje. El sistema detecta errores ya sea de una persona con conocimientos e identifica el remedio adecuado, es decir, desarrolla un plan de enseñanza que facilita el proceso de aprendizaje y la corrección de errores.
Recuperación de información: Lo que diferencia a estos sistemas de un sistema tradicional de recuperación de información es que éstos últimos sólo son capaces de recuperar lo que existe explícitamente, mientras que un Sistema Experto debe ser capaz de generar información no explícita, razonando con los elementos que se le dan.
Una aplicación que puede utilizarse para el sistema de bibliotecas, específicamente en lo concerniente a los prestamos de materiales puede ser el pronosticar los días para poner a disposición del público los materiales que se encuentran en reserva, por ejemplo cuando hay mucha demanda de material y no tener que esperarse que los usuarios tengan que solicitar el material al encargado. Esto podría ayudar a prepararse con tiempo para estas situaciones al personal y el material con anticipación.
De la base de datos de préstamos del 2009 en la UANL generamos una gráfica junto con los intervalos donde se detecto que se necesitan sacar los materiales de reserva (3 intervalos encontrados), ya que los prestamos rebasan los 1900 prestamos diarios de acuerdo a la predicción obtenida mediante las dobles medias móviles con un intervalo de 3 valores hacia atrás.
De color azul podemos ver los prestamos reales y de color verde los intervalos donde se sugiere sacar los materiales de reserva.

Herramientas de minería de datos

En esta actividad revisaré la herramienta de código abierto KNIME para la minería de datos.

Knime es una herramienta de análisis, integración, procesamiento y de exploración de datos.
Esta herramienta permite trabajar mediante un modelo de flujo de trabajo, el cual, documenta y guarda el proceso de análisis en el orden en el que fue concebido e implementado, asegurando que los resultados intermedios estén siempre disponibles.

Las funcionalidades con las que cuenta Knime son:

Lectura y escritura de archivos y bases de datos

Manipulación de datos: pre procesamiento de los datos ingresados con filtros, agrupamiento, pivoteo, normalización, agregación, particionamiento, etc.
Vistas: Visualización de datos y resultados a través de varias vistas interactivas, permitiendo exploración de datos interactiva.

Minería: utiliza los datos del estado de la técnica como algoritmos de minería de la agrupación, inducción de reglas, árboles de decisión, reglas de asociación, Bayes ingenuo, redes neuronales, máquinas de vectores soporte, etc., para comprender mejor sus datos



Unas de las ventajas de Knime es que no es necesario instalar el paquete en la computadora, puede correr desde la carpteta donde se tengan los archivos de la aplicación. Lo que si puede ocasionar problemas es el manejo de la memoria, ya que para procesos complicados se necesita tener una buena capacidad en memoria RAM si no queremos que se inhiba la computadora.


A continuación dejo unos videos de cómo se utiliza la herramienta

Manipulación de imágenes

Esta entrada esta enfocada a la manipulación de imágenes. En mi caso me toco manipular las imágenes de manera que se pueda cambiar al color de una region en particular del mismo color.

Para realizar esto utilice la herramienta octave con el modulo image para la manipulación de imágenes.

Primero genere una matriz de 10 x 10 de ceros y unos de manera aleatoria mediante la siguiente instrucción:


Para representar esta matriz como una imagen utilice la siguiente instrucción
imgplot(y)
 
La cual genero la siguiente imagen:

Para realizar el cambio de color de una región seleccionada de la imagen, realice una rutina la cual esta compuesta por funciones

La primera es la función principal, la cual ejecuta las demás y devuelve la matriz ya modificada. La idea general de esta rutina es la de ir revisando los valores adyacentes al pixel indicado para revisar si es del mismo color que el principal, si es así le cambia el color y revisa los valores adyacentes a ese valor que se le acaba de cambiar el color. Esto lo realiza mediante funciones recursivas. A continuación dejo las funciones que genere:

function res = colorear(m,x,y)
#Funcion que cambia de color los pixeles adyacentes al indicado
#m es la matriz a la cual se le quiere manipular
#x es la fila del valor seleccionado para cambiar los valores adyacentes del mismo color
#y es la fila del valor seleccionado para cambiar los valores adyacentes del mismo color
z = m(x,y);
m = colorearsec(m,x,y,z);
res = m;
endfunction

function res = colorearsec(m,x,y,z)
#Función recursiva que cambia de color el pixel indicado y ejecuta las funciones para cambiar los adyacentes
m(x,y) = 3;
m = derecha(m,x,y,z);
m = abajo(m,x,y,z);
m = izquierda(m,x,y,z);
m = arriba(m,x,y,z);
res = m;
endfunction
function res = derecha(m,x,y,z)
#Función que cambia de color el pixel a la derecha del especificado
[x1,y1]= size(m);
if((y+1)
if(m(x,y+1)==z)
m(x,y+1)=3;
m = colorearsec(m,x,y+1,z);
endif
endif
res = m;
endfunction
function res = izquierda(m,x,y,z)
#Función que cambia de color el pixel a la izquierda del especificado
[x1,y1]= size(m);
if((y-1)>0)
if(m(x,y-1)==z)
m(x,y-1)=3;
m = colorearsec(m,x,y-1,z);
endif
endif
res = m;
endfunction
function res = abajo(m,x,y,z)
#Función que cambia de color el pixel a abajo del especificado
[x1,y1]= size(m);
if((x+1)
if(m(x+1,y)==z)
m(x+1,y)=3;
m = colorearsec(m,x+1,y,z);
endif
endif
res = m;
endfunction
function res = arriba(m,x,y,z)
#Función que cambia de color el pixel arriba del especificado
[x1,y1]= size(m);
if((x-1)>0)
if(m(x-1,y)==z)
m(x-1,y)=3;
m = colorearsec(m,x-1,y,z);
endif
endif
res = m;
endfunction

Al ejecutar la rutina para cambiar el color de los pixeles adyacentes al que se encuentra en la posición y(1,2) tenemos el siguiente resultado:

Como podemos observar los valores adyacentes al pixel seleccionado cambiaron al valor '3'.

Si graficamos esta matriz tenemos el siguiente resultado:


El problema que encontré con estas funciones es que como utiliza funciones recursivas es fácil que se llegue al limite de recursividad de la herramienta octave por lo que tendremos que aumentar este limite. Aun habiendo hecho esto la herramienta tiende a fallar cuando son muchas llamadas recursivas. Trate de solucionar este detalle creando rutinas que utilicen ciclos pero el proceso es muy lento. Como quiera dejo las rutinas creadas por si quieren darle un vistazo.

function res = colorear2(m,x,y)
z = m(x,y);
m(x,y) = 3;
[x1,y1] = size(m);
encontrado = 0;
do
encontrado = 0;
for i = 1:x1
for j = 1:y1
if (m(i,j)==z)
if ((derecha2(m,i,j,z) ==1)|(izquierda2(m,i,j,z)==1)|(arriba2(m,i,j,z)==1)|(abajo2(m,i,j,z)==1))
encontrado = 1;
m(i,j) = 3;
break;
endif
endif
endfor
if (encontrado == 1)
break;
endif
endfor
until encontrado == 0
res = m;
endfunction
function res = derecha2(m,x,y,z)
#Función que cambia de color el pixel a la derecha del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((y+1)
if(m(x,y+1)==3)
res = 1;
endif
endif
endif
endfunction
function res = izquierda2(m,x,y,z)
#Función que cambia de color el pixel a la izquierda del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((y-1)>0)
if(m(x,y-1)==3)
res = 1;
endif
endif
endif
endfunction
function res = abajo2(m,x,y,z)
#Función que cambia de color el pixel a abajo del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((x+1)
if(m(x+1,y)==3)
res = 1;
endif
endif
endif
endfunction
function res = arriba2(m,x,y,z)
#Función que cambia de color el pixel arriba del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((x-1)>0)
if(m(x-1,y)==3)
res = 1;
endif
endif
endif
endfunction


Datos anomalos

Esta entrada esta dedicada al estudio de anomalías en los conjuntos de datos
Un dato anómalo es aquel que se encuentra a una distancia anormal de los demás datos de una muestra aleatoria de datos. En este sentido la definición deja en manos del analista el decidir lo que considera anormal, para esto es necesario identificar los datos que se consideran normal.

Para el siguiente ejercicio utilice la base de datos de prestamos del sistema de bibliotecas de la UANL en el 2009.

Utilice para realizar los cálculos y las gráficas la herramienta Octave con el modulo outliers.

Para cargar los valores en una variable dentro de Octave utilice la siguiente instrucción:

x = csvread("/home/carlos/Documentos/Prestamos2009")

En la cual se almacena la matriz de los prestamos realizados en el 2009 en una columna y en otra el día en que se realizo el préstamo. Para nuestro estudio no nos interesa el día exacto en el que se realizo el préstamo, solo la cantidad de prestamos por día, por lo que solo utilizaremos la columna con los valores del préstamo.

Para graficar los prestamos realizados utilice la siguiente instrucción:

plot(x(:,2),'b*')

En la cual le indico a la herramienta que deseo graficar los valores de la segunda columna, que los ponga de color azul y que utilice el símbolo '*' para representar los valores en la gráfica

La gráfica de dispersión de los prestamos realizados en la UANL tienen el siguiente aspecto:


Para obtener el valor que se encuentra mas alejado del comportamiento normal de los demás, utilice la siguiente instrucción:

[out2] = outlier(x(:,2),0,0)

El cual arrojo el valor: 2405

con esta instrucción ya tengo cual es el valor mas alejado del comportamiento normal dentro del conjunto de datos, pero todavía no se en que posición se encuentra dentro del vector. Para solucionar esto utilizo la siguiente instrucción:

[out] = outlier(x(:,2),0,1)

La cual almacena en la variable “out” un vector con valores 0 y 1, en donde 0 significa que el dato almacenado en esa posición del vector inicial tienen comportamiento normal, a contraposición de los que tienen valor 1 (que en este caso solo envía un solo valor)

Para poder observar en la gráfica el punto que se considera anómalo, multiplico el vector resultante con el valor anómalo y lo guardo en un segundo vector con la siguiente instrucción:


out3 = out*out2

Ahora puedo graficar los dos vectores y observar cual es el dato anómalo dentro de la gráfica de dispersión utilizando la función Plot:

plot(x(:,2),'b*',out3,'r*')

La gráfica resultante muestra los valores dentro del conjunto de datos de color azul y el dato anómalo lo muestra de color rojo como se ve a continuación

12 diciembre 2010

Pronósticos de series


El objetivo de esta entrada es el investigar la generación de pronósticos a partir de una serie. La herramienta que utilice para generar estos pronósticos fue Dobles Medias móviles las cuales son más acertadas cuando el comportamiento de la variable que estudiamos tiene una tendencia variable. Esta herramienta utiliza como predicción del periódo T+1 el valor del periódo T más la media de los incrementos observados en la muestra (1,2,…T)
Esta técnica supone dos medias móviles. La primera sobre el valor original de la variable y la segunda sobre la media móvil simple. La primera calcula el periodo T y con la segunda obtenemos su incremento. La predicción para más allá de un periódo supone una perdida de información o el uso de predicciones.
Para obtener la media móvil la obtenemos de la siguiente formula:
Para obtener la segunda media móvil utilizamos la siguiente fórmula:
Para obtener la predicción la obtenemos de la siguiente fórmula:

Donde

Para obtener los errores de las predicciones se utilizaron las siguientes fórmulas:


A continuación muestro los resultados de las predicciones que obtuve con la los prestamos de libros registrados en el 2009 en la UANL. He eliminado los prestamos realizados los sábados ya que son muy pocos (máximo 250) en comparación con los que se realizan de lunes a viernes.
Para la generación de predicciones con medias móviles es necesario especificar la cantidad de valores anteriores que se tomarán en cuenta.
En la gráficas siguientes podremos observar de color azul los prestamos registrados en el sistema y de color rojo los valores generados mediante las dobles medias móviles.
En primer instancia realicé la prueba con 30 valores anteriores para generar las predicciones y obtuve los siguientes resultados:

Se puede observar que la predicción tiende a tener un comportamiento parecido a los valores reales pero con muy poca precisión.
Estos son los resultados de error que de esta prueba:

Error absoluto de la media (MAD)
14.5257978
Error absoluto porcentual de la media (MAPE)
0.28473171
Desviación porcentual absoluta de la media (PMAD)
0.00753047
Error cuadrático de la media (MSE)
386527.106
Raíz del error cuadrático de la media (RMSE)
621.713041


Para la segunda prueba reduje el número de valores a considerar para la predicción a 15 y obtuve los siguientes resultados:

Se puede observar que los valores pronosticados tienden a ser más precisos que la prueba anterior. En los valores de los errores se puede observar que el error absoluto de la media se incrementa pero los valores del error cuadrático de la media y la raíz del error cuadrático disminuyen.

Error absoluto de la media (MAD)
71.6742415
Error absoluto porcentual de la media (MAPE)
0.18077682
Desviación porcentual absoluta de la media (PMAD)
0.03715738
Error cuadrático de la media (MSE)
248015.863
Raíz del error cuadrático de la media (RMSE)
498.01191

Continué disminuyendo la cantidad de valores a considerar para generar la predicción a 10 y obtuve los siguientes resultados:


Se puede observar que los valores son todavía más cercanos a los valores reales que en la prueba anterior.
También el error cuadrático de la media disminuye:
Error absoluto de la media (MAD)
90.3441498
Error absoluto porcentual de la media (MAPE)
0.16649666
Desviación porcentual absoluta de la media (PMAD)
0.04683624
Error cuadrático de la media (MSE)
169679.553
Raíz del error cuadrático de la media (RMSE)
411.92178
Al generar las predicciones con 5 valores anteriores se obtuvo la siguiente gráfica:


A simple vista podría decirse que se ajusta muy bien a los valores reales pero al obtener los valores de los errores de la predicción se puede observar que son mayores que la prueba anterior, por lo que puede concluirse que la cantidad optima de valores a tomar para generar la predicción con este método para este caso está entre 5 y 10 valores.
Error absoluto de la media (MAD)
242.963291
Error absoluto porcentual de la media (MAPE)
0.30465659
Desviación porcentual absoluta de la media (PMAD)
0.16433797
Error cuadrático de la media (MSE)
198008.115
Raíz del error cuadrático de la media (RMSE)
444.981028

09 noviembre 2010

Síntesis del artículo "Graph Clustering" de Satu Elisa Schaeffer

A continuación muestro una síntesis del articulo Graph Clustering de Satu Elisa Schaeffer
Al inicio del artículo se definen conceptos básicos necesarios para el entendimiento del articulo como los son complejidad computacional, algoritmos de aproximación, teoría de grafos y cadenas de Markov.
Definición de tareas de clustering de grafos discutiendo diferentes definiciones de clusterings y clusters
La partición de grafos significa minimizar la cantidad de bordes que cruzan de un grupo de vértices a otro.
No hay una definición única de clúster en un grafo. Al crear un grafo cada clúster debe de estar conectado de manera intuitiva: esto significa que debe de haber por lo menos uno, preferentemente varios caminos conectando cada para de vértices en un clúster. Si un vértice 'x' no puede ser alcanzado por un vértice 'y' no deben de estar agrupados en un mismo clúster. Además cada camino debe de ser interno al clúster: además del conjunto de vértices C que es conectada en G, la sub grafo inducido por C se debe conectar en sí mismo, es decir, que no es suficiente para dos vértices v y u en C para ser
conectados por un camino que pasa por los vértices de V \ C, sino también necesitan estar conectados por un camino que sólo visite vértices incluidos en C.
Como consecuencia, cuando el clustering de un gráfico desconectado con componentes conocidos, la agrupación por lo general debe ser conectado a cada componente por separado, a menos que se imponga una restricción global.
Definición de mediciones de similaridad
Hay dos enfoques principales para la identificación de un clúster:
Calculando algunos valores de los vértices y clasificar los vértices en grupos sobre la base de los valores obtenidos, o calcular una medida de la aptitud en el conjunto de posibles clúster y luego elegir entre el conjunto de clúster candidatos que optimizan la medida utilizada
Algoritmos globales de clustering
En un clustering global cada vértice del grafo de entrada es asignado a un clúster en el método de salida, tal como en un clúster local, las asignaciones en el clúster realizadas desde un cierto subgrupo de vértices, comúnmente un solo vértice.
Métodos locales
El clustering local se refiere a guardar el grafo en formato que permite acceder a los sub grafos conectados o a listas de adyacencia de vértices cercanos, lo que permite calcular los clúster uno a la vez basado en vistas parciales de la topología del grafo. Esto permite realizar cálculos imposibles a colecciones muy grandes de datos.
Algunas aplicaciones de clustering de grafos son las siguientes:
<!--[if !supportLists]--> <!--[endif]-->Identificar estructuras relevantes y analizar la conectividad para el modelamiento u optimización estructural.
<!--[if !supportLists]--> <!--[endif]-->Optimización de software como los servicios de chat
<!--[if !supportLists]--> <!--[endif]-->Diseño estructural de redes de sensores
<!--[if !supportLists]--> <!--[endif]-->Agrupar información en bases de datos de manera óptima

11 octubre 2010

Proyecto - Sistemas de soporte para la toma de decisiones

Buen día a todos,

Mi proyecto para la materia "Sistemas de soporte para la toma de decisiones" es la de tomar la información relacionada a los prestamos, devoluciones y renovaciones de libros contenida en la base de datos del sistema CÓDICE y utilizarla para generar información relevante que sea de ayuda a los directores y responsables de las diferentes bibliotecas de la UANL.

Que tengan un excelente día.

Reseña del libro Data warehousing fundamentals: a comprehensive guide for IT Professionals

Buen día a todos, a continuación les presento una breve reseña del libro Data warehousing fundamentals: a comprehensive guide for IT Professionals. Este libro está enfocado a los profesionales de TI que quieren adentrarse en la mineria de datos y conocer desde las bases a hasta su implementación y mantenimiento. El libro busca tomar los temas más importantes sin enfatizar mucho en todos los puntos. Es importante notar que este libro no es para cualquier persona que quiera solamente saber un poco más sobre el tema, está enfocado a profesionales de la informática ya que demana un conocimiento previo de diferentes temas. El objetivo de este libro es servir como un primer encuentro con la mineria de datos y los conceptos fundamentales en el desarrollo de herramientas de este tipo. El autor deja claro que puede ser utilizado como material de consulta para un curso sobre mineria de datos y da la pauta para profundizar en temas más especificos. En lo que alcance a observar me parece que el libro lleva un buen ritmo y no se apresura a tocar conceptos complejos sin antes dar una buena base. Me parece buena la propuesta de llevar el avance de los capitulos como tal y como llevamos el flujo de trabajo en nuestros proyecto, empezando por la planeación y dieseño, pasando por el desarrollo hasta implementación y mantenimiento de las herramientas. Espero que esta breve reseña les sea de utilidad si buscan información sobre la mineria de datos o si consideran adquirir este libro. La información que utilice para realizar la reseña la pueden encontrar en la siguiente liga: http://books.google.com.mx/books?id=n2nIM0l1TQ0C&printsec=frontcover#v=onepage&q&f=false


Que tengan un excelente día.