mirror of
https://git.roussel.pro/telecom-paris/pact.git
synced 2026-02-09 10:30:17 +01:00
161 lines
6.1 KiB
Python
161 lines
6.1 KiB
Python
from vaderSentiment_fr.vaderSentiment import SentimentIntensityAnalyzer
|
|
|
|
#Emplacements des fichiers contenants le lexique et les avis
|
|
lexiconPath = r"C:\Users\kesha\Desktop\TelecomParis\PACT\fr_lexicon.txt"
|
|
reviewPath = r"C:\Users\kesha\Desktop\TelecomParis\PACT\LouvreAvis.txt"
|
|
|
|
#Création d'une liste de listes ordonnée alphabétiquement pour ne pas
|
|
#avoir à chercher un mot d'un avis dans le lexique en entier à chaque fois.
|
|
#La dernière case correspond aux expressions n'étant pas des mots.
|
|
scoreWords = open(lexiconPath, "r")
|
|
scoreTable = [[] for i in range(27)]
|
|
line = scoreWords.readline()
|
|
|
|
#Fonction d'ajout d'une paire mot-score par ordre alphabétique avec les
|
|
#expressions n'étant pas des mots à la dernière case.
|
|
#L'indice de la bonne case est trouvée avec le code ASCII en minuscule
|
|
#(a vaut 97 et z vaut 122)
|
|
def add(scoreword):
|
|
if (ord(scoreword[0][0]) < 97 or ord(scoreword[0][0]) > 122):
|
|
scoreTable[26].append(scoreword)
|
|
else:
|
|
scoreTable[ord(scoreword[0][0])-97].append(scoreword)
|
|
|
|
#Ajout des paires mot-score dans scoreTable
|
|
while (line != ''):
|
|
line = line.strip().split("->")
|
|
add([line[0].lower(), float(line[1])])
|
|
line = scoreWords.readline()
|
|
scoreWords.close()
|
|
|
|
### Partie analyse d'avis ###
|
|
|
|
|
|
file = open(reviewPath, "r", encoding='UTF-8')
|
|
reviews = (file.read()).split('//')
|
|
|
|
|
|
#liste (partielle) de mots-clé pertinents pour un musée
|
|
keys=['attente', "d'attente", 'queue', 'patienter', 'patience', 'patient',
|
|
'patients', 'patiente', 'patientes', 'file', 'files',
|
|
'impolitesse' ,'impolie', 'impolies', 'impoli', 'impolis',
|
|
'gentillesse', 'amabilité', 'aimable', 'aimables','gentil', 'gentils',
|
|
'gentille', 'gentilles', 'personnel',
|
|
'sales', 'sale', 'saleté', 'propre', 'propres', 'propreté',
|
|
'acceuil', 'prix', 'cher', 'chers', 'chère', 'chères',
|
|
'onéreux', 'onéreuse', 'onéreuses', 'abordable',
|
|
'raisonnable', 'raisonnables', 'accessible', 'accessibilité',
|
|
'handicapé', 'handicapée', 'handicapés', 'handicapées', 'orienter','employé',
|
|
'employés', 'employées', 'employée', 'agent', 'agente',
|
|
'orientation', 'orienté', "s'orienter", 'dédale',
|
|
'désorienter', 'désorienté', 'désorientée', 'désorientés', 'désorientées',
|
|
'panneau', 'panneaux', 'signalétique', 'labyrinthe',
|
|
'perdu', 'perdus', 'perdue', 'perdues',
|
|
'toilettes',
|
|
'restaurant', 'restaurants', 'restauration', 'manger', 'mangé', 'déjeuner', 'déjeuné']
|
|
|
|
#Tableau de paires mots-clé, score associé
|
|
keyWords = []
|
|
|
|
#Score moyen d'un avis
|
|
averageScore = 0
|
|
|
|
vaderScore = {'neg': 0, 'neu': 0, 'pos': 0, 'compound': 0}
|
|
|
|
SIA = SentimentIntensityAnalyzer()
|
|
|
|
|
|
#Fonction de recherche d'un mot d'un avis parmis le lexique
|
|
def search(word):
|
|
if (len(word) != 0):
|
|
if (ord(word[0]) < 97 or ord(word[0]) > 122):
|
|
mots = list(e[0] for e in scoreTable[26])
|
|
if (word in mots):
|
|
return([word, scoreTable[26][mots.index(word)][1]])
|
|
else:
|
|
return(-1)
|
|
mots = list(e[0] for e in scoreTable[ord(word[0])-97])
|
|
if (word in mots):
|
|
return([word, scoreTable[ord(word[0])-97][mots.index(word)][1]])
|
|
return(-1)
|
|
|
|
#Fonction déterminant si une phrase contient une négation et renvoyant un booléen
|
|
def isNegative(sentence):
|
|
if (('ne' in sentence) or ("n'" in sentence) or ("pas" in sentence)):
|
|
return True
|
|
return False
|
|
|
|
vaderCriteria = ['neg', 'neu', 'pos', 'compound']
|
|
|
|
def ReviewAnalyzer(review):
|
|
reviewScore = 0
|
|
|
|
#miniKey donne les mots-clé contenus dans l'avis en train d'être analysé
|
|
miniKey = []
|
|
|
|
### Recherche de mots positifs/négatifs ###
|
|
|
|
#On découpe l'avis en une liste de phrases
|
|
sentences = Review.split('.')
|
|
for sent in sentences:
|
|
|
|
#On découpe la phrase en une liste de mots
|
|
sentence = list(e.strip(',.') for e in sent.split())
|
|
for Word in sentence:
|
|
|
|
#On met tout les mots en minuscule pour ne pas prendre en compte les majuscules
|
|
word = Word.lower()
|
|
temp = search(word)
|
|
|
|
#recherche d'un éventuel mot-clé associé à ce caractère positif/négatif
|
|
if (temp != -1):
|
|
|
|
#On change la valeur du score associé au mot-clé
|
|
#si la phrase contient une négation
|
|
if (isNegative(sentence)):
|
|
temp[1] = -temp[1]
|
|
|
|
for key in keys:
|
|
if (key in sentence):
|
|
|
|
#Récupération des mots-clés déjà détectés dans tous les avis
|
|
cles = list(e[0] for e in keyWords)
|
|
|
|
#En fonction de si key a déjà été détecté auparavant,
|
|
#et donc qu'il est dans keyWords avec un score associé,
|
|
#on augmente le score ou sinon, on crée une paire mot-clé score
|
|
if (key in cles):
|
|
keyWords[cles.index(key)][1] += temp[1]
|
|
else:
|
|
keyWords.append([key, temp[1]])
|
|
|
|
#Rajout du mot-clé key dans la liste des mots-clé trouvés dans cet avis
|
|
miniKey.append(key)
|
|
|
|
#Mise à jour du score de l'avis
|
|
reviewScore += temp[1]
|
|
|
|
#Caractéristiques de l'avis analysé
|
|
miniKey = set(miniKey)
|
|
return(miniKey, reviewScore)
|
|
|
|
for Review in reviews:
|
|
ReviewAnalayzer(Review)
|
|
|
|
#Ces 3 lignes sont pour comparer avec le score de VADER
|
|
score = SIA.polarity_scores(sent)
|
|
for criteria in vaderCriteria:
|
|
vaderScore[criteria] += score[criteria]
|
|
|
|
averageScore /= len(reviews)
|
|
print("Format: [[Mot-clé, score associé]]")
|
|
for e in keyWords:
|
|
print(e)
|
|
print('')
|
|
print("Nombre d'avis: ", len(reviews))
|
|
print("Score moyen d'un avis: ", averageScore)
|
|
for criteria in vaderCriteria:
|
|
vaderScore[criteria] /= len(reviews)
|
|
print("Score moyen de vader d'un avis: ", vaderScore)
|
|
file.close()
|