lunes, 24 de febrero de 2014

Creando un UserType de hibernate que se aplique a todas las entidades.

Hibernate posee un mecanismo muy potente para controlar la manera en que ocurre la conversion de valores obtenidos de la fuente de datos a valores Java. Se trata de los UserTypes. Por ejemplo, si utilizas una Base de Datos muy antigua que mantiene siempre al final de cada cadena espacios en blanco hasta rellenar la longitud de la columna, mediante un UserType puedes redefinir la manera en que la cadena es leida de la base de datos y escrita en el String de destino de Java. Para manipular dicho proceso basta con implementar una clase heredera que redefina algunos métodos y dejar que el framework realice el resto

package es.hib.usertype;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

public class TrimmedString implements UserType {

public TrimmedString() {
super();
}

@Override
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}

@Override
public Class returnedClass() {
return String.class;
}

@Override
public boolean equals(Object x, Object y) throws HibernateException {
return (x == y) || (x != null && y != null && (x.equals(y)));
}

@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
return new String((String) value);
}

@Override
public boolean isMutable() {
return false;
}

@Override
public Object assemble(Serializable cached, Object owner) throws

 HibernateException {
return cached;
}

@Override
public Serializable disassemble(Object obje) throws 

HibernateException {
return (Serializable) obje;
}

@Override
public int hashCode(Object obje) throws HibernateException {
return obje.hashCode();
}

@Override
public Object nullSafeGet(ResultSet rs, String[] names, 

SessionImplementor arg2, Object owner) throws HibernateException,
SQLException {

String val = rs.getString(names[0]);

if (null == val) {

return (null);
}
return val.trim();
}

@Override
public void nullSafeSet(PreparedStatement st, Object value, 

int index, SessionImplementor arg3) throws HibernateException,
SQLException {
st.setString(index, (String) value);
}

@Override
public Object replace(Object original, Object target, Object owner) 

throws HibernateException {

return original;
}
}

Ya teniendo el UserType implementado puede decidirse si usarse localmente

@Type(type="es.hib.usertype.TrimmedString")
@Column(name = "DESCRIPCION")
private String descripcion;

o globalmente, o sea, aplicarlo a la conversion de todos los VARCHAR en String de la aplicación. Para esto se debe crear en el paquete que contiene las entidades el siguiente archivo package-info.java. El mismo es una anotación a nivel de paquetes que surtirá el mismo efecto que si se anotaran una a una todas las clases del paquete dado.

@org.hibernate.annotations.TypeDef(name = "trimmedString", 
defaultForType = String.class, typeClass = TrimmedString.class)
package es.hib.entities;

import es.hib.usertype.TrimmedString;

Después de creado el package-info.java, ya solo se necesita que hibernate lo note. Para esto debe de agregarse,  programaticamente cuando se esten cargando las configuraciones añadir la siguiente sentencia.

configuration.addPackage("es.hib.entities")


domingo, 9 de febrero de 2014

Concept Net

ConceptNet es una base de conocimiento de sentido común integrada con un paquete de herramientas de lenguaje natural, concebido en el Instituto tecnológico de Massachusetts por [Liu y Singh, 2004]. El término sentido común se utiliza para expresar la manera en que fue y es construido dicho recurso. El mismo se basa en el proyecto Open Mind Common Sense que posee un sitio en Internet en el que cualquier persona puede definir en su propio idioma, hechos o relaciones, sobre los conceptos que desee, en forma de rellenado la línea, por ejemplo: “The effect of Eating food is_______”. Como puede notarse, el sitio brinda a los usuarios una oración con una estructura definida por ellos y la persona debe llenar el espacio aportando su conocimiento en particular de algún tema.


Aprovechando que en el idioma inglés existen mas de un millón de hechos definidos en Open Mind Common Sense, lo autores construyeron de manera automática esta red semántica, mediante la extracción de las relaciones reflejadas en los hechos por intermedio de reglas definidas, así como la inferencia de nuevas reglas dadas algunas muy generalizadas, como por ejemplo:

[(IsA “apple” “fruit”); (IsA “banana” “fruit”); (IsA “peach” “fruit”)]
AND
[(PropertyOf “apple” “sweet”); (PropertyOf “banana” “sweet”);
PropertyOf “peach” “sweet”)]
IMPLIES (PropertyOf “fruit” “sweet”)


O sea, si varias frutas como la manzana, el banano o el melocotón son dulces, esto implica que las frutas son dulces en general. Estas técnicas utilizadas evitaron tener que utilizar a varios expertos en lingüística para etiquetar a mano sus datos.


Para tener una idea mejor, comparándola con WordNet, se puede decir que la misma, presenta casi la totalidad de las funcionalidades que el anterior, pero se diferencia en que está mucho mas orientada al concepto que a los aspectos lingüísticos debido a que presenta un número mayor de conexiones conceptuales, lo que permite que sea usada para hacer inferencias de sentido común sobre textos reales, descubrimiento de afecto y resolución de analogías entre muchas otras.
Fragmento de la red semántica de ConceptNet

 Como ya se ha mencionado la estructura de ConceptNet está almacenada en forma de ontología conceptual, incluyendo un gran número de relaciones. A continuación puede ser visto un mapa de dicha ontología donde se señala cada relación en particular, la clase a la que pertenece y además el tamaño que abarca cada una dentro de la red semántica.

Mapa de la ontología conceptual de ConceptNet con los tipos de relaciones y el tamaño aproximado de las mismas incluídos

Introduccion a WordNet

WordNet es una sistema de referencia léxico para el idioma inglés. Su diseño, a diferencia de la mayoría de los diccionarios actuales que organizan las palabras de acuerdo a la manera en que se escriben, esta inspirado en las teorías que sostienen los psico-lingüistas sobre la organización de la memoria léxica en los humanos. En la medida en que se comenzaron a utilizar las computadoras para realizar tareas de los diccionarios, se hizo evidente que con la gran capacidad de cálculo de las mismas, sería un desperdicio contemplar solo la posibilidad de que fueran meras buscadoras por índice, sino que debía incorporársele más funcionalidad y es a esto lo que se orienta esta herramienta.


WordNet fue concebido alrededor del año 1985 cuando un grupo de investigadores del Laboratorio de Ciencias Cognitivas de la Universidad de Princenton se dieron a la tarea de crear una base de datos léxica, que a diferencia de los diccionarios convencionales presenta una organización subdividida en sustantivos, verbos, adjetivos y adverbios. Uno de sus aportes principales fue la creación de los synsets que constituyen conjuntos de palabras cuyo significado es el mismo, o sea, sinónimos. Es necesario aclarar que como una palabra puede tener varios significados, así también puede estar contenida en más de un synset. WordNet almacena además para cada synset una pequeña glosa, texto explicativo del significado del mismo, así como diversas relaciones semánticas.

Sustantivos:

  • Hiperónimos: Y es un hiperonimo de X si cada X es un tipo de Y (Ejemplo: Y=animal, X=perro)
  • Hipónimos: Y es un hipónimo de X si Y es un tipo de X (Ejemplo: Y=perro, X=animal)
  • Terminos Coordinados: X y Z son términos coordinados si comparten un Hiperonimo en común (X=perro, Z=gato, Y=animal)
  • Holónimo: Y es un holónimo de X si X es parte de Y (Ejemplo X=neumático, Y=coche)
  • Merónimo: Y es un jerónimo de X si Y es parte de X (Ejemplo X=coche, Y=neumático)
Verbos:
  • Hiperónimo: Y es un hiperónimo de X si la actividad de X es un tipo de la actividad de Y (Ejemplo X=percibir,Y=oir)
  • Tropónimo: Y es un tropónimo de X si la actividad Y realiza X de alguna forma (Ejemplo: X=balbucear,Y=hablar)
  • Vinculación(entailment): Y esta vinculado con X si para hacer X obligatoriamente se deberá hacer Y (Ejemplo: X=roncar, Y=dormir)
  • Términos coordinados: Y y X son coordinados si tienen un Hiperónimo en común. (Ejemplo: X=susurrar, Y=vocear)

Adjetivos:
  • Sustantivo al que modifican
  • Adjetivos similares
  • Participio del verbo

Adverbios:
  • Adjetivos que lo originan
Por relaciones semánticas en este caso, se entiende una conexión synset-synset con una etiqueta que define el tipo de la relación. Cada synset puede tener varias relaciones de acuerdo a la categoría del mismo, de aquí las relaciones contempladas por WordNet. La estructura del conocimiento almacenado en wordnet varía según la categoría. Los sustantivos y verbos al poseer la relación de hiperonmia o EsUn() pueden ser organizados jerárquicamente. La jerarquía va tendiendo hacia conceptos cada vez más primitivos hasta llegar al nodo raíz.

 dog, domestic dog, Canis familiaris
    => canine, canid
       => carnivore
         => placental, placental mammal, eutherian, eutherian mammal
           => mammal
             => vertebrate, craniate
               => chordate
                 => animal, animate being, beast, brute, creature, fauna
                   => ...

Los que se consideran sinónimos aparecen en el mismo nivel de la jerarquía. Es conocido que el árbol de los sustantivos es bastante profundo pues contiene gran cantidad de términos intermedios cuyo uso práctico es bien limitado, pero que son útiles para la categorización de otros mas usados. Por su parte la de los verbos tiene menos niveles de profundidad.

Para los adjetivos es imposible crear una estructura del conocimiento arbórea debido a que los mismos no poseen la mencionada relación. En lugar de eso, se forman diversos clústeres bipolares en donde son organizados sinónimos y antónimos con respecto a un atributo que los mismos modifican. El ejemplo siguiente corresponde al cluster Wetness y contiene los cúmulos de adjetivos contrarios húmedo/seco.

WET1,DRY1,! bedewed,& boggy,& clammy,& damp,& drenched,&
drizzling,&hydrated,&muggy,& perspiring,& saturated2,&
showery,&tacky,&tearful,& watery2,& WET2,&  
 bedewed,dewy,wet1,& 
 boggy,marshy,miry,mucky, muddy, quaggy, swampy, wet1,&  
 clammy,dank,humid1,wet1,&  
 damp,moist,wet1,& 
 drenched,saturated1,soaked, soaking, soppy, soused, wet1,&  
 drizzling,drizzly,misting, misty, wet1,&  
 hydrated,hydrous,wet1,& ((chem) combined with water molecules)  
 muggy,humid2,steamy,sticky1, sultry, wet1,&  
 perspiring,sweaty,wet1,& 
 saturated2,sodden,soggy,waterlogged, wet1,&  
 showery,rainy,wet1,& 
 sticky2,tacky,undried,wet1,& ("wet varnish")  
 tearful,teary,watery1,wet1,&  
 watery2,wet1,&(filledwith water; "watery soil")    DRY1,WET1,! anhydrous,&arid,&
dehydrated,& dried,& dried-up1,&
dried-up2,&DRY2,&rainless,& thirsty,&  
anhydrous,dry1,&((chem) with all water removed)  
arid,waterless,dry1,& 
dehydrated,desiccated,parched, dry1,&  
dried,dry1,&("theinkis dry")  
dried-up1,dry1,&("adry water hole")  
dried-up2,sere,shriveled, withered, wizened, dry1,&
(usedofvegetation) 
rainless,dry1,& 
thirsty,dry1,&  

Visto todo lo anterior se puede mencionar que una de las principales desventajas atribuidas a WordNet es que a pesar de que presenta una gran cantidad de significados de dominio general, muchas veces es insuficiente cuando trata de aplicarse a un dominio específico debido a que no tiene bien cubierto el mismo. En base a esto se ha apreciado en diversas ocasiones como se ha extendido de cierta manera WordNet mediante la creación de ontologías que la abarcan y añaden conocimientos extra de algún dominio en particular tal es el caso de SENSUS.

Resumiendo al decir de creadores de la herramienta que será detallada a continuación. Word Net es posiblemente el recurso semántico de uso mas extendido por la comunidad de Lingüística computacional en el día de hoy, y todo probablemente por la buena organización de su estructura y su facilidad de uso.

Probar WordNet Online





miércoles, 21 de agosto de 2013

Seminario SEO para desarrolladores o de como hacernos visibles en Internet I

El pasado febrero asistí al seminario SEO para desarrolladores organizado por Paradigma y JavaHispano. El SEO siempre ha sido una de esas sub-disciplinas de nuestra ciencia que he tenido en lista de espera, dando por hecho que cuando se cumpla mi deseo secreto de que el día tenga 48 horas voy a dedicarle tanto tiempo como para convertirme en ninja o gurú. Mientras tanto decidí asistir a la charla, esperando solo actualizar mis elementales conocimientos de forma rápida y pasar un rato entretenido.

La misma resultó muy provechosa. En el ponente Rubén Martínez se descubre un profesional con amplia experiencia en el tema, lleno de recursos para enfrentarse a las mas disímiles situaciones a las que puede enfrentarse un experto del SEO. Precisamente con esto, es con lo que mas me he quedado de todo lo que se trató. A pesar de que de manera concisa se expuso todo el entramado teórico del SEO (por lo menos lo que nos han permitido saber los creadores de buscadores) fue muy enriquecedor el hecho de que para cada aspecto teórico se brindase una herramienta práctica con el que poder medirlo, así como un ejemplo real de monitoreo del mismo de sitios reales en internet. El SEO es mitad ciencia, mitad artesanía, e incluye muchas experimentaciones y heurísticas por lo que no tiene sentido conocer solo los fundamentos teóricos.

A la hora de auditar el estado actual del SEO para un sitio dado existen 4 variables a tener en cuenta


  1. Back Links o enlaces que referencian al sitio.

  2. Bien conocido es que un criterio primordial para Google el que se "hable" mucho de algo por internet. Para esta categoría se presentó la herramienta ahref.com que brinda una extensa información sobre las referencias que posee nuestro sitio en el grafo de internet. Aunque de pago, permite realizar un número de análisis de manera gratuita, siendo muy interesante jugar con ella y observar sus resultados. También como aspecto interesante se brindó la siguiente tabla que muestra la distribución de los sitios en internet según el idioma, aspecto a tener en cuenta porque es mucho mas fácil obtener referencias de sitios en el mismo idioma que el nuestro.
    gráfico con la distribución de idiomas en paginas de internet



    Según el reflejo de esta tabla mas de la mitad de los sitios de internet estan en idioma inglés con lo cual es necesario cuestionarse si necesitamos publicar contenido en este idioma para tener una ventaja extra a la hora de llegar a otros sitios y ser referenciados por los mismos.

    De la misma manera, no solo importan la cantidad de referencias sino la calidad de las mismas. Ser referidos por sitios de prestigio puntuara mejor, mientras que por el contrario aparecer en enlaces "comprados" o sitios con alta cantidad de SPAM puede llegar a incurrir en penalizaciones. Una forma de lidiar con esto es mediante GOOGLE WEB MASTER TOOL

    Otras herramientas

  3. Palabras Claves

  4. Entran aquí además de las meta-tags, todas aquellas usadas en títulos, URLS, enlaces, pies de imágenes y otras partes del sitio, con las que es necesario tener especial cuidado y elegirlas para que sabiamente representen nuestro contenido a los "ojos" del crawler de Google.

    Existen herramientas para encontrar puntos débiles en este apartado y mejorarlos tales como:
    siteliner: Permite encontrar textos duplicados
    copyscape: Detecta el plagio de otros sitios de internet.
    operador site para búsquedas en google: conocer la cantidad de paginas indexadas para un dominio dado por google

  5. Arquitectura del sitio
  6. Es bueno tener un conocimiento de como se estructura nuestro sitio, que páginas reciben mas enlaces externos y cuales mas internos, cuan fácil sería por un crawler moverse por todas las aristas formadas en el grafo de nuestro sitio, que diferentes formatos se presentan. Para esto se vió en un ejemplo super completo en el cual se recogió toda la información de un sitio mediante la herramienta Xenu's Link Sleuth que hace un recorrido en profundidad del sitio y lo exporta a un archivo. Luego este puede ser importado por una herramienta de visualización de grafos Gephi.org quedando al descubierto aspectos muy interesantes sobre su topología.

    Otras herramientas sobre este aspecto:

La segunda parte versó sobre que errores no cometer y que aspectos priorizar al construir un sitio desde cero, pero es tan amplia e interesante que se merece un segundo post. Mientras tanto os comparto el enlace a los recursos que permiten ahondar aun mas en todo lo que se trató.

Ebook con los apuntes de la charla
Presentacion en Parleys

jueves, 1 de agosto de 2013

Obteniendo un listado de palabras en idioma español


Como parte de uno de los proyectos personales en los que me encuentro enrolado actualmente tuve la necesidad de disponer de un listado de palabras lo mas completo posible del idioma español. Un listado como este, sirve para mucho, desde el análisis estadístico de las mismas, hasta ser fuente de diversión, usado en un juego. 

En una búsqueda preliminar encontré algunos, aunque bastante incompletos. Otros eran solo lemarios, o sea, que no llegaban a incluir variantes como las distintas conjugaciones de los verbos (lo cual consideraba prioritario para mi proyecto), sino simplemente el lema de los mismos, debiendo ser expandido este mediante un algoritmo posterior. 

Partiendo de estas fuentes, y habiendo comprobado la efectividad de correctores ortográficos como el Chrome decidí crearme uno propio. A estos recursos con que ya contaba añadí el siguiente listado que de la dirección publica del código de Chrome extraje y luego de un pre-procesado mediante un script de Groovy (github) , ha quedado listo para usarse en lo que sea necesario.

Enlace a 110419 palabras