Script Performant de Densité de mots clefs

Script Performant de Densité de mots clefs - PHP - Programmation

Marsh Posté le 08-04-2009 à 13:47:38    

Bonjour, je suis à la recherche d'un script performant retournant la densité de mots clefs d'un texte
Mon exemple est simple, un texte de 54ko, par ma méthode actuelle, prend 1200ms à retourner les occurences de mots clefs à 3 mots et 2 mots ..
ce qui force l'usage d'un cache ..

 

Qq'un aurait-il une idée lumineuse pour m'aider ?

Code :
  1. for($i=0;$i<count($x)-2;$i++){#echantillon, $x=split(" ",$texte);
  2.       $kw=$x[$i]." ".$x[$i+1]." ".$x[$i+2];
  3.       if(count(array_intersect(array($x[$i],$x[$i+2]),$common))>0)continue;
  4.       if(strlen($x[$i])>1 AND strlen($x[$i+1])>1 AND strlen($x[$i+2])>1 AND strlen($kw)>10){$out[$kw]+=3;}
  5. }


Ces boucles prennent bcp de temps, je trouve ma facon de procéder assez moche ..


Message édité par grosbin le 08-04-2009 à 14:11:00

---------------
Photos Panoramiques Montagnes Haute Savoie
Reply

Marsh Posté le 08-04-2009 à 13:47:38   

Reply

Marsh Posté le 08-04-2009 à 14:16:09    

tu stockes le tout en base déjà, au lieu de le foutre en ram
au passage , tu dois splitter aussi sur tout ce qui n'est pas des lettres


---------------

Reply

Marsh Posté le 08-04-2009 à 14:38:33    

exact je procède avec des caches, je recherche à optimiser le premier passage ..
en soit la boucle ci-dessus
Je pense procèder de la sorte

Code :
  1. $occurences=array_count_values($x);asort($oc);
  2. foreach($occurences as $k=>$v){
  3.   if($v>1 AND strlen($k)>1)continue;
  4.   $unset[]=$k;
  5. }
  6. $x=array_diff($x,$unset);


au départ x fait 8314 valeurs
unset=1433
restent 5817 valeurs

 

Par tatonnement, en réduisant le tableau des mots clefs en input le script gagne en rapidité de 50%
la boucle reste à mon gout trop gourmande


Message édité par grosbin le 08-04-2009 à 15:01:08

---------------
Photos Panoramiques Montagnes Haute Savoie
Reply

Marsh Posté le 08-04-2009 à 17:19:38    

Si je suis bien :
$x est un tableau qui contient les mots de ton texte. Genre (à partir de ton premier message) :

Code :
  1. $x = ("Bonjour","je","suis","à","la","recherche","d","un","script",...);


Et ce que tu veux, c'est compter combien tu as de "trinômes" identiques dans ton texte:
"Bonjour je suis" => 5
"je suis à" => 2
etc.
Pour au final trouver les trinômes les plus fréquents.
Et en plus tu veux fixer des conditions (en supprimant les mots à un caractère et les "trinômes" de moins de 10 caractères).
 
Du coup, dans ton message "Bonjour, je suis à la recherche d'un script performant", on comptabiliserait :

  • bonjour je suis
  • un script performant

C'est bien ça ?
Par contre tu ne précises pas si tu veux avoir la liste complète des occurences, ou juste les N premiers...
 
Ce que je constate :
- Sur un texte de N mots, il y a N-2 "trinômes"  
Du coup, plus le texte est petit, moins il y a de trinômes par rapport au nombre de mots.
Un texte de 1000 mots donnera 998 trinômes.
10 textes de 100 mots donnera 10 * 98 trinômes = 980 trinômes
- Un trinôme contenant un mot de un caractère est viré.
- Un trinôme contenant un mot n'apparaissant qu'une seule fois est viré.
=> Ca peut être intéressant de découper le texte pour travailler sur plusieurs textes plus petits, avant de recombiner les résultats.
 
 
Dans ce cas, j'aurais tendance à procéder de cette manière :
1. Compter le nombre d'occurence de chaque mot.
2. Scinder le texte original sur les mots à un caractère ET les mots ayant une seule occurence.
POUR CHAQUE "morceau" de texte :
  2.1 Créer un tableau des trinômes
  2.2 Compter le nombre d'occurences des trinômes
  2.3 Comptabiliser le résultat dans un tableau général.
  (Si tu ne veux que les N premiers résultats tu peux encore scinder le texte sur les mots qui apparaissent moins souvent que le N-ième trinôme)
 
A savoir :
- Pour créer le tableau des mots, preg_split est plus rapide que split. Sinon, explode fait encore mieux si on n'a pas besoin d'expressions régulières.
- Voir la fonction str_word_count (avec le paramètre format à 1)

Reply

Marsh Posté le 08-04-2009 à 17:38:25    

Merci à toi c'est parfaitement ce qu'il se passe dans la globalité :)

 

str_word_count est en effet le plus rapide ..
C'est au moment de constituer les trinomes, avec un array de 8000 elements que cela se met à ralentir ..
l'intérieur de la boucle et rapide, contrairement à ses répétitions

 

En amont je nettoye le tableau

Code :
  1. $oc=array_count_values($x);asort($oc);
  2. foreach($oc as $k=>$v){
  3.   if(strlen($k)>1 AND $v>3)continue;//à conserver
  4.   $z[]=$k;
  5. }
  6. $x=array_diff($x,$z);


Puis La constitution de mes trinômes & binômes donc je suis peu sastisfait .. 0,13 ms par passage en moyenne .. avec 8700 mots clefs c'est amusant ..

Code :
  1. foreach($x as $v){$i++;
  2.     $n=$n2;$n2=$n3;$n3=$v;  $kw2="$n $n2";  $kw3="$n $n2 $n3";
  3.     if(!strpos($data,$kw2) or count(array_intersect(array($n,$n2),$common))!=0)null;
  4.       elseif(strlen($n)>2 AND strlen($n2)>2 AND strlen($kw2)>9){$out[$kw2]+=2;}
  5.     if(!strpos($data,$kw3) or count(array_intersect(array($n,$n3),$common))!=0)null;
  6.       elseif(strlen($n)>1 AND strlen($n2)>1 AND strlen($n3)>1 AND strlen($kw3)>10){$out[$kw3]+=3;}
  7.     if($i>5000 OR array_product($out)>12000 OR array_sum($out)>50){break;}
  8.   }


A cause de sa condition de sortie .. j'espère trouver d'autres fonctions permettant d'associer les binomes, trinomes, plus rapidement, peu être aussi, sans boucle

 

Nb: $common empêche de créer des association commencant par des mots "stupides" tels que "alors" etc..
une fonction php magique existe-elle ? une sorte de levenshtein recursif dans un preg_match ?


Message édité par grosbin le 08-04-2009 à 18:15:04

---------------
Photos Panoramiques Montagnes Haute Savoie
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed