2009-08-18 7 views
11

Je dois nettoyer certaines entrées de l'OCR qui reconnaît l'écriture manuscrite comme du charabia. Des suggestions pour une regex pour nettoyer les caractères aléatoires? Exemple:Regex pour remplacer le charabia


 
Federal prosecutors on Monday charged a Miami man with the largest 
case of credit and debit card data theft ever in the United States, 
accusing the one-time government informant of swiping 130 million 
accounts on top of 40 million he stole previously. 

, ':, Ie 
':... 11'1 
. '(.. ~!' ': f I I 
. " .' I ~ 
I' ,11 l 
I I I ~ \ :' ,! .~ , .. r, 1 , ~ I . I' , .' I ,. 
, i 
I ; J . I.' ,.\) .. 
. : I 
'I', I 
.' ' 
r," 

Gonzalez is a former informant for the U.S. Secret Service who helped 
the agency hunt hackers, authorities say. The agency later found out that 
he had also been working with criminals and feeding them information 
on ongoing investigations, even warning off at least one individual, 
according to authorities. 

eh....l 
~.\O ::t 
e;~~~ 
s: ~ ~. 0 
qs c::; ~ g 
o t/J (Ii ., 
::3 (1l Il:l 
~ cil~ 0 2: 
t:lHj~(1l 
. ~ ~a 
0~ ~ S' 
N ("b t/J :s 
Ot/JIl:l"-<:! 
v'g::!t:O 
-....c...... 
VI (:ll <' 0 
:= - ~ 
< (1l ::3 
(1l ~ ' 
t/J VJ ~ 
Pl 
..... 
.... 
(II 
+3

+1 parce qu'il est une question intéressante, même si je pense que vous ne serez pas obtenir une réponse qui fonctionne. –

+0

C'est une bonne question, et la reconnaissance de mots/phrases (ou l'inverse) est un sujet brûlant dans le cadre de l'IA. – Russell

+1

Je crois fortement qu'un REGEX est le mauvais outil pour ce travail. – Breton

Répondre

0

Eh bien un groupe de symboles correspondrait un peu de charabia. Peut-être vérifier contre un dictionnaire pour les mots?

Il semble y avoir beaucoup de sauts de ligne là où il y a du charabia, ce qui peut aussi être un indicateur.

+0

J'ai fait quelques recherches à Uni il y a quelques années sur l'extraction de phrases (vous faites plutôt le contraire). Il y a beaucoup d'articles (par exemple: http://portal.acm.org/citation.cfm?id=1097059) dessus mais malheureusement il n'y a pas de solution unique "hit-all". – Russell

0

Problème intéressant. Si cela est représentatif, je suppose que vous pourriez construire une bibliothèque de mots communs et supprimer toute ligne qui ne correspond à aucun d'entre eux. Ou peut-être pourriez-vous faire correspondre les caractères et les caractères de ponctuation et voir s'il y a une coupure de rapport fiable, ou simplement une fréquence d'occurrence de certains caractères qui la marque comme du charabia. Quoi qu'il en soit, je pense qu'il va falloir avoir une certaine logique de programmation, pas simplement une simple expression régulière.

0

Je suppose qu'une regex n'aiderait pas ici. Regex correspondrait essentiellement à une entrée déterministe, c'est-à-dire qu'une regex aura un ensemble prédéfini de motifs qu'elle va correspondre. Et le charabia serait dans la plupart des cas aléatoire. Une façon serait d'inverser le problème, c'est-à-dire de faire correspondre le texte pertinent au lieu de correspondre au charabia.

1

L'une des solutions SimpleSet (ne comportant pas de regexpes):

#pseudopython

number_of_punct = somme ([1 si c.ispunct() sinon 0 pour c en ligne])

si number_of_punct> len (ligne)/2: ligne_is_garbage()

bien. Ou regexpish grossier s/[! '"@ # ~ $%^&] {5,} // g

+0

Qu'en est-il de cette ligne:, i – Breton

+0

Rien. Retirez-le à la main plus tard. Ne vous attendez pas à ce que l'heuristique enlève toutes les ordures. Proverbe du jour: "Ne pas jeter le bébé avec l'eau du bain". – maykeye

1

Regex ne va pas aider ici. Je dirais que si vous avez le contrôle sur la partie de reconnaissance, alors se concentrer sur une meilleure qualité là:

Vous pouvez également demander à l'utilisateur de vous aider et de spécifier le type de texte avec lequel vous travaillez, par exemple si c'est une page d'un livre alors vous vous attendez à ce que la majorité des lignes soient les mêmes longueur et principalement composé de lettres, d'espaces et de ponctuation

0

Je revendiquerais une expression régulière comme «n'importe quelle ponctuation suivie de n'importe quoi sauf un espace est un spam».

Ainsi, dans .NET, il est peut-être quelque chose comme

.Replace("\\p{1,}[a-zA-Z0-9]{1,}", ""); 

alors vous considérez comme « un mot avec deux ponctuations ou plus consécutivement:

.Replace(" \\p{2,} ", ""); 

On dirait un bon début de toute façon.

+0

> Je demanderais une regex comme "n'importe quelle ponctuation suivie de n'importe quoi sauf un espace est spam." Pas toujours, cependant, certains noms de famille ont des traits d'union, pas seulement des noms de famille (pensez à moi-même). quotes "commence par la ponctuation – maykeye

+0

Vrai, alors n'incluez pas la double citation dans cette partie de la regex Je ne pense pas qu'il cherche un système infaillible, juste quelque chose à faire une 'première coupe' –

+0

Je ne suis pas d'accord. ... :-) –

2

Une heuristique simple, similaire à anonymous réponse:

listA = [0,1,2..9, a,b,c..z, A,B,C,..Z , ...] // alphanumerical symbols 
listB = [[email protected]$%^&...] // other symbols 

Na = number_of_alphanumeric_symbols(line) 
Nb = number_of_other_symbols(line) 

if Na/Nb <= garbage_ratio then 
    // garbage 
+0

Cela suppose que toute la ligne soit corrompue ou non, mais selon l'échantillon, c'est une chose raisonnable à supposer –

+0

oui, c'est pour filtrer les lignes entières. avec le texte * normal * ne sera pas si simple :-) –

2

Aucune idée comment cela fonctionnerait, mais je l'ai examiné ce problème dans le passé, les bras croisés. J'ai parfois joué avec un petit dispositif programmatique appelé markov chain

Maintenant, l'article de wikipedia n'aura probablement pas beaucoup de sens jusqu'à ce que vous voyiez certaines des autres choses pour lesquelles une chaîne markov est bonne. Un exemple d'une chaîne markov en action est ce Greeking generator. Un autre exemple est le MegaHAL chatbot.

Grec est un charabia qui ressemble à des mots. Les chaînes de Markov fournissent un moyen de générer aléatoirement une séquence de lettres, mais en pondérant les choix aléatoires pour émuler les modèles de fréquence d'un corpus examiné. Ainsi, par exemple, Étant donné la lettre "T", la lettre h est plus susceptible de s'afficher que toute autre lettre. Donc, vous examinez un corpus (disons certains journaux, ou blogues) pour produire une sorte d'empreinte de la langue que vous ciblez.

Maintenant que vous avez cette table de fréquence/empreinte digitale, vous pouvez examiner votre exemple de texte et noter chaque lettre en fonction de la probabilité qu'elle apparaisse. Ensuite, vous pouvez marquer les lettres sous un seuil particulier probabilités de suppression. En d'autres termes, un filtre surprise. Filtrer les surprises.

Il existe une marge de manœuvre pour la génération de vos tables de fréquence. Vous n'êtes pas limité à une lettre après l'autre. Vous pouvez construire une table de fréquence qui prédit quelle lettre suivra vraisemblablement chaque digraphe (groupe de deux lettres), ou chaque trigraph, ou quadgraph. Vous pouvez travailler de l'autre côté, prédisant des trigraphes probables et improbables à apparaître dans certaines positions, compte tenu du texte précédent.

C'est un peu comme une regex floue. Plutôt que MATCH ou NO MATCH, le texte entier est noté sur une échelle mobile en fonction de la similarité avec votre texte de référence.

1

J'ai fait un combo d'éliminer les lignes qui ne contiennent pas au moins deux mots de 3 lettres, ou un mot de 6 lettres.

([az | AZ] {3,} \ s) {2,} | ([az | AZ] {6,})

http://www.regexpal.com/

+0

J'ajouterais une comparaison de dictionnaires pour m'assurer que les mots trouvés sont réels et pas seulement des lettres aléatoires. –

0

J'aime @ réponse de Breton - Je d suggérer d'utiliser son approche du corpus avec une bibliothèque de «mauvaises analyses» connues, qui pourrait être plus facile à identifier parce que «indésirable» a plus de cohérence interne que «bon texte» s'il provient de mauvaises analyses OCR (le nombre de glyphes distincts est plus bas par exemple).

0

Une autre bonne technique consiste à utiliser un vérificateur d'orthographe/dictionnaire et à rechercher les «mots» après avoir éliminé les choses illisibles avec regex.

1

Voici une implémentation Perl de l'heuristique garbage_ratio:

#!/usr/bin/perl 

use strict; 
use warnings; 

while (defined(my $chunk = read_chunk(\*DATA))) { 
    next unless length $chunk; 

    my @tokens = split ' ', $chunk; 
    # what is a word? 
    my @words = grep { 
     /^[A-Za-z]{2,}[.,]?$/ 
      or /^[0-9]+$/ 
      or /^a|I$/ 
      or /^(?:[A-Z][.])+$/ 
    } @tokens; 

    # completely arbitrary threshold 
    my $score = @words/@tokens; 
    print $chunk, "\n" if $score > 0.5; 
} 

sub read_chunk { 
    my ($fh) = @_; 
    my ($chunk, $line); 

    while (my $line = <$fh>) { 
     if($line =~ /\S/) { 
      $chunk .= $line; 
      last; 
     } 
    } 

    while (1) { 
     $line = <$fh>; 
     last unless (defined $line) and ($line =~ /\S/); 
     $chunk .= $line; 
    } 

    return $chunk; 
} 


__DATA__ 

collez le texte ci-dessus après __DATA__ ci-dessus (ne pas répéter le texte ici pour gagner de l'espace). Bien sûr, l'utilisation de la section __DATA__ est dans le but de poster un script autonome. Dans la vraie vie, vous auriez du code pour ouvrir le fichier, etc.

Sortie:

 
Federal prosecutors on Monday charged a Miami man with the largest 
case of credit and debit card data theft ever in the United States, 
accusing the one-time government informant of swiping 130 million 
accounts on top of 40 million he stole previously. 

Gonzalez is a former informant for the U.S. Secret Service who helped 
the agency hunt hackers, authorities say. The agency later found out that 
he had also been working with criminals and feeding them information 
on ongoing investigations, even warning off at least one individual, 
according to authorities.
Questions connexes