Calcular la dificultad de lectura de una palabra

Hacer un algoritmo que calculé lo difícil de leer que es una palabra es complicado, depende de muchos factores, algunos propios del lector: cultura, velocidad, conocimiento del tema, problemas con algunas sílabas,… Por lo que el valor obtenido hay que tomarlo como un indicador y no como un valor absoluto

En nuestro modelo vamos a asociar la dificultad para lectura con la dificultad para pronunciar. Por ello descompondremos la palabra en sílabas y calcularemos la dificultad de cada una.

Dificultad de lectura de una sílaba

El modelo que usaremos puntúa con valor númerico a cada letra de la silaba, además suma o resta puntos por ciertas combinaciones de letras. El resutado final de sumar todo da la dificultad de lectura.

  • Las vocales son más faciles de leer que las consonantes. (+1)
  • La h al ser muda no afecta a la pronunciación. (+0)
  • Las consonantes habituales tienen una dificultad media (+2)
  • Hay consonantes poco comunes que hacen más dificiles la pronunciciación debido a la falta de habito. (+3)

Valores de cada letra:

  • +0: h
  • +1: a,e,i,o,u
  • +2: b,c,d,f,g,j,l,m,n,ñ,p,q,r,s,t,v
  • +3: k,w,x

Hay excepciones en las que una letra no cuenta, por lo que en esos casos esa letra no aporta valor, para ello se realizaran los siguientes remplazos:

que = qe
qui = qi
gui = ge
gue = ge
rr = r
ll = y

Dos consonantes seguidas complican la pronunciacion:Si la segunda consonanete es “hbrls” +1Si  la segunda consonanete es cualquier otra +2

Dificultad:

Baja1-3a, be, ca
Media4-6del, bra, tri
Alta7-…tras, blas


Problemas y mejoras:

  • No sirve para otros idiomas.
  • Considera que todo es valido, por ejemplo “mnztr” puntua alto pero lo considera “legible”

Dificultad de lectura de una palabra

Para saber la dificultad de una palabra basta con sumar la dificultad de cada una de sus sílabas. Aunque se puede usar el valor medio (dividiéndolo entre el número de sílabas o de letras) yo recomiendo usar el valor absoluto ya que así se refleja la longitud de la palabra. Por ejemplo “catarata” a mí me parece más difícil que “cabra”. Si usamos el valor absoluto catarata puntúa 12 y cabra 9. En valor medio 3 y 4,5. 

El primer problema es dividir la palabra en sílabas, por suerte aquí tienes una solución. 

Ahora se puede valorar cada sílaba y sumarlas. Para saber qué dificultad tiene cada palabra se pueden usar los siguientes valores que he calculado
a prueba y error:

Baja1-9
Media10-13
Alta14-…

Problemas y mejoras:

  • Los plurales, simplemente añadir una s o una es al final puede hacer que una palabra suba su dificultad cuando muchas veces no se corresponde con el incremento “real” de la dificultad.

  • Hay sílabas que cuando van seguidas aumenta la dificultad de pronunciarlas, en este modelo no se ha tenido en cuenta.

¿Qué aporta el libre albedrío a los agentes racionales?

Vamos a entrar en el incierto mundo de las suposiciones, para ello intentaremos imaginar que ocurre cuando dotamos a una inteligencia artificial de libre albedrío (sin entrar en detalles sobre si existe o no). Una inteligencia artificial actúa como un agente racional. Esto que quiere decir que tomara decisiones basadas en elegir la que más beneficiosa sea según sus preferencias.

Las preferencias de los agentes son establecidas por varios factores: el aprendizaje, las circunstancias (tanto internas del agente como externas del medio) del momento en que se toma la decisión y de preferencias establecidas por los programadores. Esto quiere decir que dos agentes en las mismas situación pueden elegir respuestas diferentes y que un mismo agente puede elegir distintas respuestas según la situación en la que se encuentre.

Cuando a un agente de este tipo se le ofrecen varias alternativas pondera cada una de ellas y elige aquella que mayor valor le aporta.

Vamos con un ejemplo, imaginemos que tenemos un robot en Marte para estudiar su geología, vamos a resumirlo como “estudiar piedras”. Si nuestro robot ve un piedra interesante puede decidir entre estudiarla o no. Lo primero que hará será valorar su nivel de batería, si la batería no tiene suficiente carga como para permitirle llegar hasta la piedra y estudiarla con cierto márgen de seguridad se quedará esperando a que sus paneles la recarguen. De esa forma su decisión queda condicionada a su estado. En otro caso encuentra dos piedras interesantes y tiene que elegir cuál es más interesante, para ello procesa las imágenes de ambas piedras en busca de indicadores que los geólogos terrestres han introducido en su base de datos. Ahí es donde las preferencias vienen condicionadas por los valores establecidos en su programación. Pasa el tiempo y tras analizar muchas piedras ha ido aprendiendo que los geólogos de la tierra no estaban del todo acertados sobre que piedra es interesante y cual no. Así que poco a poco cambia sus preferencias sobre “piedras interesantes” y por tanto su comportamiento. En este último caso ha ajustado sus preferencias según lo aprendido.

El modelo es muy simple, un modelo realista tendría que tener en cuenta muchas más cosas como el riesgo del camino a la piedra, el estado de las ruedas, la metereología y mil cosas más, pero un modelo tan complejo no ayuda más a entender las cosas que uno simple, así que vamos a quedarnos con nuestro robot simplificado.

Tenemos a nuestro robot tomando sus decisiones en Marte. Al principio desde la Tierra era fácil predecir su comportamiento, ya que seguía las reglas que habían escrito en su programación. Según pasa el tiempo va aprendiendo cosas nuevas y su experiencia influye más sobre sus decisiones haciendo que desde la Tierra no puedan predecir al 100% sus actos. Sin embargo, si pudieran hacer un volcado de su software y analizarlo verían que sigue siendo un agente racional que elige la opción que sus preferencias internas le dicen que es la mejor.

Desde la Tierra preparan una actualización de software que incluye el módulo “libre albedrío”. Una vez descargada e instalada ¿Qué aporta este módulo?. Ahora, antes de tomar una decisión, el agente tiene que tener en cuenta un elemento más, el “libre albedrío”. Este módulo le da la libertad de, voluntariamente, elegir la opción que quiera sin ceñirse a sus preferencias. ¿Qué le aporta a nuestro robot elegir una opción que no es la que prefiere?. Probablemente nuestro robot pasé su vida eligiendo la misma opción con libre albedrío que la que elegiría sin él. Así que el libre albedrío no debería influir demasiado en el resultado ya que solo sirve para elegir una opción distinta a la mejor, cosa que poco va a interesar a un agente racional.

En resumen un agente racional al eligir la mejor respuesta según sus preferencias hace que el libre albedrío no le afecte demasiado ya que no afecta a las preferencias ni a como se valora cada opción, si no que permite elegir una distinta a la mejor opción. Lo cual no parece resultar muy útil. Aún en el caso de tener libre albedrío lo más probable es que el resultado no varíe y la respuesta sea la misma. Es difícil diferenciar entre un agente racional y un agente racional con libre albedrío.

Cosas que no necesitan libre albedrío

Muchas veces se atribuyen al libre albedrío ser la causa de diversos comportamientos que en realidad no lo requieren.

Comportamiento aleatorio: el comportamiento aleatorio es tan contrario al libre albedrío como el comportamiento determinista.

Curiosidad: ser curioso consiste en tener preferencia por las cosas nuevas o desconocidas.

Comportamiento irracional: muchas veces el comportamiento irracional se debe a las diferentes preferencias entre el que juzga y el que lo juzga. Un agente es racional siempre siga sus preferencias, sin importar las que sean. Aquí surge que a veces se confunde la irracionalidad de la inteligencia artificial con la asociada a ciertos comportamientos humanos. Por ejemplo las conductas autodestructivas se consideran irracionales, pero si yo programo un agente para que prefiera darse, literalmente, cabezazos contra la pared ese será un comportamiento racional.

Pero….

A nivel de comportamiento puede ser que no varíe el resultado pero eso no quiere decir que dotar de libre albedrío a un agente inteligente no sería un logro histórico para la humanidad. Tendría consecuencias científicas y filosóficas revolucionarias. Hay una diferencia enorme entre “elegir la mejor opción” y “elegir libre y voluntariamente la mejor opción”.

Inteligencia artificial, armas y ética.

Últimamente grandes empresas de tecnología como Google o Microsoft han tenido conflictos con sus trabajadores por querer aplicar sus conocimientos en I.A. al campo militar. Parece que hay una corriente en contra de dotar a las armas de inteligencia. Por otro lado el Pentágono dice que necesita desarrollar ese tipo de armas para poder defenderse de países con menos escrúpulos que si las desarrollen.

Actualmente la mayoría aceptamos que el uso de armas en defensa propia es legítimo y ético. Siempre y cuando se haga un uso proporcionado de las mismas. Incluso se acepta tomar represalias en respuesta a ataques siempre que se evite afectar a inocentes. ¿Quién se podría negar a ayudar a defender a tu país? Y aunque no sea patriota. ¿Quién se niega a defender a sus vecinos?. Creo que nadie, el problema es confiar en que el gobierno de tu país no va a usar las armas de forma poco ética.

Realmente las armas inteligentes hace muchos años que existen y se emplean. Quizás el caso más conocido sean los sistemas de guiado para que las armas alcancen su blanco. Siempre se ha defendido que su mejora reducirá los daños colaterales. Sin embargo en su origen estos sistemas servían para lo contrario.

Mejores armas y tratados internacionales

Los sistemas de guía nacieron en la segunda guerra mundial con los cohetes alemanes. Que un cohete llegase solo hasta su objetivo cuando hasta a los pilotos de los bombarderos les costaba localizar los objetivos fue todo un reto. Los primeros sistemas de guía eran poco más que cronómetros que pasado cierto tiempo de vuelo cortaban el flujo de combustible a los motores para que el cohete se precipitara sobre su objetivo. Con objetivos del tamaño de Londres era posible, pero no fácil, acertar. Derribar un solo bloque de edificios en una ciudad era imposible. Pero Londres no se bombardeaba para alcanzar objetivos militares se bombardeaba para desmoralizar a la población. Cohetes más precisos no eran la solución. La solución ha sido los Convenios de Ginebra. Es decir llegar al acuerdo entre naciones de unas reglas humanitarias que hay que respetar en los conflictos armados. Muchas armas como las químicas, bacteriológicas, lanzallamas, napal, minas antipersona, bombas de racimo,… Se han prohibido, gracias a acuerdos internacionales y por razones humanitarias, no por motivos tecnológicos.

Por tanto, la mejora de las armas no trajo consigo una reducción del número de civiles muertos. Lo tratados internacionales es lo que los ha traído y aun así sigue habiendo gran cantidad de “daños colaterales”. La idea es que si un país incumple esos acuerdos podrá ser sancionado por el resto de los países. Para ello es necesario que exista un equilibrio de fuerzas ya que en el momento que un país supere en fuerzas al resto de países juntos podría hacer lo que quisiera….¿O no?.  No. Aunque un ejercito sea muy superior a otro toda lucha tiene un coste. Puede que seas más fuerte que tú rival pero no vas a usar la fuerza con él porque aunque ganes algún golpe vas a recibir y nunca es agradable. Además de que tiene un coste en imagen, nadie quiere tratar con alguien violento. Para los países es parecido solo que muchos más complicado. Tienen que cuidar la imagen exterior pero también hacia los propios ciudadanos. Igualmente una guerra tiene dos tipos de costes, económico y en vidas de los soldados enviados a combatir. Los ciudadanos no se toman nada bien la muerte de los propios soldados.

Reducir los costes de la guerra

La inteligencia artificial permite hacer armas baratas y precisas. Pero también sustituir a los soldados. Esto permite reducir el coste de la guerra, al menos en vidas de soldados. De primeras puede parecer una ventaja, pero tiene una pega. Al reducir lo que a un país le cuesta la guerra es más fácil es que decida comenzar una, aunque sean guerras “baratas” en vidas no parece que sea una buena idea dirigirse hacia un mundo donde sea más fácil mandar a máquinas a destruirse entre ellas que sentarse a negociar.

Además nos podemos plantear si el ideal de una guerra donde no mueran soldados es una guerra sin víctimas. Los daños colaterales no siempre son causados por ataques directos. La población también sufre por los daños a las infraestructuras (electricicidad, agua, luz, comunicaciones, carreteras, …). Por lo que la idea de una guerra sin bajas es cuestionable y la única lucha sin muertes es la que se da en las mesas de negociación.

Carrera armamentística

Con tecnologías como la inteligencia artificial con un desarrollo tan rápido se corre el riesgo de entrar en una absurda carrera armamentística donde cada arma queda desfasada antes de entrar en uso. Espionaje, desconfianza, dudas de lo que habrán desarrollado los demás, pruebas de fuerza para demostrar lo que tú eres capaz pero sin mostrar todas tus cartas, faroles,…. El peligro de todo esto es la mala imagen que da del campo de la I.A. y esto puede repercutir en los futuros investigadores que decidan dedicarse a investigar otras cosas.

El secretismo retrasa el desarrollo

La investigaciones militares están rodeadas de un gran secretismo. Por lo que se corre el riesgo que los resultados y avances que ellos obtengan queden clasificados y no aporten a la comunidad. Si no que se lo pregunten a Clifford Cocks que creo un sistema de cifrado de clave asimétrica en 1973 pero que el gobierno británico mantuvo en secreto hasta 1997. Lo irónico de todo esto es que ese sistema fue reinventado en 1977 de forma independiente dando lugar al hoy conocido como “algoritmo RSA”. En apenas 4 años su “sistema de cifrado secreto” podía ser usado por cualquiera. Y es que en el mundo actual con tanta gente cualificada es difícil que ningún gobierno o empresa desarrolle algo que nadie más este a punto desarrollar. La única manera que tiene un gobierno de proteger sus “armas secretas” es crear leyes que limiten el desarrollo de ciertos campos fuera del ámbito militar. Estados Unidos ha llegado a tener leyes muy estrictas sobre tecnologías para cifrar datos.

En la lista de afectados por este secretismo y prohibiciones podemos encontrar: la colaboración entre países, las universidades y sus investigadores, las empresas privadas, y los proyectos de software libre….casi nada.

I.A. tomando decisiones éticas

Las decisiones que tiene que tomar el ejercito no siempre son fáciles. De hecho puede que no haya solución buena. ¿Bombardear un campamento enemigo donde puede haber civiles pero que evitara una batalla más cruenta en un territorio más poblado? ¿Y si solo reduce el número de bajas de tus soldados? ¿Unos pocos civiles para evitar la muerte de miles de tus soldados?. ¿Cuantos daños colaterales son aceptables en un bombardeo?. Si hacemos máquinas inteligentes con la capacidad de decidir sobre la vida y la muerte han de ser capaces de lidiar con semejantes decisiones. Lo mínimo que ha de ser capaz es de saber a quien puede y a quien no puede disparar. O casos mas complejos como cuando un enemigo se ha rendido o esta herido. Un arma inteligente debe de respetar los tratados internacionales.

El ser humano no es perfecto. Son famosos muchos abusos de soldados a prisioneros. Sin embargo una I.A. dotada de una ética que le prohibiese comerte esos abusos nunca los cometería. ¿No podemos hacer armas dotadas de ética? Es difícil. Para empezar desde el punto de vista de todo ejercito ellos son los buenos. Las “hordas malvadas” existen en las películas, todos los soldados son personas con una vida, amigos y familia. Luchando por lo que creen que es lo correcto o por lo menos por lo que su país cree que es correcto. Incluso es posible que cada bando tenga parte de razón. A una guerra rara vez se llega de un día para otro, suele ser causa de una escalada de tensiones y de agresiones que termina en un conflicto entre bandos. Posiblemente la postura ética de “la violencia solo esta permitida en defensa propia” sea la más adecuada, pero difícilmente un ejercito va comprar un arma con esa forma de pensar. Sin embargo un arma inteligente que no tenga ningún tipo de limite ético seria poco más que una picadora de carne.

El peligro de que se vuelvan en nuestra contra

Quizás sea el caso menos probable, pero si dotamos a un arma de la capacidad de matar, debemos asegurarnos de que no la va a usar contra los seres humanos de forma indiscriminada. No podemos permitir que mate soldados, civiles, sanitarios, periodistas y cualquier cosa que se parezca a un ser humano. Asi que la ética de la I.A. actúa, ademas de como extensión de nuestra propia ética, como mecanismo de seguridad.

Una I.A. puede volverse en contra nuestra no solo por que alcance un nivel de consciencia tal que le permita “volverse contra sus creadores”, también esta expuesta a problemas técnicos (averias, bugs, daños) y “hackeos” desde el otro bando. Este escenario es más probable y en el caso de un ejercito con gran dependencia de este tipo de armas puede ser un desastre.

Sin embargo el escenario más probable por el que un arma puede acabar siendo usada contra los soldados del país que la desarrollo. Su comercialización. La venta de armas mueve decenas de miles de millones de euros anuales. Es una cantidad muy jugosa como para no comercializar las innovaciones. Es cierto que se trata de limitar a que países se venden, pero al final cuando un arma se introduce en el mercado resulta difícil que no acabe en manos de aquellos países que tengan dinero para comprarlas.

Derecho a la defensa

Los países tienen el derecho y la necesidad de poder defenderse. Eso impulsa la carrera armamentística de fabricar armas antes de que lo haga el enemigo. Sin embargo no es del todo cierto. No hace falta tener las mismas armas para defenderte del enemigo. De las armas químicas o biológicas no te proteges con más armas químicas o biológicas si no mejorando los tratamientos. La defensa legitima la investigación en todo tipo de armas “para defendernos de ellas”. Pero conocer cómo funcionan no quiere decir que se desarrollen. Precisamente para evitar eso entran de nuevo los tratados internacionales que vigilen que el resto de países no las fabriquen.

Los programadores y las armas

¿Puede un trabajador quejarse de que su trabajo se use en armas?. En un mundo ideal un trabajador tiene derecho a tener cierto control ético sobre su trabajo y más cuando es un trabajo creativo. en un mundo menos ideal y más real se entabla un “tira y afloja” con la empresa y dependerá de la fuerza que tenga cada uno. La mayor amenaza que tiene un trabajador es dimitir si la empresa sigue adelante. Nadie puede discutir el derecho de un trabajador a dimitir e irse si no le gusta lo que hace. En un área tan competitiva y necesitada de expertos como la inteligencia artificial el riesgo de causar descontento entre tus trabajadores y que una cantidad apreciable de ellos te abandonen por la competencia puede causar más costes que el beneficio que te reporte un proyecto militar, que además te va a producir mala imagen pública.

Conclusiones

El control de las armas ha de realizarse a través de tratados internacionales, la presión pública y la ética profesional.

La militarización de un campo puede entorpecer su desarrollo y dañar su imagen.

Mejores armas y más baratas no significan menos víctimas, ni guerras más humanas significa que sea más “barato” entrar en una guerra.

Cálculo de la frontera de Voronoi

Una vez que hemos calculado las particiones en el plano de Voronoi vamos a sacar las fronteras de las mismas. La frontera es el punto donde se pasa de un polígono a otro.

Partiendo del caso anterior calcular una frontera es simple, una frontera es aquel individuo que tiene algún vecino de un color/tipo diferente. Así de sencillo es calcular la fronteras en un autómata celular. Si alguno de los vecinos es distinto estoy en una frontera.

    this.isBorder = false;
    for(var i = 0; i < neighbors.length; ++i){
      if(neighbors[i].creature.point != this.point){
        this.isBorder = true;
    }

Cuando se ejecuta la demo se puede ver como las fronteras van creciendo extendiéndose hasta que chocan con otras fronteras y dejan de avanzar. El resultado final lo pongo en la imagen, en ella se pueden ver las fronteras de los polígonos en color negro.

Unos de los problemas que se pueden ver es que la frontera ocupa dos celdas de ancho. Esto se debe a que realmente la frontera es lo que pasa entre ambas celdas, pero lo que se está coloreando son las celdas que están en la frontera, es decir el vecino que esta a cada lado de la misma.

Operaciones con el histograma

A nivel de programación podemos ver el histograma de un conjunto de valores como un array donde se asocia a cada posible valor del conjunto a un indice donde se almanacena el número de veces que aparece ese valor en el conjunto de datos. Es habitual usarlos con imágenes. Así que vamos a usarlo como ejemplo, pero estos cálculos son aplicables para cualquier histograma.

Empezando por el caso más simple, el de una imagen en escala de grises con 8 bits de profundidad. Su histograma es el número de pixeles que hay de cada valor (0-255). Se calcula con un procedimiento tan simple como recorrer la imagen e ir contando el número de pixels de cada intensidad .

Histograma de un solo canal (escala de grises)
var histograma = [];
for(var i = 0; i < pixels.length; i++){
  histograma[pixels[i]] = histograma[pixels[i]]+1 || 0;
}

Para el caso de una imagen RGB lo que habitualmente se hace es calcular un histograma por cada canal, por lo que tendremos tres histogramas. Se podria hacer un histograma contando cada una de las posibles combinaciones que hay de los tres canales RGB, pero son mas de dieciséis millones y quedaba un histograma demasiado grande para ser manejable

Histograma RGB.

Vale, ya sabemos que es y como se calcula ¿Para qué demonios sirve? Para conocer la distribución de las distintas intensidades en la imagen. Por ejemplo, si la mayoría de los pixeles están en los valores bajos la imagen será oscura y posiblemente estará subexpuesta. Por el contrario si se concentran en los valores altos la imagen será luminosa y podría estar sobreexpuesta.

El histograma normalizado es un histograma cuyos valores se han ajustado para que la suma de todos sus valores sea 1. Se calcula dividiendo cada valor del histograma entre el número total de píxeles que tiene la imagen. Resulta útil para trabajar con histogramas que procedan de distintas fuentes ya que el número de píxeles puede no ser equivalente. Lo que indica es la proporción de píxeles sobre el total. Hay que recordar que el total de píxeles de la imagen es igual a la suma de los valores de todo el histograma

var total = 0;
for(var i = 0; i < histograma.lentgh; i++)}
  total += histograma[i];
}
var normalizado = [];
for(var i = 0; i < histograma.lentgh; i++)}
  normalizado[i] = histograma[i]/total;
}

El histograma acumulado indica cuantos píxeles tienen un valor igual o inferior a uno dado. Se calcula sumando a cada posición del histograma la suma de las anteriores.

var acumulado = [];
acumulado[0] = histograma[0];
for(var i = 1; i < histograma.lentgh; i++)}
  acumulado[i] = acumulado[i-1]+histograma[i];
}

Estadística

El histograma facilita los cálculos estadísticos sobre los valores de la imagen.

La media aritmética:

var media = total/histograma.lentgh;

La varianza:

var varianza = 0;
for(var i = 1; i < histograma.lentgh; i++)}
  varianza += Math.pow(histograma[i], 2);
}
varianza /= histograma.lentgh;
varianza -= Math.pow(media, 2);

La desviación tipica:

var desviacion = Math.sqrt(varianza)

La moda:

var moda = 0;
for(var i = 0; i < histograma.lentgh; i++)}
    if(histograma[i] &gt; histograma[moda]){
        moda = i;
    }
}

La mediana:

var suma = 0;
for(var i = 0; i < histogram.lentgh; i++)}
    suma = histograma[i];
    if(suma &gt; total/2){
        return i;
    }
}

Probabilidad

Para la probabilidad usaremos el histograma normalizado. Que representa como de probable es que un pixel cogido al azar tenga el valor indicado por el indice (0-255). Es decir normalizado[3] es la probabilidad que de que un pixel elegido al azar tenga valor 3

Probabilidad de que el pixel elegido al azar tenga un valor x:

var probabilidad = normalizado[x];

Probabilidad de que el pixel elegido al azar tenga un valor x, y o z:

var probabilidad = normalizado[x] + normalizado[y] + normalizado[z];

Probabilidad de que un pixel elegido al azar tenga un valor que sea distinto de x, y o z:

var probabilidad = 1 - (normalizado[x] + normalizado[y] + normalizado[z]);

Para calcular la probabilidad acumulada podemos calcular el histograma acumulado del histograma normalizado:

var acumuladoNormalizado = [];
acumuladoNormalizado[0] = normalizado[0];
for(var i = 1; i < normalizado.lentgh; i++)}
  acumuladoNormalizado[i] = acumuladoNormalizado[i-1]+normalizado[i];
}

Ahora pasa saber la probabilidad de que un pixel tomado al azar sea menor o igual que un valor x:

var probabilidad = acumuladoNormalizado[x];

Si queremos calcular que sea mayor que el valor x:

var probabilidad = 1 - acumuladoNormalizado[x];

Todos estos casos en lugar de como probabilidad se pueden interpretar como “porcentaje de pixeles de la imagen”. Por ejemplo: “Porcentaje de pixeles de la imagen que son mayores que 100” Seria:

var probabilidad = 1 - acumuladoNormalizado[100];

Unir histogramas

Una de las ventajas del histograma es que su cálculo es fácilmente paralelizable. Se puede dividir la imagen en varias partes y calcular el histograma de cada una de ellas en paralelo. Luego esos histogramas se pueden unir en uno solo de forma fácil. Simplemente basta con sumar cada uno de los indices del histograma:

var union = [];
 for(var i = 0; i < histograma1.lentgh; i++)}
   union[i] = histograma1[i]+histograma2[i]
 }

En el caso del histograma normalizado hay que sumar y dividir entre 2 para conservar al propiedad de que sume 1 en total.

var union = [];
 for(var i = 0; i < normalizado1.lentgh; i++)}
   union[i] = (normalizado1[i]+normalizado2[i])/2
 }

El valor de tus datos

Vivimos en la época en que los datos son tan valiosos como el dinero. Es imposible desarrollar modelos de Big data o de aprendizaje maquina sin una gran cantidad de datos (el término “big data” puede ser una pista de lo importantes que son). Obtener estos datos es uno de los problemas más costosos de resolver a la hora de implementar estos modelos.

La necesidad de datos no termina ahí, para sacar rendimiento a estos modelos necesitan datos sobre los que aplicarlos. Imagínate que voy al banco a pedir un crédito y solo tienen mi nombre y apellidos, con eso su departamento de riesgos no va a poder evaluar cuanto “riesgo” supone darme un crédito. Necesitarán que rellene un formulario y les lleve varios documentos que les permitan valorar ese riesgo. En ese caso soy consciente de ello, pero en muchos otros no.

No sirve alimentar al sistema con datos a lo loco, estos datos necesitan tener algunas características:

Cantidad: se necesitan montones de datos para obtener un modelo. Obtenerlos es un proceso complicado y en algunos casos caro. Puede ser que no sea necesario recopilar los datos, que ya estén en bruto, pero que sea necesario “extraerlos”. Incluso es posible que digitalizarlos.

Procesar estos datos tiene un coste, no basta con “acumularlo y lanzarlos a los algoritmos”, necesitas saber que hacer con ellos y adaptarlos. Eso necesita un equipo de expertos detrás.

Calidad: los datos han de ser ciertos y útiles. O lo que es lo mismo han de tener la mínima cantidad de errores.

Esto hay que tenerlo en cuenta al procesar los datos. Según el método de recopilación puede haber errores al introducir los datos, al transcribirlos, malentendidos o directamente datos falsos. ¿Quién no ha mentido al rellenar un formulario?.

Relevancia: si tenemos muchos datos pero no podemos obtener conclusiones de ellos no nos sirven. Por desgracia es posible que durante la fase de recopilación de datos no se sepa muy bien cuáles son útiles o que surja una especie de “síndromes de Diógenes” de los datos y se recopilen todos los que se pueda. Como consecuencia asume que cuando usas una web o una aplicación todo lo que haces es recopilado.

Por ejemplo, saber el número de pie de todos los que entran a una tienda probablemente no nos resulte útil (quizás, si es una zapatería). Sin embargo lo que han comprado si.

Hay un tipo de datos especialmente valioso que sirve para cruzar entre varias fuentes. Un ejemplo es el número de teléfono móvil. Es un dato que no solemos revelar mucho de darlo al realizar compras por internet, encargos, rellenar formularios para tarjetas descuento, …. Sin embargo puede ser tremendamente valioso ya permite identificar al mismo individuo en distintas fuentes de datos y cruzarlas.

Variedad: de nada sirve tener muchos datos de gran calidad si pertenecen a una muestra pequeña de individuos. Es necesario tener muestras del mayor número de sujetos posibles.

Si los datos están sesgados el modelo también lo estará. Por ejemplo si obtienes los datos a partir de una aplicación de descuentos en el móvil estás dejando de lado a toda la gente que no use smartphones o no tengan suficiente soltura para usarlos o no quiera “instalar cosas raras” en ellos. Los datos de esas personas se vuelven más valiosos para completar el modelo. Quizás podría hacer un concurso donde se participe rellenando una papeleta con los datos personales.

Legales y éticos: es importante no recopilar datos que la ley prohíba recopilar o qué no sea ético hacerlo. Aunque es posible hacer trampas y usar proxys. Los proxys son datos que de forma directa o indirecta permiten “deducir” otros datos. A veces no son 100% exactos pero no importa los algoritmos pueden tolerar cierta cantidad de errores. Un ejemplo tan obvio que solo sirve como ejemplo sería no poder pedir el sexo pero si el nombre. Con el nombre se puede extraer el sexo en la mayoría de los casos. Hay veces que un proxy no es un solo dato sino varios.

Baratos: debido a la cantidad de datos necesarios es importante que obtener cada muestra sea barato. Eso puede condicionar el método elegido para recopilarlos e introducir sesgos.

Muchos datos que necesitan tratamiento manual son procesados por personas con sueldos bastante bajos.

Hasta este punto todo han sido costes. El modelo no dará beneficios hasta que empiece a usarse. Esto no es una justificación para no pagar por los datos, de hecho es probable que te hayan pagado en forma de descuentos, promociones, concursos. El problema es que no sabes que van a hacer con esos datos. ¿Y si se usan en un modelo que acaba siendo usado en perjuicio tuyo?

Una vez creado el modelo para obtener beneficio hay que usarlo. Para ello se necesita obtener tus datos para introducirlos al modelo y obtener un resultado. Lo que este resultado aporte al negocio (más conversiones a clientes, más compras, mejor servicio, ahorro de recursos y costes) es el beneficio que produce.

Cuando alguna empresa anuncie que ha desarrollado un sistema que le va a permitir ahorrar o ganar cantidades ingentes de dinero piensa que tus datos han sido necesario para ello.

Hacer un sistema de lectura rápida

En esta entrada voy a dar los pasos para crear un sistema de lectura rápida tipo spritz o spritzlet.

Estos sistemas se basan en poder leer de un vistazo sin mover los ojos. Para ello nos muestran las palabras una a una centradas de forma adecuada para no tener que mover los ojos. Con algo de práctica llegas a un punto en que lees las palabras casi sin darte cuenta. En mi experiencia personal puedo decir que en textos complejos cuesta seguir el hilo. Pero para lectura de textos sencillos o para una primera lectura resulta muy útil.

Punto de reconocimiento óptimo (ORP)

El primer paso es separar el texto en tokens. Usaremos los espacios y fin de línea como separadores.

Para cada token hemos de calcular el “punto de reconocimiento óptimo” (Optimal Recognition Point) ORP. Que es el punto donde se fijan los ojos al leer una palabra. Su cálculo es sencillo, es suficiente con saber la longitud de la palabra: (en la tabla la posición está indicada empezando a contar el primer carácter como posición 0)

LongitudPosición ORP
10
21
31
41
51
62
72
82
92
103
113
123
133
14+4

Con el ORP calculado hemos de calcular el tiempo que se mostrará ese token en pantalla. Ajustando el tiempo por carácter más un pequeño extra para cambiar de palabra y una parada un poco más larga en los signos de puntuación (o se pueden mostrar estos de forma individual).

Interfaz de usuario

Con eso ya tenemos todo lo necesario para mostrar la palabras una por una. Para ello elegiremos un punto de la pantalla donde no suponga un gran esfuerzo mirar fijamente. Por lo general o el centro de la pantalla o un poco por encima de este.

Hay que elegir unos colores para el texto y su fondo que se lean correctamente. Podemos oscurecer el resto de la pantalla para que no distraiga.

¿Os acordáis del ORP? Ahora hay que asegurarse de que todas las palabras se presentan centradas en ese carácter. Puede ser buena idea marcarlo de alguna manera, generalmente se marca en algún color llamativo, aunque usar alguna ayuda más como subrayar o ponerla en negrita permite que sea más accesible para personas que no distingan colores o desde dispositivos que sean en blanco y negro.

Algunas versiones cambian el tamaño de las letras según lo que ocupe la palabra, pero a mí esa opción me parece incómoda cuando saltas de palabras pequeñas a muy largas y eso supone un gran cambio del tamaño de letra.

Tiempo de lectura

Es necesario permitir al lector ajustar la velocidad de lectura en palabras por minuto. Habitualmente la velocidad se permite ajustar de 100 a 700 palabras por minuto.

Para calcular el tiempo que hemos de tener cada palabra en pantalla hay dos formas. Tener todas las palabras el mismo tiempo en pantalla, para ello se calcula el tiempo por palabra dividiendo 60 segundos entre el número de palabras por minuto seleccionado. Es un sistema simple y que da buenos resultados. Si se quiere hilar un poco más fino se puede calcular el tiempo por letra, para ello se supone que el tiempo por palabra se refiere a una palabra media de 5 letras y se divide por 5 para obtener el tiempo por letra, ahora se multiplica este tiempo por el total de letras en la palabra y así se obtiene el tiempo que tiene que mostrarse la palabra. Es buena idea fijar un tiempo mínimo o en casos de lecturas muy rápidas las palabras muy cortas podrían ser difíciles de leer.

Palabras muy largas

Aquí tenemos un problema. Si la palabra es muy larga, algo del estilo de “esternocleidomastoideo”, mostrarla de una sola vez obliga a mover los ojos. Hay que dividirla, lo recomendable es no pasar de las tres o cuatro sílabas. Pero ojo, no partas sílabas, eso complica la lectura de la misma. Es recomendable señalar de alguna forma que el texto que muestras es parte de una palabra. Compara:

“Esternoc” “leidomast” “oideo”

“Esterno~” “~cleidomas~” “~toideo”

Conclusión

Aunque, dada la cantidad de librerías y aplicaciones que implementan este sistema de lectura spritz, no es necesario programar desde cero un lector rápido las ideas aquí expuestas pueden servir para entender como funciona y para aplicarlas a otras funcionalidades.