• Publicidad

Cómo detectar poblaciones en un texto

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Cómo detectar poblaciones en un texto

Notapor crawler » 2011-08-15 06:31 @313

Hola a todos, soy nuevo en el foro y necesito un poco de ayuda.

Estoy tratando de realizar un programa que sepa reconocer las poblaciones de Cataluña en un texto cualquiera.

Tengo guardado como claves de un hash los nombre de las poblaciones y como valor un índice (1..947), para el tratamiento de poblaciones formadas por una sola palabra (ej. Reus, Girona, Sabadell), divido el texto por espacios y compruebo si existe en el hash.

Pero el problema lo tengo para reconocer las poblaciones formadas con más de una palabra, como por ejemplo: La Bisbal d'Empordà, El Vendrell etc...

Disculpad sino me he explicado muy bien y agradeceré cualquier ayuda o sugerencia.
crawler
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2011-08-15 06:05 @295

Publicidad

Re: Cómo detectar poblaciones en un texto

Notapor explorer » 2011-08-15 07:19 @346

Bienvenido a los foros de Perl en español, crawler.

Aquí hay varios problemas...

¿Qué método usas para realizar la búsqueda?

No nos lo dices, pero podemos hacer algunas suposiciones.

Para saber si un texto está dentro de otro, se suele usar (normalmente):
  • el operador lógico 'eq'
  • la función index() (o la rindex())
  • una expresión regular

Nos comentas que estás dividiendo el texto por los espacios, así que sospecho que estás usando el primer método, el del 'eq'. El problema está en que hay poblaciones con más de una palabra.

Lo podrías resolver complicando un poco más la estructura de datos, buscando por todas las palabras que componen cada población, ampliando el hash, y por cada población, además, saber cuántas palabras lo forman. Pero es que además, deberías llevar el control de si las palabras encontradas están juntas y en el orden adecuado. Desde luego, sería muy complicado, pero con esta solución podrías localizar poblaciones que están escritas "al revés", como por ejemplo, Bisbal d'Empordà, La (solo cambia una palabra de sitio, para dar más importancia a Bisbal).

Otra solución. Con index() puedes buscar si un texto está dentro de otro, y te devuelve la posición (empezando en 0) en donde se encuentre.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! /usr/bin/perl
  2. use common::sense;              # Hay que tener sentido común
  3. #use Modern::Perl;              # Somos modernos
  4. #use autodie;                   # es mejor morir que regresar con deshonor (proverbio Klingon)
  5. #use utf8;                      # este programa está escrito en utf8
  6. use open qw(:utf8 :std);        # la salida y la entrada estándar serán en utf8
  7.  
  8. my $texto = "
  9. Reus es una población de Cataluña, de Reus
  10. La Bisbal d'Empordà jhf sdkjfh sakdlfh sdkfh skhf sdkf dkjfh
  11. sdlkjfh sdlkjfh slkjfh sdklfjh sklfjh sdklfjh sdkjfh sdkfh
  12. ksdf kdjfh sdkfh sf El Vendrell fjdh fskdjfh skdjfh ksdjfh
  13. Gironaslkfj lkjf lskjf lsdkjf sdljf La Bisbal d'Empordà
  14. sldfj ljflsdkjf ";
  15.  
  16. my @poblaciones = (
  17.     'Reus', 'Girona', 'Sabadell',
  18.     "La Bisbal d'Empordà", 'El Vendrell',
  19. );
  20.  
  21. for my $población (@poblaciones) {
  22.     my $pos = 0;
  23.     while($pos = index($texto, $población, $pos) + 1 ) {
  24.         print "Población $población encontrada en posición $pos\n";
  25.     }
  26. }
  27. __END__
  28. Población Reus encontrada en posición 2
  29. Población Reus encontrada en posición 40
  30. Población Girona encontrada en posición 224
  31. Población La Bisbal d'Empordà encontrada en posición 45
  32. Población La Bisbal d'Empordà encontrada en posición 260
  33. Población El Vendrell encontrada en posición 185
  34.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Funciona, pero siempre y cuando las poblaciones estén escritas de la misma manera en que las tienes definidas en el array.

Pero no es perfecto. Fíjate que ha encontrado 'Girona', pero está "pegada" a la palabra que le sigue: index() no sabe distinguir entre palabras y espacios. Solo busca cadenas de caracteres. Y en algunos casos no nos servirá.

Otra solución, usando expresiones regulares.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! /usr/bin/perl
  2. use common::sense;              # Hay que tener sentido común
  3. #use Modern::Perl;              # Somos modernos
  4. #use autodie;                   # es mejor morir que regresar con deshonor (proverbio Klingon)
  5. #use utf8;                      # este programa está escrito en utf8
  6. use open qw(:utf8 :std);        # la salida y la entrada estándar serán en utf8
  7.  
  8. my $texto = "
  9. Reus es una población de Cataluña, de Reus
  10. La Bisbal d'Empordà jhf sdkjfh sakdlfh sdkfh skhf sdkf dkjfh
  11. sdlkjfh sdlkjfh slkjfh sdklfjh sklfjh sdklfjh sdkjfh sdkfh
  12. ksdf kdjfh sdkfh sf El Vendrell fjdh fskdjfh skdjfh ksdjfh
  13. Gironaslkfj lkjf lskjf lsdkjf sdljf La Bisbal d'Empordà
  14. sldfj ljflsdkjf sabadell df slkjf slfj El vendrell
  15. LA BISBAL D'EMPORDÀ Y REUS";
  16.  
  17. my @poblaciones = (
  18.     'Reus', 'Girona', 'Sabadell',
  19.     "La Bisbal d'Empordà", 'El Vendrell',
  20. );
  21.  
  22. for my $población (@poblaciones) {
  23.  
  24.     while ($texto =~ /\b$población\b/gsmi) {
  25.  
  26.         print "Población $población encontrada en posición ", pos($texto), "\n";
  27.     }
  28. }
  29.  
  30. __END__
  31. Población Reus encontrada en posición 5
  32. Población Reus encontrada en posición 43
  33. Población Reus encontrada en posición 356
  34. Población Sabadell encontrada en posición 303
  35. Población La Bisbal d'Empordà encontrada en posición 63
  36. Población La Bisbal d'Empordà encontrada en posición 278
  37. Población La Bisbal d'Empordà encontrada en posición 349
  38. Población El Vendrell encontrada en posición 195
  39. Población El Vendrell encontrada en posición 329
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Fíjate, que además de encontrar todas las posiciones anteriores, podemos:
  • saber cuándo es una palabra separada de las demás (Girona ya no se encuentra, porque en el texto aparece como Gironaslkfj)
  • no importa si está escrito en mayúsculas o no (última línea del $texto) o mezclado (el caso de "El vendrell")

Yo te recomiendo que mires esta opción de usar expresiones regulares (aparte que es muy sencilla: solo buscamos por $población, separada del texto del $texto por \b, que marca los límites de una palabra. Y la buscamos independientemente de si está en mayúsculas o no (/i).

Atento a la codificación de caracteres que estés usando... eso también influye.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Cómo detectar poblaciones en un texto

Notapor crawler » 2011-08-15 10:37 @484

Muchas gracias explorer por tu rapidez y tu solución, te explico que antes he sido muy directo.

Estoy realizando una araña que ya es capaz de extraer de los canales culturales de sindicalizacion, el texto del titular, un texto que yo le llamo "información" ( normalmente informa de la fecha, hora y lugar publicados por el autor) y el texto puramente de la noticia.

Bien a partir de estos campos necesito comprobar si alguno de estos contiene la población para más tarde geolocalizar el evento.

Normalmente en la mayoría de noticias, el texto "información" facilita el nombre de la población,

Para realizar la búsqueda, separo el texto del campo "información" por espacios y compruebo si existe como llave del hash que contiene las poblaciones, este criterio solo sirve para encontrar las poblaciones de un palabra y computacionalmente hablando es eficiente.

ej:
@palabras_informacion = split(/\s+/, $text_informacion);

foreach my $i (@palabras_informacion)
{
if( exists ( $municipios{$i}) )
{
$ubicacion = $i;
print "Trobat per clau -> text_info: $ubicacion\n";
last;
}
}



El último criterio es buscar dentro del texto de la noticia.

Como bien dices, con expresiones regulares puedo casi reconocer en el texto si hay una población pero realmente es complejo ya que existen demasiadas ambigüedades y ocurrencias.

De todas formas te agradezco muchísimo tus consejos y tu tiempo, creo que seguiré por el camino de las expresiones regulares.
crawler
Perlero nuevo
Perlero nuevo
 
Mensajes: 2
Registrado: 2011-08-15 06:05 @295

Re: Cómo detectar poblaciones en un texto

Notapor pvaldes » 2011-08-17 18:44 @822

Yo no separaría el texto en palabras, de hecho igual haría justo lo contrario.

Me explico:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
"Caminando por El Vendrell, siguiendo la carretera encontramos el pueblo del Ven-
drell"
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Hay dos problemas aquí.

Pero si quitamos todos los espacios en blanco, los saltos de carro y los guiones y encima pasamos todo a minúsculas.

"caminandoporelvendrell,siguiendolacarreteraencontramoselpueblodelvendrell"

Aparecen ambas citas,

Es una postura extrema desde luego, simplemente para poner de manifiesto que tienes que considerar la posibilidad de que se inserte un guión traicionero y un salto de línea.
pvaldes
Perlero nuevo
Perlero nuevo
 
Mensajes: 129
Registrado: 2011-01-22 12:56 @580


Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 8 invitados