from matplotlib.cm import get_cmap import plotly.graph_objects as go about_blurb = ''' ### About the QuAL Score The Quality of Assessment for Learning score (QuAL score), was created to evaluate short qualitative comments that are related to specific scores entered into a workplace-based assessment, common within the competency-based medical education (CBME) context. It is rated on a scale of 0-5, with 0 signifying very low quality and 5 very high quality. It consists of three subscores which are summed to calculate the overall QuAL score: 1. Evidence - Does the rater provide sufficient evidence about resident performance? (0-no comment at all, 1-no, but comment present, 2-somewhat, 3-yes/full description) 2. Suggestion - Does the rater provide a suggestion for improvement? (0-no/1-yes) 3. Connection - Is the rater's suggestion linked to the behavior described? (0-no/1-yes) The QuAL score has validity evidence for accurately measuring the quality of evaluation comments in CBME. For more information, see the paper [here](https://doi.org/10.1080/10401334.2019.1708365). ### About this Tool The QuAL score accurately rates the quality of narrative comments in CBME, but it still requires time-consuming manual rating. With large volumes of text generated in a typical CBME program, large-scale assessment of comment quality is impractical. This tool uses machine learning (ML) and natural langugage processing (NLP) to automate the rating of the QuAL score on narratie comments. We trained a machine learning model to predict each of the three subscores described above. The resulting models are accurate: 1. Evidence - Balanced accuracy of 61.5% for a 0-3 result, within-one accuracy of 96.4% 2. Suggestion - Accuracy of 85%, sensitivity for lack of suggestion 86.2% 3. Connection - Accuracy of 82%, sensitivity for lack of connection 90% The models are highly accurate, but not perfect! You may experience times where the results are not consistent with your interpretation of the text. If you do, please leave us [feedback](https://forms.gle/PfXxcGmvLYvd9jWz5). This tool is intendened as a demonstration only and should not be used for high-stakes assessment (yet!). ''' class NQDOverview(object): def __init__(self, parent, results, dial_cmap='RdYlGn'): self.p = parent self.results = results self.cmap = get_cmap(dial_cmap) def _get_color(self): color = self.cmap(self.results['qual']['label'] / 6.0) color = f'rgba({int(color[0]*256)}, {int(color[1]*256)}, {int(color[2]*256)}, {int(color[3]*256)})' return color def _build_figure(self): color = self._get_color() fig = go.Figure(go.Indicator( domain = {'x': [0, 1], 'y': [0, 1]}, value = self.results['qual']['label'], mode = "gauge+number", title = {'text': "QuAL"}, gauge = {'axis': {'range': [None, 5], 'showticklabels': True, 'ticks': ""}, 'bgcolor': 'lightgray', 'bar': {'color': color, 'thickness': 1.0} } ), layout=go.Layout(margin=dict(t=0, b=135)) ) return fig def draw(self): st = self.p with st.expander('About the QuAL Score and this Tool', expanded=False): st.markdown(about_blurb) fig = self._build_figure() cols = st.columns([7, 3]) with cols[0]: st.plotly_chart(fig, use_container_width=True) with cols[1]: q1lab = self.results['q1']['label'] if q1lab == 0: md_str = 'πŸ˜₯ None' elif q1lab == 1: md_str = '😐 Low' elif q1lab == 2: md_str = '😊 Medium' elif q1lab == 3: md_str = '😁 High' cols[1].metric('Level of Detail', md_str, help='Q1 - Evidence - Does the rater provide sufficient evidence about resident performance? (0-no comment at all, 1-no, but comment present, 2-somewhat, 3-yes/full description)') q2lab = self.results['q2i']['label'] if q2lab == 0: md_str = 'βœ… Yes' else: md_str = '❌ No' cols[1].metric('Suggestion Given', (md_str), help='Q2 - Suggestion - Does the rater provide a suggestion for improvement? (0-no/1-yes)') q3lab = self.results['q3i']['label'] if q3lab == 0: md_str = 'βœ… Yes' else: md_str = '❌ No' cols[1].metric('Suggestion Linked', md_str, help='Q3 - Connection - Is the rater’s suggestion linked to the behavior described? (0-no/1-yes)')