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.

Requisitos para usar big data o I.A. para clasificar personas

El big data esta de moda, la cantidad de empresas que anuncian que usan big data para mejorar los resultados del servicio que ofrecen no para de crecer. Muchas de ellas no tienen muy claro de que hablan o se dedican a entrenar algún modelo de aprendizaje máquina lanzandole datos sin limpiar ni procesar y esperan obtener algo que funcione. Por supuesto hay muchas que saben lo que hacen. Aún haciendo todo de forma correcta el big data y la I.A. corren el riesgo convertirse en los oráculos modernos. Le metes datos, esperas y obtienes una respuesta y sin la necesidad de sacrificar una cabra a ningún dios. El problema es que quienes acuden a estos oráculos toman las respuestas como verdades absolutas, sin entender de donde ha salido esa respuesta. Muchos de estos modelos se empiezan a aplicar para valorar a personas: concederles una hipoteca, un trabajo, la libertad condicional o una tarjeta de crédito, son solo algunos ejemplos. Aplicar estos modelos de caja negra a asuntos humanos es arriesgado y puede llegar a causar bastantes injusticias.

En esta entrada voy a tratar de describir algunos principios que deberían de cumplir los modelos obtenidos a partir de grandes cantidades de datos para que su uso con personas sea justo. Describe un ideal de las características que debería de tener un sistema así.

Ser transparente

Si se va a emplear un modelo obtenido a través de big data sobre alguna persona está debería ser correctamente informada de ello. Además debe de saber lo eficaz que es ese sistema. Su tasas de falsos positivos y negativos.

Ser entendible

Se ha de entender el proceso de decisión del sistema. Si no se entiende se corre el riesgo de estar tomando decisiones basadas en datos anecdóticos o sesgos en los datos del entrenamiento.

Para estar seguro de esto un humano experto ha de ser capaz de entender el funcionamiento del sistema y las decisiones que toma..

Ofrecer explicaciones

Tiene doble función, primero ayudar al punto anterior y segundo que la persona que ha sido evaluada por el sistema sepa que motivos han llevado a considerarla “apta” o “no apta”.

Puede parecer que con que un sistema ofrezca un resultado es suficiente, pero la realidad es que no lo es. Si no sabes porque estas descartando a una persona no puedes decirselo y esta persona no sabe que tiene que cambiar para “pasar la prueba”.

Resulta algo extremadamente frustrarte. Si no sabes que tienes que cambiar la sensación es que “estas marcado de por vida”. Si una persona es informada de cuales han sido los motivos por los que es “no apta” puede valorar si trata de cambiarlos o no. Lo cual puede ser una ventaja para ambas partes. Imagínate que un banco te niega una hipoteca o un crédito por el único motivo de que no tienes un aval. Pero en realidad si que lo tienes o lo puedes pero no consta en los datos. Ambos estáis perdiendo una oportunidad beneficiosa.

Validación continua

Es necesario tener validación de su correcto funcionamiento permanentemente. Es fundamental comprobar que las conclusiones que ha tomado el sistema son correctas. La sociedad y el mundo cambia pudiendo hacer que el modelo quede obsoleto y falle si no se adapta correctamente. Hay que tener un mecanismo de revisión y validación para asegurarse de que sigue funcionando.

Asociado a esto tiene que tener un mecanismo de corrección. Si por ejemplo se descubre que el sistema tiene en cuenta algún dato que ya no se puede usar ha de poder descartarse este dato. En los últimos años hemos vivido varios cambios en las leyes sobre protección de datos. Un dato que se puede usar hoy en unos años puede ser ilegal usarlo, los sistemas han de ser capaces de adaptarse a eso.

Saber que datos nuestros se han usado

Tenemos derechos sobre nuestros datos y el mínimo de ellos es saber cuales se han usado y de donde provienen. Con más motivo si esos datos se usan para tomar decisiones sobre nosotros.

No solo saber que datos se usan, también El origen de los datos es importantes. La fuente que provee de datos pueden preferir cantidad a calidad y no verificarlos correctamente o ahorrar costes no verificando si datos de hace años aún son ciertos.

Muchas veces los datos tienen una historia detrás. No es lo mismo estar en una lista de morosos por tener varios créditos sin pagar que por tener pendiente una factura de un servicio tras discutir con el proveedor del mismo.

Gestión de casos extraordinarios

Solo con modelos muy simples el sistema acertará siempre. En el resto de las situaciones habrá casos extraordinarios que serán mal clasificados. Hay que saber como gestionar estos casos. No basta con justificarse en “lo dice el ordenador”. Tiene que haber formas de saber si estamos ante un caso mal clasificado y es el oráculo ha hecho mal su trabajo.

Objeciones

“Una empresa privada ¿Por qué ha de seguir estas reglas?” Primero porque trabaja en la sociedad y tiene que seguir sus reglas y colaborar en mantenerlas. Segundo porque estos sistemas tienen el riesgo de extenderse. Un sistema realmente bueno puede ser vendido como servicio, que las empresas empiecen a contratarlo y entonces afectaría a millones de personas.

“Si las estadísticas dicen que algo es así será por algo”. Si, obvio que es por algo. Pero antes de empezar a valorar a un grupo de personas por ser peores trabajadores o más delincuentes o menos confiables o cualquier prejuicio similar piensa que según las estadísticas un hospital es un lugar donde muere mucha gente y es mejor no ir y menos aún si estas enfermo. El que un hospital es un sitio peligroso para los enfermos es un prejuicio causado por un una visión parcial de la realidad fijándose solo en datos.

“Es un gran avance y puede producir un gran beneficio, no merece la pena frenarlo por unos pocos casos en os que resultaría injusto”. Lo de sacrificar a unos pocos para obtener un bien mayor ha justificado muchas barbaridades. No es una cuestión de prohibirlo, si no de buscar un equilibrio.

“Con el tiempo mejorara y alcanzara una precisión absoluta”. Es difícil que eso ocurra en los próximos años y posiblemente décadas. La realidad es demasiado compleja para separar fácilmente todos los casos sin cometer ningún error. De hecho incluso seria discutible que es un error y que no lo es.

Tablas de consulta (lookup table)

Más que un algoritmo de visión por computador es una forma de acelerar los cálculos. La idea es reemplazar todos los cálculos aplicados a un pixel por un simple acceso a memoria. Suena bien ¿verdad?. Se puede ganar bastante velocidad pero por desgracia está limitado y solo sirve para operaciones que afecten a un solo canal del pixel. Si el resultado se ve influido por algo más como la posición, el valor de los vecinos o del resto de los canales este método no sirve. Aun con estas limitaciones resulta útil para optimizar operaciones como el umbral, el ajuste de brillo y/o contraste o corrección del color.
Empecemos por la idea básica. A partir de ahora cuando hable de pixel me refiero a un pixel de un solo canal en escala de grises, para el caso de color RGB seria en realidad uno de los canales de color. Y habría que tener una tabla de consulta por cada canal.
Un pixel tiene un número limitado de valores, de 0 a 255. Eso significa que podemos precalcular esos 256 valores en una tabla y luego simplemente consultar el valor del pixel en esta en lugar de repetir los calculos para cada pixel.
Por tanto necesitamos generar una tabla con indices de 0 a 255. Calculamos el resultado para cada uno de los 256 posibles valores de un pixel. Cada resultado se almacenará en la posición correspondiente al valor original del pixel. Por ejemplo si nuestra funcion suma diez al valor del pixel, la tabla seria:
T[0]=10;
T[1]=11;

T[254]=255;
T[255]=255;
Si os fijais hay un detalle a tener en cuenta. Los valores de la tabla no pueden ser mayores de 255 que es el valor máximo de un pixel, tampoco pueden ser menores de 0, que es el valor mínimo.
Vale, ya tenemos los 256 valores posibles. Para usar esta tabla solo hemos de recorrer la imagen leyendo el valor de cada pixel y remplazarlo el valor que tenga la tabla para ese índice. Por ejemplo, para un pixel P con valor I y una tabla de consulta T
Image[P] = T[I]
Pero esto no es todo, puedes combinar varias de estas tablas en una sola tabla y calcular varias operaciones con un coste en tiempo ridiculo. Vamos a ver cómo.
Cuando operamos varias veces sobre un pixel de valor p realmente lo que estamos haciendo es.
funN(…func2(func1(p)))
Para cada cada pixel solo hay 256 valores posibles (del 0 al 255), eso quiere decir para cada función habra como mucho 256 resultados distintos. Si ademas limitamos que cada una de esas funciones solo pueda devolver valores entre 0 y 255. Podemos usar el resultado de una función como entrada de la siguiente. Por lo tanto podriamos precalcular esos 256 valores y convertir todas esas funciones en una sola que relacione cada valor del pixel con su resultado…efectivamente eso es lo mismo que hacer un array con los 256 resultados y usar el valor original como indice.
Repito, esto solo se cumple cuando sobre la función que aplicamos solo influye el valor del propio pixel y los valores que devuelve están comprendidos entre 0 y 255.

Si tenemos dos tablas de T1 y T2 calcular una tabla T3 que combine ambas en una sola operación es muy sencillo:

i = 0..255
T3[i]=T2[T1[i]];

Se pueden combinar tantas tablas como se quiera.

Aunque en los procesadores actuales resulta casi igual de rápido realizar un par de operaciones simples que recurrir a estas tablas, cuando se acumulan varias funciones en una sola tabla el aumento de rendimiento es más que apreciable.

Detectar nombres propios en un texto

En el análisis de un texto detectar los nombres propios es importante ya que aporta información de que se habla en el texto. Permite extraer nombres e personas empresas y de hecho es una tarea habitual en muchos sistemas inteligentes de gestión de documentos.

Empiezan por mayúscula

Detectar nombres propios en español parece una tarea sencilla, lo primero que se nos ocurre es: “Empiezan por mayúscula” y es cierto, cualquier palabra que empiece por mayúsculas en un texto es sospechoso de ser un nombre propio. As que nuestro primer paso es recopilar esas palabras.

No es suficiente con que empiece por mayúscula. Cualquier palabra al principio de una oración también empieza por mayúscula y precisame el principio de la oración es un lugar muy habitual para los nombres (propios o comunes). En ese caso la mayúscula no servirá de pista. Es necesario obtener la información de si una palabra “sospechosa de se un nombre” va o no al principio de una frase.

Pero no es el único caso en que una palabra que no sea un nombre propio empieza por mayúscula. Siglas, meses, días de la semana, notas musicales, cargos, períodos históricos….. Hay muchos casos en los que correcta o erróneamente (los días de la semana no deberían ir en mayúsculas pero no es raro verlos así) se suelen poner la letra inicial en mayúscula.

Siglas y acrónimos

Como caso especial están las siglas y acrónimos. El problema aquí es distinguir los que generalmente indican nombres propios de otros que no lo son, por ejemplo ONU, OTAN, USA son nombres propios mientras que SOS, WTF, OMG no lo son. Para distinguir siglas del resto de palabras de un texto es sencillo, están completamente escritas en mayúsculas y a veces tiene puntos entre ellas. Sin embargo, por motivos esteticos, puede darse el caso de encontrar siglas con minúsculas, sobre todos cuando son nombres de empresas.

Números Romanos

Son fáciles de confundir con las siglas. De hecho a veces son indistinguibles, por ejemplo CC puede ser 200 o significar “con copia”.

Los números romanos van sin punto al final y solo pueden contener las letras M,D,C,L,X,I.

Diccionarios

Necesitamos dos diccionarios, uno de palabras comunes que van en mayúsculas y no son nombres y otro de nombres.

Si una palabra empieza por mayúscula y está en el diccionario de nombres se puede considerar un nombre. Este diccionario a veces es difícil de crear ya que no se sabe que nombres se buscan, sin embargo cuando se sabe exactamente lo qué se busca puede ser una herramienta muy potente.

El diccionario de términos que pueden ir en mayúsculas y no son nombres es más genérico. Está formado por palabras que se suelen escribir en mayúsculas y otras que pueden ir al principio de una frase. Podemos incluir:

  • Meses del año
  • Días de la semana
  • Festivos
  • Notas musicales
  • Abreviaturas
  • Títulos, cargos y nombres de dignidad
  • Signos del zodíaco
  • Puntos cardinales
  • Siglas y acrónimos de nombres comunes o expresiones
  • Palabras que a veces se escriben con mayúsculas: patria, gobierno, biblia, dios,….
  • Onomatopeyas
  • Determinantes
  • Pronombres

Ojo que hay casos en que un nombre propio puede confundirse con alguno de los casos anteriores. Por ejemplo: Abril o Domingo son nombres de personas.

Hay que tener en cuenta que en el caso de los nombres compuestos pueden empezar por alguno de los elementos que están en este diccionario. Por ejemplo: “El Dorado, Los Ángeles”

Hay una mejora al diccionario de nombres y es añadir dinámicamente los nombres que vamos encontrando en el texto. Los nombres generalmente se repiten varias veces en el texto y puede ayudar a despejar las dudas sobre alguna palabra.

Palabras dudosas

Vamos a repasar los pasos que tenemos hechos hasta ahora.

  1. Seleccionar palabras que empiezan por mayúscula.
  2. Del paso anterior seleccionar aquellas que no están detrás de un punto o al inicio de una frase.
  3. Descartar excepciones usando reglas (como los números romanos) o el diccionario de palabras en mayúsculas que no son nombres.
  4. Las restantes del paso anterior se consideran nombres.
  5. Se añaden al diccionario de nombres
  6. Se toman las palabras del paso 1 que van detrás de un punto o al principio de una frase.
  7. Si están en el diccionario de nombres se consideran nombres.

Tras estos pasos nos quedan un conjuntos de palabras que no sabemos si son nombres o no. Podemos usar alguna heurística más como considerarlo un nombre si van dos palabras con mayúsculas seguidas o si son siglas.

Al final nos quedan palabras que dudamos si son nombres o no. Si el texto ha de pasar a revisión por un humano lo mejor es marcarlos como “posibles nombres”, si no hay más opciones que marcarlo como nombre o no hay que valorar que opción es menos costosa, detectar como nombres palabras que no lo son o dejarse nombres sin detectar.

Nombres compuestos

Por ahora hemos tratado los nombres como si solo fueran una palabra, pero eso es muy irreal, gran cantidad de nombres están compuestos por más de una palabra. Para detectarlos vamos juntar todos aquellas palabras que empiecen por mayúscula y vayan seguidas (sin otras palabras o signos de puntuación entre ellas).

Si una de esas palabras cumple los requisitos para ser nombre se extiende a las demás palabras en mayúsculas que la rodean.

Mejoras

Uno de los elementos más importantes de este enfoque son los diccionarios. Cuando el sistema solo va a trabaja con textos de una temática concreta unos buenos diccionarios pueden dar resultados muy exactos.

Algo parecido pasa con reglas propias para textos de ciertos ámbitos. Por ejemplo si se buscan nombres de empresas se podría usar como pista que terminen en “S.A.”, “S.L.”, “INC”, …

Hay nombres como los títulos de libros o películas que entrañan bastante dificultad ya que las reglas ortográficas dicen que tienen que ir en mayúsculas solo la primera palabra. Suelen ir entrecomilladas, en cursiva o en negrita, pero aún así no es un problema sencillo.

Inteligencia Artificial y los límites de la razón

En muchos artículos que leo se da por hecho que con los coches autónomos los accidentes desaparecerán y con ellos los seguros de coche que quedarán relegados a reparaciones y atención en carretera. Aunque muchas veces se de a entender lo contrario los primeros que celebrarían que esto ocurriese serían las aseguradoras, ellas ganan dinero cuando no hay accidentes. Desgraciadamente es una imagen irreal, los accidentes seguirán ocurriendo con los coches autónomos. En menor número ya que solo con eliminar los conductores cansados, temerarios, que miran el movil o bajo los efectos del alcohol o/y las drogas ya caerá bastante el número de accidentes. Pero seamos sinceros los buenos conductores, aquellos que están atentos, respetan todas las normas y son cautelosos lo hacen realmente bien. Los coches autónomos van a permitir gestionar y organizar el tráfico como nunca antes pero no van a ser perfectos. Vamos a usarlos como ejemplo para ver cuáles son los límites de la I.A.

Límites físicos para ejecución

Nuestro coche autónomo va circulando por una calle de un solo carril con coche aparcados a los lados cuando sin previo aviso aparece un viandante de detrás de una furgoneta a escasos tres o cuatro metros delante del coche. Por mucho que la I.A. frene la inercia va a arrastrar el coche hasta que atropelle al peatón, la otra opción es dar un volantazo y chocar con los coches aparcados. Ambas opciones son un accidente y es físicamente imposible evitarlo por muy eficaz que sea la I.A.

Límites físicos para el cálculo

Posiblemente el límite más conocido sea la capacidad de cálculo del sistema. Toda I.A. para ser útil ha de dar la respuesta en un tiempo finito y breve. Un sistema que tarde cuatrocientas millones de veces la vida del universo en dar una respuesta puede dar con la solución perfecta pero no resulta muy útil. Cuando juegas al ajedrez contra un software este responde con un movimiento suficientemente bueno pero no sé sabe si el mejor. En el caso de los coches autónomos cada elemento que tengan que “vigilar” aumenta la complejidad del problema (aumenta el espacio de búsqueda) y aumenta el tiempo que el sistema tiene que usar en detectarlo (reconocerlo, encontrar su límites, situarlo en el espacio, predecir su movimiento para anticiparse). Sin embargo el tiempo que tiene para reaccionar no aumenta.

Hay muchos más límites físicos, espacio, memoria, no-aleatoriedad, ….

Los sentidos nos engañan

O más bien “los sentidos están limitados”. Descartes creía que no podemos confiar plenamente en los sentidos ya que nos pueden engañar. Lo cierto es que percibimos el mundo a través de ellos y nos dan una percepción muy limitada de la realidad. Los sensores tienen límites de alcance, precisión, exactitud, cometen errores y por supuesto se estropean dando medidas falsas

La sonda Schiaparelli se estrelló al tratar de aterrizar en Marte, la causa un error en las medidas de un sensor debido a que se saturo por el ruido indicaba que estaba bajo tierra así que apagó los motores.

Un fallo un sensor fue también la causa de los problemasdel Boeing 737 max.

Incertidumbre

Hay algoritmos para tratar con la incertidumbre. Pero generalmente acaban trabajando con probabilidades y tratando de decidir valorando beneficios y costes respecto a lo probable que sean. Pero algo sea improbable no quiere decir que no vaya a ocurrir.

Un coche autónomo puede suponer que es improbable que un ciervo cruce la carretera de repente y lo atropelle, todos conducimos sin plantearnos cada segundo si un animal va a saltar sobre nuestro capó, pero sabemos que no es imposible y que ha se han dado casos.

Funcionamos con la suposición de que lo improbable no va a pasar, el coche de al lado no va a abalanzarse sobre nosotros sin previo aviso (incluso los conductores agresivos dejan claras sus intenciones confiando que los demás cedan por precaución y les dejen cambiarse), que nadie va a ir circulando en dirección contraria por mi carril o que los demás van a respetar el semáforo en el cruce. Por supuesto que a veces estas reglas se incumplen pero es tan improbable que difícilmente se pueden tener en cuenta si no hay otras señales que nos hagan pensar que es probable (el conductor de al lado hace unas “eses” sospechosas mientras trata de mantenerse en el carril o el coche que llega al cruce va demasiado rápido como para frenar de golpe en el semáforo).

Aprende de la experiencia

El aprendizaje máquina trata de sacar unas reglas generales a partir de un montón de ejemplos particulares. El problema está en que la I.A. no va a poder tratar casos que no haya “visto”. Por ejemplo una I.A. que ha aprendido a reconocer peatones puede fallar si el peatón va disfrazado de platano, por ejemplo. Eso no quiere decir que no tenga que frenar si se cruza, pero para la I.A. sería un obstáculo en la vía, no un peatón

Los agentes inteligentes están altamente especializados. Un programa que aprende a jugar al ajedrez no sirve para aprender a conducir. Los coches autónomos se mueven en el mundo real en una sociedad creada por humanos que tienen sus reglas de convivencia y un entorno muy complejo.

Por ejemplo algunos modelos de coches autónomos han tenido problemas con su forma de conducir porque marea a los pasajeros. Un conductor humano siente lo mismo que los pasajeros y evita sensaciones desagradables a los mismos (frenazos muy bruscos, giros repentinos, aceleraciones bruscas,…). Pero nadie había entrenado a la I.A. del coche para ello.

Otro ejemplo es el de un coche autónomo que buscando ahorrar dinero en lugar de aparcar en una zona de pago prefiera seguir circulando despacito de tal forma que el coste de circular sea menor que el del aparcamiento. Desde un punto de vista cívico eso es una barbaridad, consumir energía gratuitamente y empeorar el tráfico. Si la inteligencia no ha sido entrenada para tener en cuenta eso puede caer en soluciones erróneas.

Límites del sistema

Es parecido al punto de los límites físicos, pero en este caso los motivos no son físicos si no la organización o estructura del sistema. En muchos casos la solución es reorganizar el sistema pero eso queda más allá de las opciones del agente inteligente. Un ejemplo son algunos atascos. Hace años trabajé en un polígono industrial con solo dos salidas. Los viernes en verano la mayoría de las empresas salíamos entre las tres y las tres media de la tarde lo que suponía soportar atascos de 20 minutos. Y no hay forma de evitarlos. Aunque todos los coches fueran un agente inteligente y se coordinasen seguiría habiendo atascos. Se lo que estáis pensando: “Los coches se podrían coordinar para no intentar salir todos a la vez”. Pero la consecuencia es la misma que un atasco, me va a costar 20 minutos salir de ahí. Me da igual si estoy atascado o esperando con el coche o con el coche dando vueltas o esperando que me avise al móvil que ya podemos irnos.

Riesgos calculados

En la vida real hay que tomar riesgos. Generalmente por dos motivos, falta de información e imposibilidad de conseguirla o que no hay más remedio para evitar una situación peor.

Un ejemplo es llegar a un cruce donde un camión mal aparcado tapa la visión. El coche autónomo no puede quedarse parado hasta que retiren el camión. Tendrá que moverse lentamente minimizando los riesgos pero asumiendo que ni el ve ni es visto y eso podría causar un accidente.

Decisiones irracionales

Actualmente la inteligencia artificial no puede decidir si no tiene una forma de comparar opciones. Eso no quiere decir que no pueda simplemente elegir al azar una opción. El mismo problema tiene si varias opciones son igual de buenas.

Al final hemos diseñado la I.A. para que haga decisiones racionales pero la vida humana esta llena de decisiones no racionales.