tabla paleta hexadecimales código colores codigo buscador barra amarillo algorithm colors string-metric

algorithm - paleta - tabla de codigo de colores



Asignación de cadenas arbitrarias a valores RGB (8)

Tengo un gran conjunto de cadenas de lenguaje natural arbitrarias. Para que mi herramienta los analice, necesito convertir cada cadena en un valor de color único (RGB u otro). Necesito que el contraste de colores dependa de la similitud de las cuerdas (cuanta más cuerda sea diferente de la otra, más diferentes serán sus respectivos colores). Sería perfecto si siempre obtuviera el mismo valor de color para la misma cadena.

¿Algún consejo sobre cómo abordar este problema?

Actualización sobre la distancia entre cadenas

Probablemente necesito "similitud" definida como una distancia similar a Levenstein. No se requiere un análisis de lenguaje natural.

Es decir:

"I am going to the store" and "We are going to the store"

Similar.

"I am going to the store" and "I am going to the store today"

Similar también (pero ligeramente menos).

"I am going to the store" and "J bn hpjoh up uif tupsf"

Bastante no similar

(Gracias, Welbog !)

Probablemente sabría exactamente qué función de distancia necesito solo cuando vea la salida del programa. Así que comencemos con cosas más simples.

Actualización sobre simplificación de tareas

He eliminado mi propia sugerencia para dividir la tarea en dos: cálculo absoluto de la distancia y distribución del color. Esto no funcionaría bien ya que al principio estamos reduciendo la información dimensional a una única dimensión y luego intentamos sintetizarla hasta en tres dimensiones.


Necesita elaborar más sobre lo que quiere decir con "cadenas similares" para obtener una función de conversión adecuada. Son las cuerdas

"I am going to the store" and "We are going to the store"

considerado similar? ¿Qué hay de las cuerdas?

"I am going to the store" and "J bn hpjoh up uif tupsf"

(todas las letras en el original +1), o

"I am going to the store" and "I am going to the store today"

? En función de lo que quiere decir con "similar", podría considerar diferentes funciones.

Si la diferencia puede basarse únicamente en los valores de los caracteres (en Unicode o en cualquier espacio de donde provengan), puede intentar sumar los valores y usar el resultado como un matiz para el espacio HSV. Si tener una cadena más larga debería hacer que los colores fueran más diferentes, podría considerar ponderar los caracteres por su posición en la cuerda.

Si la diferencia es más compleja, como por la aparición de ciertas letras o palabras, entonces necesita identificar esto. Tal vez pueda decidir valores rojos, verdes y azules en función de la cantidad de Es, Ss y Rs en una cadena, si su dominio tiene muchos de estos. O elija un matiz basado en la proporción de vocales a consonantes, o palabras a sílabas.

Hay muchas, muchas formas diferentes de abordar esto, pero la mejor depende realmente de lo que quiere decir con cadenas "similares".


Parece que quieres un hash de algún tipo. No es necesario que sea seguro (por lo tanto, nada tan complicado como MD5 o SHA), sino algo así como:

char1 + char2 + char3 + ... + charN % MAX_COLOUR_VALUE

funcionaría como un simple primer paso. También podría hacer cosas más elegantes en la línea de hacer que cada personaje actúe como una "amplitud" para R, G y B (e podría ser + 1R, + 2G y -4B, etc.) y luego simplemente sumar todos los valores en una cuerda ... apriétalos al final y tienes un método para convertir cadenas de longitud arbitraria en colores como un tipo de proceso ''hash de color''.


Primero, deberá elegir una forma de medir la similitud de las cadenas. La distancia de edición mínima es tradicional, pero no es suficiente para ordenar bien las cadenas, que es lo que necesitará si desea asignar los mismos colores a las mismas cadenas cada vez; quizás podría ponderar los costos de edición por distancia alfabética. También la distancia de edición mínima por sí sola puede no ser muy útil si lo que buscas es similitud en el habla en lugar de en forma escrita (si es así, considera un pase de derivación / soundex primero), o algún otro sentido de "similitud".

Luego debe elegir una forma de atravesar el espacio de color visible en función de esa métrica. Puede ser útil considerar el uso de la representación de color HSL o HSV ; el algoritmo podría ser tan simple como elegir un tono inicial y recorrer el corpus ordenado, asignando el matiz actual a cada cuerda antes de compensarla por la diferencia de la cuerda con respecto al anterior.


Tal vez defina algún delta entre dos cadenas. No sé lo que define como la diferencia (o "desigualdad") de dos cadenas, pero lo más obvio que podría pensar sería la longitud de la cadena y el número de ocurrencias de letras en particular (y su índice en la cadena) . No debería ser complicado implementarlo de modo que devuelva el mismo código de color en cadenas iguales (si hace un primer igual, y regresa antes de una comparación posterior).

Cuando se trata del valor RGB real, trataría de convertir los datos de la cadena en 4 bytes (RGBA), o 3 bytes si solo usa el RGB. No sé si cada cadena encajaría en ellos (¿puede ser específico del idioma?).


Lo sentimos, pero no puedes hacer lo que estás buscando con distancia levenshtein o similar. RGB y HSV son espacios geométricos tridimensionales, pero la distancia levenshtein describe un espacio métrico: un conjunto mucho más flexible de contstraints sin un número fijo de dimensiones. No hay forma de asignar un espacio métrico en un número fijo de dimensiones conservando siempre la localidad.

Sin embargo, en lo que se refiere a las aproximaciones, para los términos individuales podría usar una modificación de un algoritmo como soundex o metaphone para elegir un color; para términos múltiples, podría, por ejemplo, aplicar soundex o metaphone a cada palabra individualmente, luego sumarlos (con desbordamiento).


¿Qué tan importante es que nunca termines con dos cuerdas diferentes que tengan el mismo color?

Si no es tan importante, entonces ¿podría funcionar?

Puede elegir un espacio de color de 1 dimensión que sea "homotópico" para el círculo: supongamos que la función de color c(x) se define para x entre 0 y 1 . Entonces querrías c(0) == c(1) .

Ahora toma la suma de todos los valores de los caracteres modulo algún factor de escala y envuélvalo de nuevo al espacio de color:

c( (SumOfCharValues(word) modulo ScalingFactor) / ScalingFactor )

Esto podría funcionar aún mejor si definió un espacio de color "envolvente" de dimensiones superiores y para cada dimensión elija SumOfCharValues función SumOfCharValues diferente; alguien sugirió suma y longitud alternas.

Solo un pensamiento ... HTH


Aquí está mi sugerencia (creo que hay un nombre general para este algoritmo, pero estoy demasiado cansado para recordarlo):

Desea transformar cada cadena en un nodo de punto 3D (r, g, b) (puede escalar los valores para que se ajusten a su rango) de modo que se minimice el siguiente error:

Error = /sum_i{/sum_j{(dist(node_i, node_j) - dist(str_i, str_j))^2}}

Puedes hacerlo:

  1. Primero asigne a cada cuerda un color aleatorio (r, g, b)
  2. Repita hasta que le parezca adecuado (por ejemplo, el error se ajusta menos de / epsilon = 0.0001):
    1. Elige un nodo aleatorio
    2. Ajuste su posición (r, g, b) de manera que el error se minimice
  3. Escale el sistema de coordenadas de modo que cada una de las coordenadas de los nodos esté en el rango [0., 1.) o [0, 256]