You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Sinon : test de la similarité (seulement si le message de l'utilisateur n'est pas très court)
44
+
// On calcule la distance de Levenshtein entre le keyword et la question de l'utilisateur (en parcourant les n-grammes du message de l'utilisateur et en prenant en compte la longueur du n-gramme ; avec n = nombre de mots du keyword)
// On prend en compte la plus longue chaîne commune de caractères (sauf si on doit passer au message seulement s'il y a présence du keyword [cas d'un quiz] : dans ce cas, on doit être plus strict et tester seulement la proximité avec la distance de Levenshtein pour simplement autoriser quelques fautes d'orthographe)
constLEVENSHTEIN_THRESHOLD=3;// Seuil de similarité (tolérance des fautes d'orthographe et des fautes de frappe)
9
4
constMATCH_SCORE_IDENTITY=30;// Pour régler le fait de privilégier l'identité d'un keyword à la simple similarité
10
-
constWORD_LENGTH_FACTOR=0.1;// Prise en compte de la taille des keywords (plus les keywords sont grands, plus ils doivent avoir un poids important)
11
5
12
6
functionbuildKeywordsList(next,response){
13
-
// Si on a la directive !Next, alors on ne teste pas la correspondance avec le titre, mais seulement avec les keywords (sauf s'il n'y a pas de keyword)
7
+
// Si on a la directive !Next, on inclut seulement les keywords dans la liste des termes à tester (sauf s'il n'y a pas de keyword)
@@ -37,6 +32,35 @@ function calculateCosineSimilarityScore(
37
32
returncosSim ? cosSim+0.5 : 0;
38
33
}
39
34
35
+
functionadjustScore(
36
+
response,
37
+
matchScore,
38
+
distanceScore,
39
+
bestDistanceScore,
40
+
next,
41
+
yaml,
42
+
){
43
+
// si on a un score de distance négatif, c'est qu'il y avait des keywords négatifs : donc le matchscore doit être égal à 0
44
+
if(distanceScore<0){
45
+
matchScore=0;
46
+
}
47
+
if(
48
+
(matchScore==0||(yaml&&yaml.searchInContent))&&
49
+
!next.needsProcessing
50
+
){
51
+
// En cas de simple similarité : on monte quand même le score. Mais si on est dans le mode où on va directement à une réponse en testant la présence de keywords, la correspondance doit être stricte, on ne fait pas de calcul de similarité
52
+
if(distanceScore>bestDistanceScore){
53
+
matchScore=matchScore+distanceScore;
54
+
bestDistanceScore=distanceScore;
55
+
}
56
+
}
57
+
// Si on a la directive !Next : titre réponse, alors on augmente de manière importante le matchScore si on a un matchScore > 0.5 et que la réponse correspond au titre de la réponse voulue dans la directive
@@ -45,13 +69,12 @@ export function computeResponseScore({
45
69
yaml,
46
70
}){
47
71
constnext=chatbot.nextMessage;
48
-
letbestDistanceScore=0;
49
-
// Si on a la directive !Next, alors on ne teste pas la correspondance avec le titre, mais seulement avec les keywords (sauf s'il n'y a pas de keyword)
50
-
// Sinon on inclut le titre
51
-
// On met tout en minuscule
52
72
constkeywords=buildKeywordsList(next,response);
73
+
74
+
letbestDistanceScore=0;
53
75
letmatchScore=0;
54
76
letdistanceScore=0;
77
+
55
78
// Si le YAML indique de faire une recherche dans le contenu avec la similarité vectorielle, on prend comme base de score le cosine similarity entre le message de l'utilisateur et le contenu vectoriel de la réponse
56
79
if(yaml&&yaml.searchInContent){
57
80
matchScore=calculateCosineSimilarityScore(
@@ -61,77 +84,28 @@ export function computeResponseScore({
61
84
next,
62
85
);
63
86
}
87
+
88
+
// On calcule les scores pour chaque keyword
64
89
for(letkeywordofkeywords){
65
-
// On prend en compte les keywords négatifs (on ne doit pas les voir dans la question de l'utilisateur)
66
-
constisNegativeKeyword=keyword.startsWith("! ");
67
-
keyword=keyword.replace(/^!\s/,"");
68
-
keyword=normalizeText(keyword,{keepCase: true});
69
-
if(userInput.includes(keyword)){
70
-
// Test de l'identité stricte
71
-
letstrictIdentityMatch=false;
72
-
if(next.needsProcessing){
73
-
// Si on utilise la directive !Next, on vérifie que le keyword n'est pas entouré de lettres ou de chiffres dans le message de l'utilisateur
// Sinon : test de la similarité (seulement si le message de l'utilisateur n'est pas très court)
94
-
// On calcule la distance de Levenshtein entre le keyword et la question de l'utilisateur (en parcourant les n-grammes du message de l'utilisateur et en prenant en compte la longueur du n-gramme ; avec n = nombre de mots du keyword)
// On prend en compte la plus longue chaîne commune de caractères (sauf si on doit passer au message seulement s'il y a présence du keyword [cas d'un quiz] : dans ce cas, on doit être plus strict et tester seulement la proximité avec la distance de Levenshtein pour simplement autoriser quelques fautes d'orthographe)
107
-
distanceScore=
108
-
distanceScore+
109
-
longestCommonSubstringWeightedLength(
110
-
userInput,
111
-
keyword,
112
-
WORD_LENGTH_FACTOR,
113
-
);
114
-
}
115
-
}
116
-
}
117
-
// si on a un score de distance négatif, c'est qu'il y avait des keywords négatifs : donc le matchscore doit être égal à 0
118
-
if(distanceScore<0){
119
-
matchScore=0;
120
-
}
121
-
if(
122
-
(matchScore==0||(yaml&&yaml.searchInContent))&&
123
-
!next.needsProcessing
124
-
){
125
-
// En cas de simple similarité : on monte quand même le score. Mais si on est dans le mode où on va directement à une réponse en testant la présence de keywords, la correspondance doit être stricte, on ne fait pas de calcul de similarité
126
-
if(distanceScore>bestDistanceScore){
127
-
matchScore=matchScore+distanceScore;
128
-
bestDistanceScore=distanceScore;
129
-
}
130
-
}
131
-
// Si on a la directive !Next : titre réponse, alors on augmente de manière importante le matchScore si on a un matchScore > 0.5 et que la réponse correspond au titre de la réponse voulue dans la directive
0 commit comments