
Learner Profiles
How to build effective learner profiles for personalised education. Discover techniques for modelling student preferences, knowledge, and goals.
Learner Profiles: Understanding Individual Students for Personalised Education
Learner profiles are digital representations of individual students that capture their knowledge, preferences, goals, and learning patterns. These profiles power personalised learning experiences by helping systems understand who each student is and how they learn best.
What is a Learner Profile?
Core Definition
A learner profile is a structured collection of data about an individual student that informs educational decisions and personalisation.
Key Components:
1. Knowledge State: What they know
2. Preferences: How they like to learn
3. Goals: What they want to achieve
4. Behavior Patterns: How they actually learn
5. Context: Their circumstances and constraintsWhy Learner Profiles Matter
Without Profiles:
One-size-fits-all approach:
- Same content for everyone
- Same pace for everyone
- Same path for everyone
- Limited effectivenessWith Profiles:
Personalised approach:
- Content matched to knowledge level
- Pace adjusted to learning speed
- Path aligned with goals
- Increased engagement and outcomesResearch Evidence:
Studies show personalised learning improves:
- Retention: +15-30%
- Engagement: +20-40%
- Completion rates: +10-25%
- Skill acquisition: +20-35%Components of Learner Profiles
1. Knowledge Model
What the Learner Knows:
Skill Mastery:
Skill: Python Functions
Mastery level: 0.75 (75%)
Confidence: High
Last assessed: Jan 2, 2026
Evidence:
- Quiz score: 90%
- 3 coding challenges completed
- Applied in project successfullyConcept Graph:
data_structures
├── arrays (mastered: 0.9)
│ ├── indexing (mastered: 1.0) ✓
│ ├── slicing (mastered: 0.8)
│ └── methods (mastered: 0.7)
├── dictionaries (mastered: 0.5)
│ ├── creation (mastered: 0.8)
│ ├── access (mastered: 0.6)
│ └── methods (mastered: 0.3) ← Current focus
└── lists (mastered: 0.95) ✓Knowledge Representation:
class KnowledgeState:
def __init__(self):
self.skills = {}
def update_skill(self, skill_name, performance):
if skill_name not in self.skills:
self.skills[skill_name] = Skill(skill_name)
skill = self.skills[skill_name]
skill.update_mastery(performance)
def get_mastery(self, skill_name):
return self.skills.get(skill_name, Skill(skill_name)).mastery
class Skill:
def __init__(self, name):
self.name = name
self.mastery = 0.0
self.attempts = []
self.last_practiced = None
def update_mastery(self, performance):
# Bayesian update
self.attempts.append(performance)
self.mastery = self.calculate_mastery()
self.last_practiced = datetime.now()
def calculate_mastery(self):
# Weighted average favoring recent performance
if not self.attempts:
return 0.0
weights = [0.5 ** i for i in range(len(self.attempts)-1, -1, -1)]
weighted_sum = sum(w * p for w, p in zip(weights, self.attempts))
return weighted_sum / sum(weights)2. Learning Preferences
Content Format Preferences:
Preferred learning modalities:
- Visual: High preference (learns best from diagrams, videos)
- Auditory: Medium (benefits from explanations, discussions)
- Kinesthetic: High (needs hands-on practice, examples)
- Reading: Medium (can learn from text, but not primary)
Example action:
→ For new concept, start with visual diagram, then
interactive example, supplement with text explanationPacing Preferences:
Learning speed: Self-paced preferred
Session duration: 30-45 minutes optimal
Frequency: 3-4 sessions per week
Time of day: Evening (7-9pm)
Example action:
→ Break long modules into 30-minute chunks
→ Send reminders in early eveningDifficulty Preferences:
Challenge level: Moderate-high
Risk tolerance: Medium
- Willing to attempt difficult problems
- Needs scaffold for very hard content
- Appreciates hints available
Frustration tolerance: Medium
- Can persist through 2-3 failed attempts
- Needs encouragement after that
- Responds well to breaking problems down
Example action:
→ Start with challenging problem
→ After 2 failures, offer hint
→ After 4 failures, break into sub-problemsFeedback Preferences:
Feedback timing: Immediate preferred
Feedback detail: High (wants explanation, not just correct/incorrect)
Feedback tone: Encouraging but honest
Progress visibility: High (wants dashboards, metrics)
Example action:
→ Show immediate detailed feedback with explanation
→ Include "Great effort!" along with corrections
→ Display progress bar and mastery metrics3. Goals and Motivation
Learning Objectives:
Primary goal: "Get job as junior developer"
- Timeline: 6 months
- Specific: Python web development
- Success criteria: Portfolio + first job offer
Sub-goals:
1. Master Python basics (3 months)
2. Learn Django framework (2 months)
3. Build 3 portfolio projects (ongoing)
4. Prepare for interviews (1 month)
Current progress:
- Python basics: 75% complete ✓
- Django: Not started
- Projects: 1 of 3 completeMotivation Profile:
Intrinsic motivation: High
- Enjoys problem-solving
- Curious about how things work
- Finds coding satisfying
Extrinsic motivation: High
- Career advancement
- Financial improvement
- Recognition
Motivational strategies that work:
✓ Show real-world applications
✓ Celebrate achievements (badges, certificates)
✓ Connect to career goals
✓ Provide progress metrics
Strategies that don't work:
✗ Competition with others (demotivating)
✗ Pressure/deadlines (causes anxiety)Engagement Patterns:
High engagement triggers:
- New challenging content
- Real-world projects
- Visible progress
- Community interaction
Low engagement triggers:
- Repetitive exercises
- Unclear relevance
- No feedback
- Feeling stuck
Example action:
→ When engagement drops, introduce new project-based
learning or connect current content to career goals4. Behavioral Patterns
Learning Strategies:
Observed behaviors:
- Systematic learner (follows sequential path)
- Note-taker (creates summaries)
- Hands-on (runs every code example)
- Help-seeker (asks questions when stuck)
Example profile:
Learning style: Active experimentation
- Tries things immediately
- Learns from failures
- Iterates rapidly
→ Provide interactive playgrounds, encourage experimentation,
make it safe to failError Patterns:
Common mistakes:
- Syntax errors: Off-by-one errors in loops
- Logic errors: Forgets edge cases
- Conceptual: Confuses shallow vs deep copy
Growth areas:
- Testing: Rarely writes tests
- Documentation: Minimal comments
- Planning: Jumps to coding before thinking
Example action:
→ Provide off-by-one checker in exercises
→ Add edge case reminders
→ Introduce TDD methodologySocial Learning:
Community engagement: Active
- Forum posts: 15 per month
- Helps others: 8 responses
- Asks questions: 5 questions
- Study groups: Member of 1 group
Social learning preference: High
- Benefits from peer explanation
- Motivated by helping others
- Learns well in discussions
Example action:
→ Recommend study groups for new topics
→ Invite to mentor beginners
→ Facilitate peer code review5. Context and Constraints
Time Availability:
Work schedule: Full-time (9am-5pm)
Family commitments: Evening (5-7pm)
Available for learning: 7-10pm weekdays, Saturday mornings
Total weekly time: ~15 hours
Planning consideration:
→ Realistic pace: Complete 2-3 modules per week
→ Flexible deadlines
→ Weekend intensive options availableTechnology Access:
Devices: Laptop (primary), smartphone (mobile)
Internet: Stable broadband at home
Software: Can install tools
Learning environment: Quiet home office
Limitations:
- No access during work hours
- Mobile learning limited (phone)
Example action:
→ Optimise for laptop experience
→ Provide offline mode for content
→ Keep mobile app for reviewing notes, flashcardsPrior Knowledge:
Education: Bachelor's in business
Programming experience: None (complete beginner)
Related skills: Excel, SQL (intermediate)
Languages: English (native), Spanish (conversational)
Strengths to leverage:
- SQL knowledge → Easy transition to data work
- Business background → Understand requirements
- Excel skills → Comfortable with logic
Example action:
→ Draw parallels between SQL and Python
→ Use business examples in exercises
→ Leverage existing problem-solving skillsBuilding Learner Profiles
Initial Profile Creation
Onboarding Survey:
1. Background:
□ What's your current experience with programming?
□ What's your educational background?
□ Have you learned similar skills before?
2. Goals:
□ Why are you taking this course?
□ What do you want to achieve?
□ Timeline?
3. Preferences:
□ How do you prefer to learn? (visual, hands-on, etc.)
□ What time of day do you study best?
□ Do you like working alone or in groups?
4. Constraints:
□ How much time can you dedicate weekly?
□ What devices will you use?
□ Any accessibility needs?Example Implementation:
class ProfileBuilder:
def create_initial_profile(self, user_id, survey_responses):
profile = LearnerProfile(user_id)
# Background
profile.set_prior_knowledge(
survey_responses['experience_level'],
survey_responses['education'],
survey_responses['related_skills']
)
# Goals
profile.set_goals(
primary_goal=survey_responses['main_goal'],
timeline=survey_responses['timeline'],
success_criteria=survey_responses['success_criteria']
)
# Preferences (initial guess, will refine)
profile.set_preferences(
learning_style=survey_responses['learning_style'],
preferred_pace=survey_responses['pace'],
social_preference=survey_responses['social_learning']
)
# Constraints
profile.set_constraints(
time_availability=survey_responses['weekly_hours'],
schedule=survey_responses['available_times'],
devices=survey_responses['devices']
)
return profileDiagnostic Assessment:
Purpose: Establish baseline knowledge
Example:
1. Place student in appropriate starting point
2. Identify knowledge gaps
3. Discover misconceptions
Adaptive diagnostic:
- Start with medium difficulty question
- If correct → Harder question
- If incorrect → Easier question
- Converge on skill level quickly
Result:
"Based on your assessment, you have:
- Strong: Variables, basic syntax ✓
- Some knowledge: Functions
- No experience: Object-oriented programming
We'll start you in Module 3: Intermediate Python"Continuous Profile Updates
Explicit Updates:
Learner-initiated changes:
- Update goals
- Change pace settings
- Modify preferences
- Report issues
Example:
"My learning goal has changed from web development
to data science. Can you adjust my learning path?"
→ System updates goal in profile
→ Recommends data science track
→ Adjusts content recommendationsImplicit Updates (Learning):
class ProfileUpdater:
def update_from_interaction(self, user_id, interaction):
profile = self.get_profile(user_id)
# Update knowledge state
if interaction.type == 'assessment':
profile.knowledge.update_skill(
skill=interaction.skill,
performance=interaction.score,
timestamp=interaction.timestamp
)
# Update engagement patterns
if interaction.type == 'content_view':
profile.engagement.log_interaction(
content_type=interaction.content_type,
duration=interaction.duration,
completion=interaction.completed
)
# Update preferences (implicit signals)
if interaction.duration < expected_duration * 0.5:
profile.preferences.decrease_preference(
content_type=interaction.content_type,
reason='early_exit'
)
# Update behavioral patterns
profile.behavior.add_pattern(
pattern_type=interaction.pattern,
timestamp=interaction.timestamp
)
self.save_profile(profile)Pattern Detection:
Automated pattern recognition:
Time preferences:
- Track login times
- Detect peak engagement hours
- Adjust reminder schedule
Difficulty preference:
- Monitor challenge level vs engagement
- Track frustration signals (many attempts, exit)
- Adjust content difficulty
Learning style:
- Track content type engagement
- Videos: 85% completion
- Text: 60% completion
- Interactive: 95% completion
→ Infer preference for interactive content
Pacing:
- Monitor progress speed
- Compare to cohort
- Detect acceleration/deceleration
→ Adjust recommendations accordinglyValidation and Refinement
Profile Accuracy Checks:
1. Prediction accuracy:
- Does predicted performance match actual?
- Are recommendations engaging?
- Do interventions work?
2. Feedback loops:
- Ask learner: "Is this recommendation helpful?"
- Ratings: "How well does this match your level?"
- Adjustments: "Too easy/hard?"
3. A/B testing:
- Test different personalisation strategies
- Measure effectiveness
- Refine modelsExample Validation:
def validate_profile_accuracy(profile, recent_interactions):
# Check knowledge state accuracy
predicted_performance = profile.knowledge.predict_performance(skill)
actual_performance = recent_interactions.get_performance(skill)
accuracy = 1 - abs(predicted_performance - actual_performance)
# Check preference accuracy
recommended_content = profile.get_recommendations()
engagement = recent_interactions.get_engagement(recommended_content)
preference_accuracy = engagement / expected_engagement
# Adjust profile confidence
if accuracy < 0.7:
profile.reduce_confidence()
profile.schedule_refinement()
return {
'knowledge_accuracy': accuracy,
'preference_accuracy': preference_accuracy,
'overall_health': (accuracy + preference_accuracy) / 2
}Using Learner Profiles
Personalised Recommendations
Content Recommendations:
def recommend_next_content(profile):
# Get knowledge state
mastery = profile.knowledge.get_overall_mastery()
weak_skills = profile.knowledge.get_weakest_skills(n=3)
# Get goals
goal_skills = profile.goals.get_required_skills()
# Get preferences
preferred_types = profile.preferences.get_preferred_content_types()
# Find content matching:
# 1. Addresses weak skills OR advances toward goals
# 2. Appropriate difficulty
# 3. Preferred format
candidates = content_db.query(
skills=weak_skills + goal_skills,
difficulty_range=(mastery - 0.2, mastery + 0.3),
content_types=preferred_types
)
# Rank by relevance
ranked = rank_by_relevance(
candidates,
profile.goals.priority_skills,
profile.engagement.past_engagement
)
return ranked[0] # Top recommendationLearning Path Personalisation:
Standard path:
Module 1 → Module 2 → Module 3 → Module 4
Personalised for Alice (Python experience):
[Diagnostic: Already knows Module 1] ✓
→ Skip Module 1
→ Start Module 2
→ Module 3 (extend: add advanced topics)
→ Module 4
→ Bonus: Advanced project
Personalised for Bob (struggling):
→ Module 1 (add extra practice)
→ Module 1.5 (bridge content)
→ Module 2 (standard)
→ Module 3 (add scaffolding)
→ Module 4Adaptive Difficulty
Dynamic Adjustment:
def select_next_problem(profile, topic):
# Get current skill level
current_mastery = profile.knowledge.get_mastery(topic)
# Get preferred challenge level
challenge_pref = profile.preferences.challenge_level
# Calculate optimal difficulty
# (slightly above current mastery = zone of proximal development)
if challenge_pref == 'high':
target_difficulty = current_mastery + 0.3
elif challenge_pref == 'medium':
target_difficulty = current_mastery + 0.2
else: # low
target_difficulty = current_mastery + 0.1
# Get problem matching difficulty
problem = problem_db.get_problem(
topic=topic,
difficulty=target_difficulty,
exclude=profile.completed_problems
)
return problemScaffolding:
For struggling learners:
- Hints available
- Step-by-step guidance
- Worked examples
- Partial solutions
For advanced learners:
- Minimal hints
- Open-ended problems
- Extension challenges
- Real-world scenariosPersonalised Feedback
Tailored to Learning Style:
Visual learner:
❌ "Your solution is incorrect"
✓ "Your solution: [diagram]
Expected: [diagram]
Difference: [highlighted diagram]"
Analytical learner:
✓ "Your solution produced output: [5, 6, 7, 8]
Expected output: [6, 7, 8, 9]
Issue: Off-by-one error (starting index)
Line 3: range(1, 5) should be range(2, 6)"Motivational Alignment:
Career-motivated learner:
✓ "Great work! This sorting algorithm skill is used in
87% of junior developer interviews. You're building
valuable career skills."
Intrinsically-motivated learner:
✓ "Excellent! You've discovered an elegant solution.
Notice how this algorithm is more efficient than
the previous approach?"Intervention Triggers
At-Risk Detection:
def check_interventions_needed(profile):
interventions = []
# Check engagement
if profile.engagement.recent_sessions < 2 and \
days_since_last_login(profile) > 5:
interventions.append({
'type': 'engagement',
'action': 'send_reminder_email',
'message': f"We miss you! Your goal of {profile.goals.primary}
is waiting. Just 30 minutes today can keep you on track."
})
# Check performance
recent_scores = profile.knowledge.get_recent_scores(n=5)
if mean(recent_scores) < 0.6:
interventions.append({
'type': 'struggling',
'action': 'offer_help',
'message': "Having trouble? Let's schedule office hours or
we can recommend additional practice exercises."
})
# Check frustration
if profile.behavior.consecutive_failures > 3:
interventions.append({
'type': 'frustration',
'action': 'provide_hint',
'message': "This is challenging! Here's a hint to get you unstuck..."
})
return interventionsPrivacy and Ethics
Data Collection
Transparency:
Tell learners:
✓ What data is collected
✓ How profile is built
✓ How it's used for personalisation
✓ Who has access
✓ How long it's stored
✓ How to view/modify/deleteConsent:
Opt-in approach:
"We can personalise your learning experience by:
- Tracking your progress
- Recommending content
- Adapting difficulty
- Predicting challenges
[X] Yes, personalise my experience
[ ] No thanks, I'll follow the standard path
You can change this anytime in settings."Profile Control
Learner Access:
Profile Dashboard:
"Your Learner Profile"
Knowledge State:
- Python basics: 85% mastered
- Functions: 70% mastered
- Data structures: 45% mastered
[View details]
Preferences:
- Learning style: Visual, hands-on
- Pace: Self-paced
- Difficulty: Medium-high
[Edit preferences]
Goals:
- Primary: Get developer job (6 months)
- Current progress: 45%
[Update goals]
Data Management:
- Download my profile data
- Reset my profile
- Delete my profileCorrections:
Allow learners to:
✓ Correct misclassifications
✓ Update preferences
✓ Challenge predictions
✓ Opt out of specific tracking
Example:
"We think you prefer video content, but your engagement
is low. Would you prefer text and interactive exercises?"
[Yes, update my preference]Bias Prevention
Avoiding Stereotypes:
Don't assume based on demographics:
❌ Age → Learning ability
❌ Gender → Subject interest
❌ Background → Career goals
❌ Location → Opportunity
Instead, rely on:
✓ Observed behavior
✓ Stated preferences
✓ Actual performance
✓ Individual goalsEquitable Personalisation:
Ensure profiles don't create:
- Self-fulfilling prophecies (low expectations → low outcomes)
- Tracking (limiting opportunities based on past performance)
- Homogenization (everyone in a box)
Instead:
- High expectations for all
- Multiple pathways to success
- Opportunities to surprise the model
- Regular re-assessmentAdvanced Topics
Multi-Dimensional Profiles
Beyond Simple Attributes:
Instead of:
learning_style = "visual"
Use:
learning_preferences = {
'visual': 0.8,
'auditory': 0.5,
'kinesthetic': 0.9,
'reading': 0.6
}
Context-dependent:
- New topics: Prefers visual introduction
- Practice: Prefers kinesthetic (hands-on)
- Review: Prefers reading (text summaries)Temporal Dynamics
Profiles Change Over Time:
Beginner Alice (Month 1):
- Knowledge: Low (0.2)
- Confidence: Low
- Pace: Slow
- Help-seeking: High
Intermediate Alice (Month 3):
- Knowledge: Medium (0.6)
- Confidence: Growing
- Pace: Moderate
- Help-seeking: Medium
Advanced Alice (Month 6):
- Knowledge: High (0.85)
- Confidence: High
- Pace: Fast
- Help-seeking: Low (helps others instead)
→ Personalisation must adapt to growthCross-Context Profiles
Portable Learner Profiles:
Vision: Profile follows learner across platforms
Standards:
- IMS Caliper (learning analytics)
- xAPI (experience API)
- W3C Verifiable Credentials
Benefits:
- No "starting over" on each platform
- Consistent personalisation
- Lifelong learning record
Challenges:
- Privacy (sensitive data portability)
- Interoperability (different systems)
- Consent (who owns the profile?)Implementation Example
class LearnerProfile:
def __init__(self, user_id):
self.user_id = user_id
self.knowledge = KnowledgeModel()
self.preferences = PreferenceModel()
self.goals = GoalModel()
self.behavior = BehaviorModel()
self.context = ContextModel()
self.metadata = ProfileMetadata()
def personalise_experience(self, current_context):
# Get next best action
next_content = self.recommend_content(current_context)
difficulty = self.calculate_difficulty()
feedback_style = self.get_feedback_style()
return {
'content': next_content,
'difficulty': difficulty,
'feedback': feedback_style,
'interventions': self.check_interventions()
}
def recommend_content(self, context):
# Combine knowledge state, goals, preferences
knowledge_gaps = self.knowledge.get_priority_gaps()
goal_alignment = self.goals.get_next_skills()
preferred_types = self.preferences.content_types
# Weight factors
recommendations = content_engine.get_recommendations(
knowledge_gaps=knowledge_gaps,
goals=goal_alignment,
preferences=preferred_types,
context=context
)
return recommendations[0] # Top recommendation
def calculate_difficulty(self):
mastery = self.knowledge.get_current_mastery()
challenge_pref = self.preferences.challenge_level
recent_performance = self.behavior.recent_success_rate
# Adjust for recent performance
if recent_performance < 0.5:
# Struggling → easier content
return mastery + 0.1
elif recent_performance > 0.8:
# Succeeding → harder content
return mastery + 0.3
else:
# Balanced
return mastery + 0.2
def update(self, interaction):
# Update all models based on interaction
self.knowledge.update(interaction)
self.behavior.log(interaction)
self.preferences.adjust(interaction)
self.metadata.last_updated = datetime.now()
def check_interventions(self):
# Check if any interventions needed
interventions = []
if self.is_at_risk():
interventions.append(self.create_engagement_intervention())
if self.is_struggling():
interventions.append(self.create_support_intervention())
if self.is_ready_for_challenge():
interventions.append(self.create_stretch_intervention())
return interventionsNext Steps
Explore related topics:
Effective learner profiles are the foundation of personalised education. By understanding each student as an individual—their knowledge, preferences, goals, and context—we can create learning experiences that are more engaging, effective, and equitable.