plentas / codeScripts /rubrics.py
xiomarablanco's picture
Procesando respuestas de Moodle
ce84b09
import spacy
#spacy model imported in the init of class Semantica2
#nlp = spacy.load('es_core_news_sm')
#nlp = spacy.load('es_core_news_md')
#nlp = spacy.load('es_core_news_lg')
from codeScripts.Dependencies.SentenceTransformer2 import *
from codeScripts.rubricsOut import SemanticOutput, OrtographicOutput, SintacticOutput
from codeScripts.utils import spelling_corrector, mu_index, FHuertas_index, check_senteces_words, save_json,create_file_path
#Done
class Semantica2():
"""
This class allows to compute the semantic level of the rubric
"""
#funciones para la extraccion/generacion de kw --- no integradas
def __init__(self, settings):
self.output = SemanticOutput(settings)
self.spacy_model = spacy.load(settings.spacy_package)
self.settings = settings
def computeSimilarity(self,sentences1,sentences2,similarityMethod):
"""
This function applies a defined method to obtain the similarity between two sentences
Inputs:
-sentences1: First set of sentences to compare
-sentences2: Second set of sentences to compare
-similarityMethod: The inherited similarity method selected in getSimilarity
Outputs:
-similar: The similarity score
"""
if similarityMethod.lower() == "spacy":
r1 = self.spacy_model(sentences1)
r2 = self.spacy_model(sentences2)
similar = round(r1.similarity(r2), 3)
else:
similar = self.settings.BertModels_glbl.similarity(self.settings.model_path, sentences1, sentences2)[0][0].item()
return similar
class Ortografia2 ():
"""
This class allows to compute the ortographic level of the rubric
"""
def __init__(self, settings):
self.output = OrtographicOutput()
self.settings = settings
def Evaluation(self, respuesta_alumno):
"""
This method is used for calculating the ortographic mark.
Inputs:
respuesta_alumno: The student's answer.
Outputs:
nota_Orto: The generated mark.
"""
#some exceptions that should not be considered as mistakes
exceptionsTxt = open('codeScripts/OrtographicExceptions.txt', encoding="utf-8")
exceptions = exceptionsTxt.readline()
exceptionsTxt.close()
nota_Orto = 0
if respuesta_alumno == "":
self.output.number_mistakes.append(0)
self.settings.faltasOrto = 0
else:
#obtaining the number of mistakes using hunspell
errores, mistakes = spelling_corrector(respuesta_alumno, self.settings.hunspell_aff, self.settings.hunspell_dic)
for mistake in mistakes:
if mistake not in exceptions:
if mistake not in self.output.mistakes:
self.output.mistakes.append(mistake)
else:
errores-=1
#storing the mistakes for debugging purposes
self.output.number_mistakes.append(errores)
#counting the number of errors when surpassing a fixed number of them (config parameter)
if errores <= self.settings.FaltasSalvaguarda:
nota_Orto = self.settings.PesoOrtografia
self.settings.faltasOrto = 0
else:
self.settings.faltasOrto = errores
#computing the mark applying rubric weights
try:
rel = self.settings.PesoOrtografia/self.settings.NMaxErrores
nota_Orto = self.settings.PesoOrtografia - (errores - self.settings.FaltasSalvaguarda) * rel
except:
nota_Orto = 0
if nota_Orto < 0:
nota_Orto = 0
return nota_Orto
def SaveMistakes(self):
"""
This method is used for saving some information about the students' found mistakes
"""
save_json(create_file_path('RecopiledMistakes.json', doctype= 2),self.output.mistakes, False)
save_json(create_file_path('NumberMistakes.json', doctype= 2),self.output.number_mistakes, False)
class Sintaxis2():
"""
This class allows to compute the syntactic level of the rubric
"""
def __init__(self, settings):
self.output = SintacticOutput()
self.settings = settings
def Evaluation(self, respuesta_alumno):
"""
This method is used for calculating the syntactic mark.
Inputs:
respuesta_alumno: The student's answer.
Outputs:
nota_Sintaxis: The generated mark.
"""
if respuesta_alumno == '':
self.output.leg_FH.append(0)
self.output.leg_mu.append(0)
self.settings.palabrasPorFrase = 0
return 0
else:
#obtaining FH and mu indexes
sentencesLenght, wordsLenght, syll, letter_per_word = check_senteces_words(respuesta_alumno)
print("wordsLenght: " + str(wordsLenght))
FH, _ = FHuertas_index(sentencesLenght, wordsLenght, syll)
mu, _ = mu_index(sentencesLenght, wordsLenght, letter_per_word)
#storing the indexes
self.output.leg_FH.append(FH)
self.output.leg_mu.append(mu)
#calculating the grade
nota_Sintaxis = (self.settings.PesoSintaxis/2) * FH/80 + (self.settings.PesoSintaxis/2) * mu/60
if nota_Sintaxis > self.settings.PesoSintaxis:
nota_Sintaxis = self.settings.PesoSintaxis
print("sentencesLenght: " + str(sentencesLenght))
self.settings.palabrasPorFrase = round(wordsLenght/sentencesLenght,2)
return nota_Sintaxis
def saveResults(self):
"""
This method is used for saving some information about the students' readability
"""
self.output.saveLegibilityResults()
def GenerateFeedback(settings, respuesta, OrtoMark, SintMark, SemanMarkSpacy, SemanMarkBert):
"""
This function is used to analyze grades and generate appropriate feedback based on sentences.
Inputs:
-settings: The settings of the experiment.
-respuesta: The student's response.
-OrtoMark: The calification of the ortographic level.
-SintMark: The calification of the syntactic level.
-SemanMarkSpacy: The calification of the semantic level - spacy.
-SemanMarkBert: The calification of the semantic level - bert.
Outputs:
-feedback: The generated feedback.
"""
feedback = ""
#if blank response
if respuesta == "":
feedback = feedback + "Respuesta en blanco"
else:
#pre-defined sentences in case: <5 - <10 - 10
if settings.Ortografia:
feedback = feedback + "\nNivel ortográfico: \n"
if OrtoMark < settings.PesoOrtografia/2:
feedback = feedback + "El estudiante cometió " + str(settings.faltasOrto) + " faltas de ortografía y no alcanzó el aprobado en este nivel de la rúbrica. El sistema reconoce un fallo si se ha producido un error en acento de puntuación o en una palabra no recogida en un diccionario español. \n"
elif OrtoMark < settings.PesoOrtografia:
feedback = feedback + "El estudiante cometió " + str(settings.faltasOrto) + " faltas de ortografía. El sistema reconoce un fallo si se ha producido un error en acento de puntuación o en una palabra no recogida en un diccionario español. \n"
else:
feedback = feedback + "El estudiante redactó su respuesta sin aparentes fallos de ortografía. \n"
if settings.Sintaxis:
feedback = feedback + "\nNivel sintáctico: \n"
if SintMark < settings.PesoSintaxis/2:
feedback = feedback + "La respuesta del estudiante incluye elementos que dificultan su correcta legibilidad y no alcanzó el aprobado en este nivel de la rúbrica. Hay " + str(settings.palabrasPorFrase) + " palabras por frase. El sistema tiene en consideración para la legibilidad el promedio de sílabas por palabra y la media de palabras por frase. Además, el uso de guiones o puntos es desaconsejable. \n"
elif SintMark < settings.PesoSintaxis:
feedback = feedback + "La respuesta del estudiante incluye elementos que dificultan su correcta legibilidad. Hay " + str(settings.palabrasPorFrase) + " palabras por frase. El sistema tiene en consideración para la legibilidad el promedio de sílabas por palabra y la media de palabras por frase. Además, el uso de guiones o puntos es desaconsejable. \n"
else:
feedback = feedback + "La respuesta del estudiante fue redactada con aparente buena legibilidad \n"
if settings.Semantica:
feedback = feedback + "\nNivel semántico, primer modelo: \n"
if SemanMarkSpacy < settings.PesoSemantics/2:
feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas y no alcanzó el aprobado en este nivel de la rúbrica. Debería profundizar más en " + settings.minipreguntasMalSpacy + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n"
elif SemanMarkSpacy < settings.PesoSemantics:
feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas. Para mejorar podría profundizar más en " + settings.minipreguntasMalSpacy + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n"
else:
feedback = feedback + "El estudiante responde a cada minipregunta de forma similar a la respuesta de referencia. \n"
feedback = feedback + "\nNivel semántico, segundo modelo: \n"
if SemanMarkBert < settings.PesoSemantics/2:
feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas y no alcanzó el aprobado en este nivel de la rúbrica. Debería profundizar más en " + settings.minipreguntasMalBert + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta.\n"
elif SemanMarkBert < settings.PesoSemantics:
feedback = feedback + "El estudiante no responde correctamente a todas las minipreguntas. Para mejorar podría profundizar más en " + settings.minipreguntasMalBert + ". El sistema evalúa una respuesta en base a la similitud que existe entre ésta y la respuesta de referencia de cada minipregunta. \n"
else:
feedback = feedback + "El estudiante responde a cada minipregunta de forma similar a la respuesta de referencia. \n"
feedback = feedback + "\n\nPor favor, si observa alguna diferencia significativa entre la calificación de ambos modelos, entre a valorar la nota del estudiante. "
return feedback