Instructions to use Clementio/PLRS with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Clementio/PLRS with Transformers:
# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("Clementio/PLRS", dtype="auto") - Notebooks
- Google Colab
- Kaggle
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -120,7 +120,12 @@ class RankingFunction:
|
|
| 120 |
prereqs = list(self.graph.predecessors(topic_id))
|
| 121 |
readiness = 1.0 if not prereqs else sum(1 for p in prereqs if mastery_vector.is_mastered(p))/len(prereqs)
|
| 122 |
downstream = self._downstream.get(topic_id, 0.0)
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
class LearningRecommendationPipeline:
|
| 126 |
def __init__(self, graph, threshold=0.70, soft_threshold=0.50, top_n=5):
|
|
@@ -183,6 +188,54 @@ def what_if_analysis(topic_id, graph):
|
|
| 183 |
blocked_labels = [graph.nodes[n].get('label',n) for n in blocked_by]
|
| 184 |
return {'direct_unlocks': unlock_labels, 'all_unlocks': all_unlock_labels, 'blocked_by': blocked_labels, 'total_unlocked': len(unlocks)}
|
| 185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
def get_attention_weights(model, config, skill_seq, correct_seq, device):
|
| 187 |
max_len=config['max_seq_len']; n_skills=config['num_skills']
|
| 188 |
if len(skill_seq)>max_len: skill_seq=skill_seq[-max_len:]; correct_seq=correct_seq[-max_len:]
|
|
@@ -252,7 +305,9 @@ def main():
|
|
| 252 |
}).sort_values('Mastery', ascending=False).head(10)
|
| 253 |
st.markdown('**π Simulated Learner Mastery Signal (top 10 topics):**')
|
| 254 |
st.bar_chart(mastery_df.set_index('Topic'))
|
| 255 |
-
|
|
|
|
|
|
|
| 256 |
st.success(f'Learner simulation complete β {n_mastered}/{n_topics} topics above mastery threshold')
|
| 257 |
if st.button('π Generate Recommendations', type='primary'):
|
| 258 |
output=pipeline.run(mastery_vector)
|
|
|
|
| 120 |
prereqs = list(self.graph.predecessors(topic_id))
|
| 121 |
readiness = 1.0 if not prereqs else sum(1 for p in prereqs if mastery_vector.is_mastered(p))/len(prereqs)
|
| 122 |
downstream = self._downstream.get(topic_id, 0.0)
|
| 123 |
+
# Near-mastery boost: topics the student has already started
|
| 124 |
+
# rank higher than untouched topics with the same gap score
|
| 125 |
+
near_mastery_boost = 0.0
|
| 126 |
+
if 0.10 <= current < self.threshold:
|
| 127 |
+
near_mastery_boost = 0.15 * (current / self.threshold)
|
| 128 |
+
return round(self.w_gap*gap + self.w_ready*readiness + self.w_downstream*downstream + near_mastery_boost, 3)
|
| 129 |
|
| 130 |
class LearningRecommendationPipeline:
|
| 131 |
def __init__(self, graph, threshold=0.70, soft_threshold=0.50, top_n=5):
|
|
|
|
| 188 |
blocked_labels = [graph.nodes[n].get('label',n) for n in blocked_by]
|
| 189 |
return {'direct_unlocks': unlock_labels, 'all_unlocks': all_unlock_labels, 'blocked_by': blocked_labels, 'total_unlocked': len(unlocks)}
|
| 190 |
|
| 191 |
+
def cascade_mastery(mastery_vector, graph):
|
| 192 |
+
"""
|
| 193 |
+
If a student has high mastery on a topic, infer that their
|
| 194 |
+
prerequisites are also likely mastered (propagate upward).
|
| 195 |
+
A student who scores 80% on Modular Arithmetic almost certainly
|
| 196 |
+
knows Whole Numbers β cascade fills these realistic gaps.
|
| 197 |
+
"""
|
| 198 |
+
changed = True
|
| 199 |
+
while changed:
|
| 200 |
+
changed = False
|
| 201 |
+
for node in graph.nodes:
|
| 202 |
+
node_mastery = mastery_vector.get_mastery(node)
|
| 203 |
+
if node_mastery < 0.40:
|
| 204 |
+
continue
|
| 205 |
+
# For each prerequisite of this node
|
| 206 |
+
for prereq in graph.predecessors(node):
|
| 207 |
+
prereq_mastery = mastery_vector.get_mastery(prereq)
|
| 208 |
+
# Infer prerequisite mastery as at least 85% of descendant mastery
|
| 209 |
+
inferred = min(node_mastery * 0.85, 0.95)
|
| 210 |
+
if inferred > prereq_mastery:
|
| 211 |
+
mastery_vector.update(prereq, inferred)
|
| 212 |
+
changed = True
|
| 213 |
+
return mastery_vector
|
| 214 |
+
|
| 215 |
+
def cascade_mastery(mastery_vector, graph):
|
| 216 |
+
"""
|
| 217 |
+
If a student has high mastery on a topic, infer that their
|
| 218 |
+
prerequisites are also likely mastered (propagate upward).
|
| 219 |
+
A student who scores 80% on Modular Arithmetic almost certainly
|
| 220 |
+
knows Whole Numbers β cascade fills these realistic gaps.
|
| 221 |
+
"""
|
| 222 |
+
changed = True
|
| 223 |
+
while changed:
|
| 224 |
+
changed = False
|
| 225 |
+
for node in graph.nodes:
|
| 226 |
+
node_mastery = mastery_vector.get_mastery(node)
|
| 227 |
+
if node_mastery < 0.40:
|
| 228 |
+
continue
|
| 229 |
+
# For each prerequisite of this node
|
| 230 |
+
for prereq in graph.predecessors(node):
|
| 231 |
+
prereq_mastery = mastery_vector.get_mastery(prereq)
|
| 232 |
+
# Infer prerequisite mastery as at least 85% of descendant mastery
|
| 233 |
+
inferred = min(node_mastery * 0.85, 0.95)
|
| 234 |
+
if inferred > prereq_mastery:
|
| 235 |
+
mastery_vector.update(prereq, inferred)
|
| 236 |
+
changed = True
|
| 237 |
+
return mastery_vector
|
| 238 |
+
|
| 239 |
def get_attention_weights(model, config, skill_seq, correct_seq, device):
|
| 240 |
max_len=config['max_seq_len']; n_skills=config['num_skills']
|
| 241 |
if len(skill_seq)>max_len: skill_seq=skill_seq[-max_len:]; correct_seq=correct_seq[-max_len:]
|
|
|
|
| 305 |
}).sort_values('Mastery', ascending=False).head(10)
|
| 306 |
st.markdown('**π Simulated Learner Mastery Signal (top 10 topics):**')
|
| 307 |
st.bar_chart(mastery_df.set_index('Topic'))
|
| 308 |
+
# Cascade mastery upward through DAG
|
| 309 |
+
mastery_vector = cascade_mastery(mastery_vector, graph)
|
| 310 |
+
n_mastered = sum(1 for t in topic_nodes if mastery_vector.is_mastered(t))
|
| 311 |
st.success(f'Learner simulation complete β {n_mastered}/{n_topics} topics above mastery threshold')
|
| 312 |
if st.button('π Generate Recommendations', type='primary'):
|
| 313 |
output=pipeline.run(mastery_vector)
|