[spip-dev] Indexer les mots de 3 lettres

Bonjour,

La question a été déjà posée mais j'ai eu beau explorer les archives je n'ai
pas trouvé trace de la réponse. Je souhaite faire indexer les mots de 3
caractères par le moteur de recherche a lieu du seuil de 4 caractères fixé
en standard dans spip.

J'ai suivi l'indication de Fil concernant la modif de $min_long=2 dans
/ecrire/inc_index.php3 + vidé le cache + effacé les index... mais cela n'a
pas résolu la question... le moteur persiste à n'indexer que les mots de
plus de 3 caractères

Quelqu'un a-t-il une idée sur comment on peut faire ce "réglage" (version
1.3)

Merci, cordialement

@ Patrice Bourlon <patrice.bourlon@online.fr> :

J'ai suivi l'indication de Fil concernant la modif de $min_long=2 dans
/ecrire/inc_index.php3 + vidé le cache + effacé les index... mais cela n'a
pas résolu la question... le moteur persiste à n'indexer que les mots de
plus de 3 caractères

Non: le moteur indexe maintenant les mots de 3 lettres. Mais l'indexation et
la recherche sont deux procédés séparés...

Pour que la recherche se fasse, il faut aller modifier la valeur '3' dans
inc-calcul-squel.php3, vers les lignes 1500 et quelque :

            unset($h);
            while (list(, $val) = each($s)) {
                if (strlen($val) > 3) {
                    $dico[] = "dico LIKE \"$val%\"";

-- Fil

Le problème d'effectuer des recherches contenant les mots de 3 lettres (et pourquoi pas moins?), c'est que la recherche se retrouve perturbée par des mots "parasites" qui ne sont pas du tout pertinents. Le choix de 4 lettres minimum est un pis-aller, mais sinon, il faudrait créer un dictionnaire d'exclusion (les mots à ne pas indexer, ou alors à indexer avec un poids minoré).

Par exemple, si tu cherches:
"publier sur internet"

les mots pertinents sont: "publier" et "internet". Avec ça, tu obtiendras d'excellents résultats, parce que ces mots ne sont pas très fréquents dans le site. En revanche, si tu prends en compte "sur" dans ta recherche, tu obtiendras tous les articles contenant beaucoup de fois le mot "sur"; ce qui concerne presque tous les articles. Et ce mot, non pertinent, primera alors (de par son poids énorme dans tous les articles), sur "publier" et "internet". Tu voudras les articles contenant "publier" et "internet", et à la place, tu auras "Sur l'eau ou sur la terre?" et autres articles faisant un gros usage du mot "sur"...

Du coup, cette limite est ce qui permet d'avoir un moteur présentant des résultats cohérents.

La seule autre solution, ce serait donc de créer une liste des mots (conjonctions, etc.) qui n'ont pas de sens en eux-mêmes, et qu'il ne faudrait pas indexer. Bon, ben reste plus qu'à analyser un dico de scrabble et à répertorier tous les mots de ce genre; et quand on fera la version multilingue, créer ces listes pour toutes les langues du monde (en comptant que, pour l'instant, le moteur actuel est cohérent déjà en allemand, en espagnol, enfin bref, certainement la mojorité des langues écrites du monde... et qu'il deviendra incohérent pour toutes les langues pour lesquelles on n'aura pas établi de liste).

ARNO*

Bonjour,

Pourquoi 3 lettres parce qu'il y a de nombreux acronymes qui font seulement
3 lettres... beaucoup moins avec seulement 2... mais c'est vrai que cela
rajoute des articles, des prépositions, etc. pour moi c'est aussi un
pis-aller

Je comprends qu'il faut bien que les concepteurs de Spip mettent une limite
pour limiter le "bruit" compte tenu de la non-gestion des mots vides (et
j'imagine bien que c'est pas mal de boulot de mettre ça en place :slight_smile:

Il me semble cependant que la meilleure solution pour limiter le bruit
serait de faire une relation ET par défaut (implémentée sur Google et autres
à part AltaVista) : dans l'exemple que tu donnes 'publier sur Internet', la
relation ET ressortirait certainement des résultats plus signifiants que -
même avec une limitation à 4 caractères minimum - la requête qui reviendrait
en fait à 'publier OU internet'.

Cette relation OU est en ce qui me concerne le dernier gros défaut de la
fonction de recherche proposée actuellement... on pourrait aussi vouloir le
choix de la syntaxe et/ou/expression exacte mais à mon sens si le choix
n'est pas proposé il serait préférable de faire du ET.

Point de vue du pur utilisateur... j'ignore ce que cela entraîne comme
complications éventuelles en matière de développement :slight_smile:

Cordialement

Salut,

Cette relation OU est en ce qui me concerne le dernier gros défaut de la
fonction de recherche proposée actuellement... on pourrait aussi vouloir le
choix de la syntaxe et/ou/expression exacte mais à mon sens si le choix
n'est pas proposé il serait préférable de faire du ET.

Ce n'est pas un OU mais une pondération additive. 15 fois "Internet" est
plus pertinent que 5 fois "Internet" et 5 fois "publier", qui est plus
pertinent que 5 fois "Internet" ou "publier".

On peut toujours s'amuser à essayer de changer la fonction de pondération.
Ligne 45 dans ecrire/inc_index, il y a :

    $index[$h] += $val;

Tu peux essayer :

    $index[$h] = log(exp($index[$h]) + $val);

Ce qui donne un réel qu'il faut arrondir à la fin après multiplication par N
(256 ?), avant de le mettre dans la table. Ensuite la pondération additive
à chaque recherche fera que la concomittance de plusieurs termes de la
recherche fera beaucoup plus augmenter le score que le nombre d'occurences
de chacun des termes.

Mais il y aura toujours des gens pour trouver que l'une ou l'autre méthode
convient mieux. En plus il faut reprendre l'indexation à zéro pour que les
scores soient recalculés.

a+

Antoine.

Fil wrote:

mixte sympa qui mettra les ET avant les OU (on peut jouer sur la valeur de a
pour qu'un OU contenant 100 fois le mot "pomme" mais jamais "cerise" passe
devant un article à une "pomme" et une "cerise".

Le problème aussi c'est qu'un article contenant un mix de "pomme" et "pommes"
passera avant un article ne contenant que "pomme".

Alors la requête devient

    $req_select[] = "SUM(idx.points) AS points";
+ $req_select[] = "MULT(idx.points)+a*SUM(idx.points) AS score";

MULT(...) -> EXP(SUM(LOG(...)))

Le coût supplémentaire de traitement devrait être négligeable. (à vérifier).

Mmmm.

Fil wrote:

En quoi est-ce un problème ? En quoi est-ce plus un problème avec ce
scoring qu'avec l'autre ?

L'actuel n'a pas cet inconvénient :wink:

EXP(LOG(2) + LOG(0)), il sait faire mysql ? Vérification faite, oui, ça
fait NULL... Après, on peut trier {par score} en espérant qu'il mette les
NULL à la fin ?.. Ce serait tellement plus simple d'avoir un opérateur qui
fasse le produit des éléments d'une liste......

Y a pas de 0 dans la colonne points, par construction.

Y a pas de 0 dans la colonne points, par construction.

Euh... OK, donc c'est ma méthode qui était fausse à la base, avec ou sans
MULT....... Comment savoir si tous les mots sont présents ?

Actuellement on a

    SELECT SUM(idx.points) ..... WHERE X GROUP BY Y;

Si on fait

    SELECT FLOOR(COUNT(idx.points) / n) ..... WHERE X GROUP BY Y;

où n = le nombre de mots, on obtient 1 si tous les mots sont là, et 0
sinon....

Du coup le panachage donnerait

    SELECT 10*(n-1)*FLOOR(COUNT(idx.points) / n) + SUM (idx.points) etc..

On ajoute 10*(n-1) points si tous les mots sont là. Enfin, tout est
envisageable, mais donner un plus aux ET me semble aussi nécessaire, à
l'usage (sur http://MondeDiplo.com/, spip est infoutu de retrouver un
article par son titre)

Autre option, un truc quadratique :
    SELECT (COUNT(idx.points))^2 * SUM(idx.points) etc.

On multiple par 4 le score quand il y a 2 mots, par 9 quand il y en a 3,
etc... j'essaie et je vous tiens au courant.

-- Fil

Fil wrote:

Du coup le panachage donnerait

    SELECT 10*(n-1)*FLOOR(COUNT(idx.points) / n) + SUM (idx.points) etc..

Le problème c'est les mots cachés : si tu demandes "liberté", "libertés"
va être ajouté à la liste des mots et donc ça foire le système de seuil
ci-dessus.

(sur http://MondeDiplo.com/, spip est infoutu de retrouver un
article par son titre)

Heu... peut-être qu'en augmentant le poids du titre à l'indexation ?
T'as un exemple ?

Mais bon, là on essaie de faire résoudre plein de problèmes à un micro-moteur
de recherche qui n'en a probablement pas les capacités. En ne faisant qu'une
passe et avec une requête MySQL la plus simple possible, je crois qu'il est
difficile de faire des miracles. De plus si tu regardes les résultats d'un
moteur de recherche "à l'ancienne" (type Altavista), c'est souvent très
médiocre aussi.

Autre option, un truc quadratique :
    SELECT (COUNT(idx.points))^2 * SUM(idx.points) etc.

On multiple par 4 le score quand il y a 2 mots, par 9 quand il y en a 3,
etc... j'essaie et je vous tiens au courant.

Bon, ça marche mais de manière un peu erratique.

Je crois que je vois pourquoi tu me parlais de "pomme" et "pommes" - si un
article contient "pomme", "pommeau" et "pommes", et que l'on demande "pomme"
et "poire", l'article en question considère qu'il a trouvé 3 mots, donc voit
son score *9, quand celui d'un article en pomme et poire n'est que *4.

-- Fil

Le problème c'est les mots cachés : si tu demandes "liberté", "libertés"
va être ajouté à la liste des mots et donc ça foire le système de seuil
ci-dessus.

ouaip

Heu... peut-être qu'en augmentant le poids du titre à l'indexation ?

oui sûrement, ça fait quand même partie des recherches de base.

T'as un exemple ?

"A legal trade in death"... pour la plupart des titres, tout de même, on
trouve dans la première page de résultats.

Mais bon, là on essaie de faire résoudre plein de problèmes à un
micro-moteur de recherche qui n'en a probablement pas les capacités. En ne
faisant qu'une passe et avec une requête MySQL la plus simple possible, je
crois qu'il est difficile de faire des miracles.

Certes, mais quelque chose d'un peu plus proche du "ET" et qui respecte un
peu mieux les titres, serait cool.

De plus si tu regardes les résultats d'un moteur de recherche "à
l'ancienne" (type Altavista), c'est souvent très médiocre aussi.

M'en fous !

-- Fil

Mais il y aura toujours des gens pour trouver que l'une ou l'autre
méthode convient mieux.

Pourquoi ne pas tout simplement proposer l'option ET/OU dans le
formulaire de recherche ???

-Nicolas

@ Nicolas Hoizey <nhoizey@phpheaven.net> :

>> Mais il y aura toujours des gens pour trouver que l'une ou l'autre
>> méthode convient mieux.

Pourquoi ne pas tout simplement proposer l'option ET/OU dans le
formulaire de recherche ???

Ce serait compliquer l'interface, mais surtout ça ne résout pas le problème:
quelle requête SQL simple et efficace pour faire quelque chose qui ressemble
à "ET" ?

-- Fil

Salut,

Désolé, mais les questions du moteur, je sature un peu :-))

- Au départ, on l'a considéré comme un petit moteur bien pratique pour rendre service, parce qu'il est rapide, et plutôt efficace. M'enfin on précisait toujours que, pour des besoins réellement spécifiques, il valait mieux se tourner vers une solution spécialisée (htDig://). Ensuite, on m'a expliqué qu'en fait, c'était un excellent moteur, très efficace. Fil l'a même installé en remplacement de htDig sur le Monde diplomatique, qui se trouve être une énorme base documentaire sur laquelle il faut un excellent moteur.

- Bref, faisons simple, faisons court: est-ce que, oui ou non, ce moteur remplit correctement son office? Est-ce qu'on trouve ce qu'on cherche, avec un "déchet" acceptable?

  Est-ce qu'on est en train de se prendre la tête parce qu'en théorie on pourrait faire mieux, ou bien est-ce qu'il offre un compromis très acceptable pour des sites Web? Franchement, sur uZine c'est bien pratique (désolé, j'ai pas tellement d'autres exemples personnel), et si le Diplo a remplacé htDig avec ce moteur, c'est qu'il doit plutôt bien fonctionner, non?

ARNO*

Bonjour,

Une autre solution serait de n'indexer les mots de moins de 4
lettres que s'ils sont intégralement en majuscules, ce qui est
souvent le cas des accronymes, et rarement le cas des non
accronymes...

Je n'ai pas vu d'écho à cette proposition, j'ai loupé quelque chose ?

Le fait est que j'aimerais bien pouvoir faire une recherche sur "PHP"
sur le site de l'AFUP ... :wink:

-Nicolas