tranhuonglan
first commit
e448441
import numpy as np
import matplotlib.pyplot as plt
import os
from matplotlib.colors import LinearSegmentedColormap
from collections import Counter
import seaborn as sns
def plot_each_feature_alpha(alpha, size, feature_list):
cumsum = 0
fig, ax = plt.subplots(2, 4, figsize=(18, 10))
fig.tight_layout(pad=3.0)
color = ['purple', 'orange', 'green', 'pink']
for id, column in enumerate(feature_list):
bars = np.arange(size[id])
ax[id//4][id%4].bar(bars, alpha[cumsum:cumsum+size[id]], color=color[:size[id]])
ax[id//4][id%4].set_xticks(bars, bars)
ax[id//4][id%4].set_title(column)
cumsum += size[id]
plt.legend()
plt.show()
def plot_feature_alpha(alpha, size, feature_list, title, course_id='dsp_001'):
cumsum = 0
fig, ax = plt.subplots(figsize=(16, 8))
color = ['lightblue', 'dodgerblue', 'blue', 'navy']
group = {}
# replace _ with space for every element in feature_list
feature_list = [x.replace('_', ' ') for x in feature_list]
for i in range(len(size)):
for j in range(max(size)):
if j not in group:
group[j] = []
if j < size[i]:
group[j].append(alpha[cumsum+j])
else:
group[j].append(0)
cumsum += size[i]
bar = np.arange(len(feature_list))
width = 0.18
for i in range(max(size)):
plt.bar(bar + width*i, group[i], color=color[i], width=width, edgecolor='black', label=i)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
plt.axhline(alpha[-1], color='black', linestyle='--', label='bias')
plt.xlabel("Metric")
plt.ylabel("Value of alpha")
plt.title(title)
plt.grid(axis='y', linestyle='-', alpha=0.6)
plt.xticks(bar, feature_list, rotation=45)
plt.legend()
title = title.split(' ')
title = '-'.join(title)
if not os.path.exists(f'results/features/{course_id}'):
os.makedirs(f'results/features/{course_id}')
plt.savefig(f'results/features/{course_id}/{title}alpha.png')
plt.show()
# -----------------------------------------------------------
# Plotting functions for raw clickstream environment
def plot_alpha(alpha, dict_event, dict_action, title=""):
fig, ax = plt.subplots(1, 2, figsize=(10, 4))
alpha = alpha
ax[0].bar(list(dict_event.values()), alpha[:len(dict_event)], align='center',
color=['red' if v < 0 else 'green' for v in alpha[:len(dict_event)]])
ax[0].set_title(title + 'Event weight')
ax[1].bar(list(dict_action.values()), alpha[len(dict_event):len(dict_event)+len(dict_action)], align='center',
color=['red' if v < 0 else 'green' for v in alpha[len(dict_event):]])
ax[1].set_xticklabels(labels=list(dict_action.values()), rotation = 90)
ax[1].set_title(title + 'Action weight')
plt.show()
def plot_all_weeks_alpha(history, dict_event, dict_action,
unique_week=np.arange(10), path=None, title="", whatif=False, topics=[], schedule=None):
lines = 2
cols = len(history)//lines + (len(history)%2!=0)
fig1, ax = plt.subplots(lines, cols, figsize=(5*cols, 4*lines))
if lines == 1:
ax = np.array([ax]).flatten()
for i in range(len(history)):
alpha = history[i]['alpha']
if (len(alpha)==0):
continue
subtitle = f'Week {i + 1}'
axis = ax[i // cols, i % cols] if lines > 1 else ax[i]
if whatif:
axis.bar(np.arange(len(alpha)), alpha, align='center',
color=['red' if v < 0 else 'green' for v in alpha])
labels = list(['Chapter_'+str(x) for x in topics.keys()])
labels.extend(['Chapter Complex', 'Values Prob', 'Value Video', 'Is problem', 'Is video'])
labels.extend(['Action' + str(x) for x in list(dict_action.keys())])
axis.set_xticks(np.arange(len(alpha)), labels=labels)
axis.set_xticklabels(labels=labels, rotation = 90)
else:
axis.bar(np.arange(len(dict_event)), alpha[:len(dict_event)], align='center',
color=['red' if v < 0 else 'green' for v in alpha[:len(dict_event)]], label='Event')
n_event_action = len(dict_event) + len(dict_action)
axis.bar(np.arange(len(dict_event), len(dict_event) + len(dict_action)), alpha[len(dict_event):n_event_action], align='center',
color=['violet' if v < 0 else 'cyan' for v in alpha[len(dict_event):]], label='Action')
if (len(alpha) > n_event_action):
axis.bar(len(alpha), alpha[-1], align='center', color='black', linewidth=2, label='Intercept')
axis.axhline(y=alpha[-1], color='black', linestyle='--')
axis.set_title(subtitle)
fig1.suptitle(title + 'Event & action weight', weight='bold')
fig1.tight_layout()
fig2, ax = plt.subplots(lines, cols, figsize=(20, 4*lines))
if lines == 1:
ax = np.array([ax]).flatten()
for i in range(len(history)):
train_loss = history[i]['train loss']
if (len(train_loss)==0):
continue
subtitle = f'Week {i + 1}'
axis = ax[i // cols, i % cols] if lines > 1 else ax[i]
axis.plot(np.arange(len(train_loss)), train_loss)
axis.set_title(subtitle)
fig2.suptitle(title + 'Train loss', weight='bold')
if path is not None:
if not os.path.exists(path):
os.makedirs(path)
save_title = title.split(' ')
save_title = '-'.join(save_title)
fig1.savefig(os.path.join(path, save_title + 'alpha.jpg'))
fig2.savefig(os.path.join(path, save_title +'train_loss.jpg'))
fig2.tight_layout()
plt.legend()
plt.tight_layout()
plt.show()
plt.close('all')
def plot_all_weeks_reward(history, dict_event, dict_action,
unique_week=np.arange(10), main_title="", path=None, schedule=None):
"""
Plot reward for all weeks
return heatmap of reward
"""
map_label_event = list(dict_event.keys())
if schedule is not None:
map_label_event = [schedule.iloc[x]['chapter'] for x in dict_event.keys()]
# Define layout (rows and columns) dynamically based on number of weeks
lines = 2
cols = len(history) // lines + (len(history) % 2 != 0)
fig, ax = plt.subplots(lines, cols, figsize=(8 * cols, 10 * lines))
if lines == 1:
ax = np.array([ax]).flatten()
# Custom colormap from red (negative) to green (positive)
colors = ['#fa8072', 'white', '#00a86b']
cmap = LinearSegmentedColormap.from_list('custom', list(zip(np.linspace(0, 1, len(colors)), colors)))
# Plot each week's reward
for i in range(len(history)):
reward = history[i]['reward']
if (len(reward)==0):
continue
title = f'Week {i + 1}'
axis = ax[i // cols, i % cols] if lines > 1 else ax[i]
if schedule is not None:
sorted_indices = np.argsort(map_label_event)
sorted_map_event = np.sort(map_label_event)
sorted_reward = reward[sorted_indices]
im = axis.imshow(sorted_reward, cmap=cmap, aspect='auto', interpolation='nearest')
_, unique_indices = np.unique(sorted_map_event, return_index=True)
axis.set_yticks(np.arange(len(sorted_map_event)))
axis.set_yticklabels(['W' + str(sorted_map_event[x]) if x in unique_indices else None
for x in range(len(sorted_map_event))], fontsize=23)
axis.set_ylabel('Chapters in Week', fontsize=23)
# axis.set_ylabel('', fontsize=16)
else:
im = axis.imshow(reward, cmap=cmap, aspect='auto', interpolation='nearest', vmin=-1, vmax=1)
# axis.set_title(title + 'Reward')
axis.set_xticks(np.arange(len(list(dict_action.values()))), labels=list(dict_action.values()))
axis.set_xticklabels(labels=list(dict_action.values()), rotation = 90, fontsize=23)
axis.set_title(title, fontsize=30)
# # Set the title for each subplot
# axis.set_title(title, fontsize=18)
# Add colorbar for visualizing reward scale
fig.colorbar(im, ax=axis, orientation='vertical', fraction=0.04, pad=0.04)
# fig.subplots_adjust(right=0.8)
# cbar_ax = fig.add_axes([1, 0.2, 0.02, 0.7])
# cbar = fig.colorbar(im, cax=cbar_ax)
# Adding gridlines for better readability
# axis.grid(True, which='both', axis='both', color='black', linestyle='--', linewidth=0.5)
plt.tight_layout(rect=[0, 0.03, 1, 0.95]) # Adjust spacing for the title
if path is not None:
if not os.path.exists(path):
os.makedirs(path)
save_title = main_title.split(' ')
save_title = '-'.join(save_title)
fig.savefig(os.path.join(path, save_title+'reward.jpg'), dpi=500)
fig.savefig(os.path.join(path, save_title+'reward.svg'), dpi=500)
# Optionally, save the plot to a file
# if path is not None:
# plt.savefig(path, dpi=500)
plt.show()
# def plot_all_weeks_reward(history, dict_event, dict_action,
# unique_week=np.arange(10), main_title="", path=None, schedule=None):
# """
# Plot reward for all weeks
# return heatmap of reward
# """
# map_label_event = dict_event.keys()
# if schedule is not None:
# map_label_event = [schedule.iloc[x]['chapter'] for x in dict_event.keys()]
# lines = 2
# cols = len(history)//lines + (len(history)%2!=0)
# fig, ax = plt.subplots(lines, cols, figsize=(6*cols, 10*lines))
# if lines == 1:
# ax = np.array([ax]).flatten()
# colors = ['red', 'white', 'green']
# cmap = LinearSegmentedColormap.from_list('custom', list(zip(np.linspace(0, 1, len(colors)), colors)))
# for i in range(len(history)):
# reward = history[i]['reward']
# if (len(reward)==0):
# continue
# title = f'Week {i + 1}'
# axis = ax[i // cols, i % cols] if lines > 1 else ax[i]
# if schedule is not None:
# sorted_indices = np.argsort(map_label_event)
# sorted_map_event = np.sort(map_label_event)
# sorted_reward = reward[sorted_indices]
# im = axis.imshow(sorted_reward, cmap=cmap, aspect='auto', interpolation='nearest', vmin=-1, vmax=1)
# _, unique_indices = np.unique(sorted_map_event, return_index=True)
# axis.set_yticks(np.arange(len(sorted_map_event)))
# axis.set_yticklabels(['W' + str(sorted_map_event[x]) if x in unique_indices else None
# for x in range(len(sorted_map_event))], fontsize=23)
# else:
# im = axis.imshow(reward, cmap=cmap, aspect='auto', interpolation='nearest', vmin=-1, vmax=1)
# axis.set_title(title + 'Reward')
# axis.set_xticks(np.arange(len(list(dict_action.values()))), labels=list(dict_action.values()))
# axis.set_xticklabels(labels=list(dict_action.values()), rotation = 90, fontsize=23)
# axis.set_title(title, fontsize=30)
# fig.subplots_adjust(right=0.8)
# cbar_ax = fig.add_axes([1, 0.2, 0.02, 0.7])
# cbar = fig.colorbar(im, cax=cbar_ax)
# fig.tight_layout(pad=3.0)
# plt.xlabel("Student's Action", fontsize=30)
# plt.ylabel('Content in Week "{x}"', fontsize=30)
# plt.tight_layout()
# plt.legend()
# if path is not None:
# if not os.path.exists(path):
# os.makedirs(path)
# save_title = main_title.split(' ')
# save_title = '-'.join(save_title)
# fig.savefig(os.path.join(path, save_title+'reward.jpg'), dpi=500)
# plt.show()
# plt.close()
def plot_problem_event_alpha(history, dict_event, dict_action, problem_event, unique_week=np.arange(10)):
cols=5
lines = len(history)//cols + (1 if len(history)%cols != 0 else 0)
cols = min(cols, len(history))
fig, ax = plt.subplots(lines, cols, figsize=(10, 8))
if lines == 1:
ax = np.array([ax]).flatten()
fig.tight_layout(pad=3.0)
for i in range(len(history)):
color = ['blue' if dict_event[i] in problem_event else 'orange' for i in range(len(dict_event))]
alpha = history[i]['alpha']
if len(alpha) == 0:
continue
title = f'Week {unique_week[i] + 1}'
axis = ax[i // cols, i % cols] if lines > 1 else ax[i]
axis.bar(list(dict_event.keys()), alpha[:len(dict_event)], align='center', color=color)
axis.set_title(title)
plt.show()
def plot_problem_event_reward(history, map_problem_id, map_video_id, dict_action):
colors = ['red', 'white', 'green']
_, ax = plt.subplots(1, 2, figsize=(16, 5))
cmap = LinearSegmentedColormap.from_list('custom', list(zip(np.linspace(0, 1, len(colors)), colors)))
reward = history['reward']
print(reward.shape)
im1 = ax[0].imshow(reward[map_problem_id, :], cmap=cmap, aspect='auto', interpolation='nearest', vmin=-1, vmax=1)
im2 = ax[1].imshow(reward[map_video_id, :], cmap=cmap, aspect='auto', interpolation='nearest', vmin=-1, vmax=1)
ax[0].set_title('Problem Reward')
ax[0].set_xticks(np.arange(len(list(dict_action.values()))), labels=list(dict_action.values()))
ax[0].set_xticklabels(labels=list(dict_action.values()), rotation = 90)
ax[1].set_title('Video Reward')
ax[1].set_xticks(np.arange(len(list(dict_action.values()))), labels=list(dict_action.values()))
ax[1].set_xticklabels(labels=list(dict_action.values()), rotation = 90)
plt.tight_layout()
plt.show()
def distribution_skillset(trajectories_each_week, world, columns=['topic']):
fig, ax = plt.subplots(2, 5, figsize=(20, 10))
for i, trajectories in enumerate(trajectories_each_week):
data = []
for trajectory in trajectories:
for state, action, _ in trajectory:
topic = world.get_features(state, action)['topic']
data.extend(topic)
word_counts = Counter(data)
print(word_counts)
unique_words = list(word_counts.keys())
word_counts_values = list(word_counts.values())
ax[i//5, i%5].bar(unique_words, word_counts_values, color='skyblue')
ax[i//5, i%5].set_title(f'Week {i + 1}')
plt.xticks(rotation=90)
plt.grid(axis='y')
plt.show()
def plot_accuracy_synthesize(accs_training, accs_full_synthesize, accs_personalized_syn, weeks):
plt.figure(figsize=(12, 6))
ax = plt.gca()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
sns.lineplot(data=accs_training, x='Week', y='Accuracy', label='Prediction Model')
sns.lineplot(data=accs_full_synthesize, x='Week', y='Accuracy', label='Synthesized Classrooms')
sns.lineplot(data=accs_personalized_syn, x='Week', y='Accuracy', label='Personalized Trajectories')
plt.xlabel('Number of Weeks')
plt.xticks(weeks)
plt.ylabel('Accuracy')
plt.legend()
plt.grid(axis='y')
plt.show()
def plot_a_week_whatif(week_data, week, course):
plt.figure(figsize=(12, 8))
sns.barplot(
x='Chapter',
y='Mean Average Impact',
data=week_data,
errorbar="sd",
legend=False
)
plt.grid(axis='y', linestyle='-', alpha=0.6)
ax = plt.gca()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
plt.xlabel("Topic")
plt.ylabel('Mean Average Effectiveness')
plt.title(f'What-if Classroom in Week {week}')
plt.savefig(f'results/whatif/{course}/whatif-analysis/whatif_results_week_{week}.png')
plt.show()
plt.close()
def plot_heatmap_whatif(whatif_results, course):
heatmap_data = whatif_results.pivot_table(
index='Week',
columns='Chapter',
values='SD Average Impact',
aggfunc='mean'
)
plt.figure(figsize=(15, 8))
sns.heatmap(heatmap_data, annot=False, cmap='Blues', linewidths=.5)
plt.ylabel('Week')
plt.xlabel("Week")
plt.savefig(f'results/whatif/{course}/whatif-analysis/whatif_results_heatmap.png')
plt.show()