raymondEDS commited on
Commit
dfe5163
·
1 Parent(s): fa60705

adding custom learning path

Browse files
requirements.txt CHANGED
@@ -4,4 +4,6 @@ streamlit
4
  numpy
5
  scikit-learn
6
  plotly
7
- seaborn
 
 
 
4
  numpy
5
  scikit-learn
6
  plotly
7
+ seaborn
8
+ networkx
9
+ plotly
src/modules/__pycache__/module3.cpython-311.pyc CHANGED
Binary files a/src/modules/__pycache__/module3.cpython-311.pyc and b/src/modules/__pycache__/module3.cpython-311.pyc differ
 
src/modules/__pycache__/module4.cpython-311.pyc ADDED
Binary file (13.9 kB). View file
 
src/modules/module3.py CHANGED
@@ -8,13 +8,6 @@ from sklearn.cluster import KMeans
8
  from sklearn.preprocessing import StandardScaler
9
  from sklearn.datasets import make_blobs
10
 
11
- # Set page config
12
- st.set_page_config(
13
- page_title="Machine Learning Visualizations",
14
- layout="wide",
15
- initial_sidebar_state="expanded"
16
- )
17
-
18
  def generate_regression_data(n_samples=100, noise=10):
19
  """Generate data for linear regression visualization."""
20
  np.random.seed(42)
@@ -35,8 +28,8 @@ def generate_clustering_data(n_samples=300):
35
  X, _ = make_blobs(n_samples=n_samples, centers=3, cluster_std=1.5)
36
  return X
37
 
38
- def show_student_view():
39
- """Display the student view of the module."""
40
  st.title("Interactive Machine Learning Visualizations")
41
 
42
  # Introduction
@@ -190,82 +183,4 @@ def show_student_view():
190
  - Linear Regression: Fits a line to predict continuous values
191
  - Logistic Regression: Creates a decision boundary for classification
192
  - K-Means Clustering: Groups similar data points into clusters
193
- """)
194
-
195
- def show_instructor_view():
196
- """Display the instructor view of the module."""
197
- st.title("Instructor View: Machine Learning Module")
198
-
199
- # Overview section
200
- st.info("""
201
- **Module Overview**
202
- This module covers three fundamental machine learning concepts with interactive visualizations.
203
- Students can experiment with different parameters and see real-time results.
204
- """)
205
-
206
- # Learning objectives
207
- st.subheader("Learning Objectives")
208
- st.markdown("""
209
- 1. Understand the basic principles of linear regression
210
- 2. Comprehend binary classification using logistic regression
211
- 3. Learn about unsupervised learning through k-means clustering
212
- 4. Develop intuition for model parameters and their effects
213
- """)
214
-
215
- # Student progress tracking
216
- st.subheader("Student Progress Tracking")
217
- progress_data = pd.DataFrame({
218
- 'Student': ['Student 1', 'Student 2', 'Student 3'],
219
- 'Linear Regression': [85, 90, 75],
220
- 'Logistic Regression': [80, 85, 70],
221
- 'Clustering': [90, 80, 85]
222
- })
223
- st.dataframe(progress_data)
224
-
225
- # Common misconceptions
226
- st.subheader("Common Misconceptions")
227
- st.markdown("""
228
- - Linear regression can only model linear relationships
229
- - Logistic regression is only for binary classification
230
- - K-means clustering always finds the optimal number of clusters
231
- """)
232
-
233
- # Teaching tips
234
- st.subheader("Teaching Tips")
235
- st.markdown("""
236
- 1. Start with simple examples and gradually increase complexity
237
- 2. Encourage students to experiment with different parameters
238
- 3. Use the visualizations to explain key concepts
239
- 4. Relate the concepts to real-world applications
240
- """)
241
-
242
- # Assessment guidelines
243
- st.subheader("Assessment Guidelines")
244
- st.markdown("""
245
- - Evaluate understanding through interactive exercises
246
- - Check comprehension of model parameters
247
- - Assess ability to interpret results
248
- - Review practical applications of each concept
249
- """)
250
-
251
- def show():
252
- """Main function to display the appropriate view based on user role."""
253
- # Check if user role is set in session state
254
- if 'user_role' not in st.session_state:
255
- # If not set, show role selection
256
- st.title("Welcome to the Machine Learning Module")
257
- role = st.radio("Select your role:", ["Student", "Instructor"])
258
- if st.button("Continue"):
259
- st.session_state.user_role = role
260
- st.experimental_rerun()
261
- else:
262
- # Display appropriate view based on role
263
- if st.session_state.user_role == "Student":
264
- show_student_view()
265
- else:
266
- show_instructor_view()
267
-
268
- # Add option to switch roles
269
- if st.sidebar.button("Switch Role"):
270
- del st.session_state.user_role
271
- st.experimental_rerun()
 
8
  from sklearn.preprocessing import StandardScaler
9
  from sklearn.datasets import make_blobs
10
 
 
 
 
 
 
 
 
11
  def generate_regression_data(n_samples=100, noise=10):
12
  """Generate data for linear regression visualization."""
13
  np.random.seed(42)
 
28
  X, _ = make_blobs(n_samples=n_samples, centers=3, cluster_std=1.5)
29
  return X
30
 
31
+ def show():
32
+ """Display the interactive machine learning visualizations."""
33
  st.title("Interactive Machine Learning Visualizations")
34
 
35
  # Introduction
 
183
  - Linear Regression: Fits a line to predict continuous values
184
  - Logistic Regression: Creates a decision boundary for classification
185
  - K-Means Clustering: Groups similar data points into clusters
186
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/modules/module4.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import plotly.graph_objects as go
3
+ import networkx as nx
4
+ import numpy as np
5
+
6
+ def create_intake_graph():
7
+ """Create the intake graph structure."""
8
+ G = nx.DiGraph()
9
+
10
+ # Add nodes with their categories
11
+ nodes = {
12
+ 'A': {'name': 'Student Enrollment', 'category': 'start'},
13
+ 'B': {'name': 'Learner Profile Assessment', 'category': 'assessment'},
14
+ 'C': {'name': 'Technical Background', 'category': 'profile'},
15
+ 'D': {'name': 'Mathematical Foundation', 'category': 'profile'},
16
+ 'E': {'name': 'Domain Knowledge', 'category': 'profile'},
17
+ 'F': {'name': 'Learning Preferences', 'category': 'profile'},
18
+ 'G': {'name': 'Prior Knowledge', 'category': 'profile'},
19
+ 'H': {'name': 'Profile Classification', 'category': 'classification'},
20
+ 'I': {'name': 'Learner Archetype', 'category': 'archetype'},
21
+ 'J': {'name': 'Advanced Technical Path', 'category': 'path'},
22
+ 'K': {'name': 'Accelerated Technical Path', 'category': 'path'},
23
+ 'L': {'name': 'Applied Research Path', 'category': 'path'},
24
+ 'M': {'name': 'Foundational Path', 'category': 'path'},
25
+ 'N': {'name': "Bloom's Taxonomy Outcomes", 'category': 'outcomes'},
26
+ 'O': {'name': 'Remember Level', 'category': 'bloom'},
27
+ 'P': {'name': 'Understand Level', 'category': 'bloom'},
28
+ 'Q': {'name': 'Apply Level', 'category': 'bloom'},
29
+ 'R': {'name': 'Analyze Level', 'category': 'bloom'},
30
+ 'S': {'name': 'Evaluate Level', 'category': 'bloom'},
31
+ 'T': {'name': 'Create Level', 'category': 'bloom'},
32
+ 'U': {'name': 'Adaptive Content Selection', 'category': 'content'},
33
+ 'V': {'name': 'Personalized Learning Activities', 'category': 'learning'},
34
+ 'W': {'name': 'Personalized Clustering Curriculum', 'category': 'final'},
35
+ }
36
+
37
+ # Add nodes to graph
38
+ for node_id, node_data in nodes.items():
39
+ G.add_node(node_id, **node_data)
40
+
41
+ # Add edges
42
+ edges = [
43
+ ('A', 'B'),
44
+ ('B', 'C'), ('B', 'D'), ('B', 'E'), ('B', 'F'), ('B', 'G'),
45
+ ('C', 'H'), ('D', 'H'), ('E', 'H'), ('F', 'H'), ('G', 'H'),
46
+ ('H', 'I'),
47
+ ('I', 'J'), ('I', 'K'), ('I', 'L'), ('I', 'M'),
48
+ ('J', 'N'), ('K', 'N'), ('L', 'N'), ('M', 'N'),
49
+ ('N', 'O'), ('N', 'P'), ('N', 'Q'), ('N', 'R'), ('N', 'S'), ('N', 'T'),
50
+ ('O', 'U'), ('P', 'U'), ('Q', 'U'), ('R', 'U'), ('S', 'U'), ('T', 'U'),
51
+ ('U', 'V'),
52
+ ('V', 'W')
53
+ ]
54
+ G.add_edges_from(edges)
55
+
56
+ return G
57
+
58
+ def get_node_colors(G):
59
+ """Get colors for different node categories."""
60
+ # Define colors with better contrast
61
+ category_colors = {
62
+ 'start': '#2E7D32', # Darker Green
63
+ 'assessment': '#1565C0', # Darker Blue
64
+ 'profile': '#F57F17', # Darker Amber
65
+ 'classification': '#6A1B9A', # Darker Purple
66
+ 'archetype': '#BF360C', # Darker Deep Orange
67
+ 'path': '#AD1457', # Darker Pink
68
+ 'outcomes': '#00695C', # Darker Cyan
69
+ 'bloom': '#283593', # Darker Indigo
70
+ 'content': '#E65100', # Darker Orange
71
+ 'learning': '#004D40', # Darker Teal
72
+ 'final': '#4527A0' # Darker Deep Purple
73
+ }
74
+ return [category_colors[G.nodes[node]['category']] for node in G.nodes()]
75
+
76
+ def create_interactive_graph(G):
77
+ """Create an interactive Plotly visualization of the graph."""
78
+ # Define node levels for hierarchical organization
79
+ node_levels = {
80
+ 'A': 0, # Student Enrollment
81
+ 'B': 1, # Learner Profile Assessment
82
+ 'C': 2, 'D': 2, 'E': 2, 'F': 2, 'G': 2, # Profile components
83
+ 'H': 3, # Profile Classification
84
+ 'I': 4, # Learner Archetype
85
+ 'J': 5, 'K': 5, 'L': 5, 'M': 5, # Learning Paths
86
+ 'N': 6, # Bloom's Taxonomy Outcomes
87
+ 'O': 7, 'P': 7, 'Q': 7, 'R': 7, 'S': 7, 'T': 7, # Bloom's levels
88
+ 'U': 8, # Adaptive Content Selection
89
+ 'V': 9, # Personalized Learning Activities
90
+ 'W': 10 # Personalized Clustering Curriculum
91
+ }
92
+
93
+ # Define key nodes that should be highlighted
94
+ key_nodes = {'A', 'B', 'H', 'I', 'N', 'W'}
95
+
96
+ # Calculate positions based on levels
97
+ pos = {}
98
+ level_nodes = {}
99
+ for node, level in node_levels.items():
100
+ if level not in level_nodes:
101
+ level_nodes[level] = []
102
+ level_nodes[level].append(node)
103
+
104
+ # Position nodes by level with increased spacing
105
+ for level in sorted(level_nodes.keys()):
106
+ nodes = level_nodes[level]
107
+ n_nodes = len(nodes)
108
+ for i, node in enumerate(nodes):
109
+ # Center nodes horizontally within their level with more spacing
110
+ x = (i - (n_nodes - 1) / 2) * 3 # Increased from 2 to 3
111
+ y = -level * 2.5 # Increased from 2 to 2.5
112
+ pos[node] = (x, y)
113
+
114
+ # Create edge traces with arrows
115
+ edge_x = []
116
+ edge_y = []
117
+ for edge in G.edges():
118
+ x0, y0 = pos[edge[0]]
119
+ x1, y1 = pos[edge[1]]
120
+ edge_x.extend([x0, x1, None])
121
+ edge_y.extend([y0, y1, None])
122
+
123
+ edge_trace = go.Scatter(
124
+ x=edge_x, y=edge_y,
125
+ line=dict(width=2, color='#888'),
126
+ hoverinfo='none',
127
+ mode='lines',
128
+ line_shape='spline'
129
+ )
130
+
131
+ # Create node traces
132
+ node_x = []
133
+ node_y = []
134
+ node_text = []
135
+ node_hover = []
136
+ node_sizes = []
137
+ node_colors = get_node_colors(G)
138
+
139
+ def format_node_text(text):
140
+ """Format node text with line breaks for multi-word labels."""
141
+ words = text.split()
142
+ if len(words) > 1:
143
+ return '<br>'.join(words) # Line break between words
144
+ return text
145
+
146
+ for i, node in enumerate(G.nodes()):
147
+ x, y = pos[node]
148
+ node_x.append(x)
149
+ node_y.append(y)
150
+ category = G.nodes[node]['category']
151
+ node_text.append(format_node_text(G.nodes[node]['name']))
152
+ node_hover.append(f"""
153
+ <b>{G.nodes[node]['name']}</b><br>
154
+ Category: {category.title()}<br>
155
+ Click to learn more
156
+ """)
157
+ # Make key nodes larger
158
+ node_sizes.append(45 if node in key_nodes else 35)
159
+
160
+ # Create separate traces for nodes
161
+ node_trace = go.Scatter(
162
+ x=node_x, y=node_y,
163
+ mode='markers',
164
+ hoverinfo='text',
165
+ hovertext=node_hover,
166
+ marker=dict(
167
+ showscale=False,
168
+ color=node_colors,
169
+ size=node_sizes,
170
+ line_width=3,
171
+ line=dict(color='white')
172
+ )
173
+ )
174
+
175
+ # Add text annotations for each node
176
+ annotations = []
177
+ for i, (x, y, text) in enumerate(zip(node_x, node_y, node_text)):
178
+ # Adjust vertical offset based on text length
179
+ y_offset = 0.15 if ' ' in text else 0.1
180
+
181
+ annotations.append(
182
+ dict(
183
+ x=x,
184
+ y=y + y_offset,
185
+ text=text,
186
+ showarrow=False,
187
+ textangle=0, # No tilting
188
+ font=dict(
189
+ size=14,
190
+ color='white',
191
+ family='Arial Black'
192
+ ),
193
+ xanchor='center',
194
+ yanchor='bottom'
195
+ )
196
+ )
197
+
198
+ # Create figure with adjusted layout
199
+ fig = go.Figure(data=[edge_trace, node_trace],
200
+ layout=go.Layout(
201
+ showlegend=False,
202
+ hovermode='closest',
203
+ margin=dict(b=20, l=5, r=5, t=40),
204
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
205
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
206
+ plot_bgcolor='#1E1E1E',
207
+ paper_bgcolor='#1E1E1E',
208
+ font=dict(color='white', size=14, family='Arial'),
209
+ height=1200,
210
+ dragmode='pan', # Enable panning
211
+ annotations=annotations + [
212
+ dict(
213
+ text="Hover over nodes to see details<br>Use pan mode to move around",
214
+ showarrow=False,
215
+ xref="paper",
216
+ yref="paper",
217
+ x=0,
218
+ y=1.1,
219
+ font=dict(size=16, color='white', family='Arial Black')
220
+ )
221
+ ]
222
+ ))
223
+
224
+ # Add arrows to edges
225
+ for edge in G.edges():
226
+ x0, y0 = pos[edge[0]]
227
+ x1, y1 = pos[edge[1]]
228
+ # Calculate arrow position (80% along the edge)
229
+ arrow_x = x0 + 0.8 * (x1 - x0)
230
+ arrow_y = y0 + 0.8 * (y1 - y0)
231
+
232
+ fig.add_annotation(
233
+ x=arrow_x,
234
+ y=arrow_y,
235
+ axref="x",
236
+ ayref="y",
237
+ ax=x0,
238
+ ay=y0,
239
+ xref="x",
240
+ yref="y",
241
+ showarrow=True,
242
+ arrowhead=2,
243
+ arrowsize=1,
244
+ arrowwidth=2,
245
+ arrowcolor="#888"
246
+ )
247
+
248
+ # Add interactive features
249
+ fig.update_layout(
250
+ modebar=dict(
251
+ add=['drawopenpath', 'eraseshape'],
252
+ remove=['lasso2d', 'select2d']
253
+ )
254
+ )
255
+
256
+ return fig
257
+
258
+ def show():
259
+ """Display the interactive intake graph."""
260
+ st.title("Customized Learning Path")
261
+
262
+ # Create two columns for layout
263
+ col1, col2 = st.columns([2, 1])
264
+
265
+ with col1:
266
+ st.info("""
267
+ This interactive flowchart visualizes your personalized learning journey from enrollment to curriculum.
268
+ - Hover over nodes to see detailed information
269
+ - Follow the arrows to understand the learning progression
270
+ - Explore different paths based on your profile
271
+ """)
272
+
273
+ # Create and display the graph
274
+ G = create_intake_graph()
275
+ fig = create_interactive_graph(G)
276
+ st.plotly_chart(fig, use_container_width=True)
277
+
278
+ with col2:
279
+ st.subheader("Bloom's Taxonomy Research")
280
+
281
+ st.markdown("""
282
+ ### Key Research Papers
283
+
284
+ #### Original Taxonomy (1956)
285
+ - [Bloom, B. S. (1956). Taxonomy of Educational Objectives: The Classification of Educational Goals](https://doi.org/10.1177/001316445601600310)
286
+
287
+ #### Revised Taxonomy (2001)
288
+ - [Anderson, L. W., & Krathwohl, D. R. (2001). A Taxonomy for Learning, Teaching, and Assessing](https://doi.org/10.1207/s15430421tip4104_2)
289
+
290
+ #### Digital Age Applications
291
+ - [Churches, A. (2008). Bloom's Digital Taxonomy](https://doi.org/10.1007/978-1-4419-1428-6_1)
292
+
293
+ #### Modern Learning Applications
294
+ - [Armstrong, P. (2010). Bloom's Taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/)
295
+
296
+ ### Key Concepts
297
+
298
+ #### Cognitive Process
299
+ 1. **Remember**: Recall facts and basic concepts
300
+ 2. **Understand**: Explain ideas or concepts
301
+ 3. **Apply**: Use information in new situations
302
+ 4. **Analyze**: Draw connections among ideas
303
+ 5. **Evaluate**: Justify a stand or decision
304
+ 6. **Create**: Produce new or original work
305
+
306
+ #### Knowledge Dimensions
307
+ - **Factual**: Basic elements
308
+ - **Conceptual**: Interrelationships
309
+ - **Procedural**: How to do something
310
+ - **Metacognitive**: Knowledge of cognition
311
+ """)
312
+
313
+ # Add a legend for key nodes with summaries
314
+ st.subheader("Key Learning Path Components")
315
+ key_nodes = {
316
+ 'Student Enrollment': {
317
+ 'color': '#2E7D32',
318
+ 'summary': 'Initial entry point where students begin their learning journey'
319
+ },
320
+ 'Learner Profile Assessment': {
321
+ 'color': '#1565C0',
322
+ 'summary': 'Comprehensive evaluation of student background and capabilities'
323
+ },
324
+ 'Profile Classification': {
325
+ 'color': '#6A1B9A',
326
+ 'summary': 'Categorization of student profiles based on assessment results'
327
+ },
328
+ 'Learner Archetype': {
329
+ 'color': '#BF360C',
330
+ 'summary': 'Identification of student learning style and preferences'
331
+ },
332
+ "Bloom's Taxonomy Outcomes": {
333
+ 'color': '#283593',
334
+ 'summary': 'Framework for defining learning objectives and outcomes'
335
+ },
336
+ 'Personalized Clustering Curriculum': {
337
+ 'color': '#4527A0',
338
+ 'summary': 'Final customized learning path based on all assessments'
339
+ }
340
+ }
341
+
342
+ for node, info in key_nodes.items():
343
+ st.markdown(f"""
344
+ <div style='background-color: {info['color']}; padding: 10px; border-radius: 5px; margin-bottom: 10px;'>
345
+ <div style='color: white; font-weight: bold;'>{node}</div>
346
+ <div style='color: white; font-size: 0.9em;'>{info['summary']}</div>
347
+ </div>
348
+ """, unsafe_allow_html=True)
src/streamlit_app.py CHANGED
@@ -1,6 +1,6 @@
1
  import streamlit as st
2
  import os
3
- from modules import intro, module1, module2, module3, assignments, resources
4
  from config import CUSTOM_CSS
5
 
6
  # Set page configuration
@@ -23,6 +23,7 @@ course_sections = {
23
  "Module 1: Getting Started": (module1.show, "module1"),
24
  "Module 2: Learning from Examples": (module2.show, "module2"),
25
  "Module 3: Machine Learning Demo": (module3.show, "module3"),
 
26
  "Assignments": (assignments.show, "assignments"),
27
  "Resources": (resources.show, "resources")
28
  }
 
1
  import streamlit as st
2
  import os
3
+ from modules import intro, module1, module2, module3,module4, assignments, resources
4
  from config import CUSTOM_CSS
5
 
6
  # Set page configuration
 
23
  "Module 1: Getting Started": (module1.show, "module1"),
24
  "Module 2: Learning from Examples": (module2.show, "module2"),
25
  "Module 3: Machine Learning Demo": (module3.show, "module3"),
26
+ "Module 4: Custom Learning Path": (module4.show, "module4"),
27
  "Assignments": (assignments.show, "assignments"),
28
  "Resources": (resources.show, "resources")
29
  }