Spaces:
Runtime error
Runtime error
from flask import Flask, render_template_string | |
import warnings | |
warnings.filterwarnings('ignore') | |
import pandas as pd | |
import numpy as np | |
import plotly.express as px | |
import matplotlib.pyplot as plt | |
import matplotlib | |
matplotlib.use('Agg') | |
import seaborn as sns | |
sns.set_style('whitegrid') | |
import panel as pn | |
from panel.interact import interact | |
pn.extension('plotly') # Interactive tables | |
import hvplot.pandas # Interactive dataframes | |
import holoviews as hv | |
from bokeh.events import Event | |
hv.extension('bokeh') | |
import os | |
os.environ['BOKEH_ALLOW_WS_ORIGIN'] = 'localhost:5006' | |
from bokeh.embed import server_document | |
import subprocess | |
df = pd.read_csv("data\StudentsPerformance.csv") | |
numeric_features = ['math score', 'reading score', 'writing score'] | |
categoric_features = ['gender', 'race/ethnicity', 'parental level of education', 'lunch', 'test preparation course'] | |
df['pass'] = df.apply(lambda row: 1 if row['math score'] >= 60 and row['reading score'] >= 60 and row['writing score'] >= 60 else 0, axis=1) | |
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet, LogisticRegression | |
from sklearn.neighbors import KNeighborsClassifier | |
from sklearn.ensemble import RandomForestClassifier | |
from sklearn.svm import SVC | |
import dashboard | |
from dashboard.plots import table_plotly | |
from dashboard.plots import pie_quali | |
from dashboard.plots import histogram_quali | |
from dashboard.plots import boxplot_quali_quanti | |
from dashboard.plots import scatter_quanti_quanti | |
from dashboard.plots import plotting_target_feature | |
from dashboard.plots import corr_heatmap | |
from dashboard.plots import qqplot | |
from dashboard.plots import hist_residual | |
from dashboard.plots import qqplot_residual | |
from dashboard.plots import residual_fitted | |
from dashboard.plots import residual_leverage | |
from dashboard.plots import bivar_quanti_plot | |
from dashboard.plots import cross_heatmap | |
from dashboard.plots import ols_resid_plot | |
from dashboard.plots import confusion_matrix_heatmap | |
from dashboard.plots import plot_roc | |
from dashboard.tables import describe_quali_quanti | |
from dashboard.tables import filtered_dataframe | |
from dashboard.tables import evaluate_regression_model | |
from dashboard.tables import cross_tab | |
from dashboard.tables import chi2_tab | |
from dashboard.tables import report_to_df | |
from dashboard.model import model_history | |
from dashboard.model import model_cl_history | |
pn.config.sizing_mode = "stretch_width" | |
reg_list = [ | |
LinearRegression, | |
Ridge, | |
Lasso, | |
ElasticNet | |
] | |
cl_list= [ | |
LogisticRegression, | |
RandomForestClassifier, | |
KNeighborsClassifier, | |
SVC | |
] | |
##### Create widgets | |
### Exploration widgets (Page 1) | |
# Dataset | |
checked_columns = ['lunch', 'race/ethnicity','test_preparation_course','math score','reading score','writing score','target_name'] | |
checkboxes = {col: pn.widgets.Checkbox(name=col, value=True) if col in checked_columns else pn.widgets.Checkbox(name=col, value=False) for col in df.columns} | |
# Histogram | |
count = pn.widgets.Select(name='feature',options=[col for col in df.columns], value='parental level of education') | |
# Scatter plot | |
abscisse_scatter = pn.widgets.Select(name='x', options=numeric_features, value='reading score') | |
ordonnee_scatter = pn.widgets.Select(name='y', options=numeric_features, value='writing score') | |
dashboard_fit_line_checkbox = pn.widgets.Checkbox(name='fit line') | |
# Box plot | |
quanti = pn.widgets.Select(name='numeric feature', options=numeric_features) | |
quali = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education') | |
# Target Plot | |
quali_target = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education') | |
### Modeling Widget (Page 2) | |
# Regression | |
target_widget = pn.widgets.Select(name='target', options=numeric_features, value='writing score') | |
model_name_widget = pn.widgets.Select(name='model', options=reg_list, value=LinearRegression) | |
# Classification | |
model_name_cl_widget = pn.widgets.Select(name='classification model', options=cl_list, value=LogisticRegression) | |
color_confusion = pn.widgets.Select(name='Matrix color', options=px.colors.named_colorscales(), value='bupu') | |
### Analysis Widget (Page 3) | |
# Quanti/Quanti | |
color1 = pn.widgets.Select(name='color', options=px.colors.named_colorscales(), value='magma') | |
quanti1_corr = pn.widgets.Select(name='x',options=numeric_features, value = 'reading score') | |
quanti2_corr = pn.widgets.Select(name='y',options=numeric_features, value = 'writing score') | |
# Quali/Quali | |
color2 = pn.widgets.Select(name='color', options=px.colors.named_colorscales(), value='redor') | |
quali1_cross = pn.widgets.Select(name='quali 1',options=categoric_features, value = 'parental level of education') | |
quali2_cross = pn.widgets.Select(name='quali 2',options=categoric_features, value = 'lunch') | |
# Q-Q Plot | |
quanti_qq = pn.widgets.Select(name='numeric feature', options=numeric_features) | |
quali_qq = pn.widgets.Select(name='categorical feature', options=categoric_features, value='parental level of education') | |
modality_qq = pn.widgets.Select(name='modality', options=df[quali_qq.params.args[0].value].unique().tolist()) | |
def update_modality_options(event): | |
selected_quali = quali_qq.value | |
selected_modality = modality_qq.value | |
modality_qq.options = df[selected_quali].unique().tolist() | |
if selected_modality not in modality_qq.options: | |
modality_qq.value = modality_qq.options[0] | |
else: | |
modality_qq.value = selected_modality | |
quali_qq.param.watch(update_modality_options, 'value') | |
##### Define reactive elements | |
### Reactive elements for Exploration (Page 1) | |
dataset = pn.bind(filtered_dataframe, df=df, **checkboxes) | |
histogram = pn.bind(histogram_quali,quali=count,df=df) | |
scatter_plot = pn.bind(scatter_quanti_quanti, x=abscisse_scatter, y=ordonnee_scatter, df=df, checkbox=dashboard_fit_line_checkbox) | |
box_plot = pn.bind(boxplot_quali_quanti, quanti=quanti, quali=quali, df=df) | |
describe_table = pn.bind(describe_quali_quanti, quali=quali, quanti=quanti, df=df) | |
target_plot = pn.bind(plotting_target_feature, quali=quali_target,df=df) | |
### Reactive elements for Modeling (Page 2) | |
# Regression | |
def update_reg_history(target, model): | |
return model_history(df=df, target=target, model=model) | |
reg_history = pn.bind(update_reg_history, target=target_widget, model=model_name_widget) | |
evaluate_reg_table = pn.bind(evaluate_regression_model,history=reg_history) | |
residual_fitted_plot = pn.bind(residual_fitted, history=reg_history) | |
qqplot_residual_plot = pn.bind(qqplot_residual, history=reg_history) | |
scale_location_plot = pn.bind(residual_fitted, history=reg_history, root=True) | |
residual_leverage_plot = pn.bind(residual_leverage, history=reg_history) | |
# Classification | |
def update_cl_history(model_cl): | |
return model_cl_history(df=df, model_cl=model_cl) | |
cl_classification = pn.bind(update_cl_history, model_cl=model_name_cl_widget) | |
evaluate_cl_table = pn.bind(report_to_df,classification=cl_classification) | |
confusion_plot = pn.bind(confusion_matrix_heatmap, classification=cl_classification,color=color_confusion) | |
roc = pn.bind(plot_roc, classification=cl_classification) | |
### Reactive elements for Analysis (Page 3) | |
corr_plot = pn.bind(corr_heatmap, df=df, quanti1=quanti1_corr,quanti2=quanti2_corr, color=color1) | |
joint_plot = pn.bind(bivar_quanti_plot, df=df, quanti1=quanti1_corr, quanti2=quanti2_corr) | |
cross_table = pn.bind(cross_tab, df=df, quali1=quali1_cross, quali2=quali2_cross) | |
chi2_table = pn.bind(chi2_tab, df=df, quali1=quali1_cross, quali2=quali2_cross) | |
cross_heatmap_plot = pn.bind(cross_heatmap, df=df, quali1=quali1_cross, quali2=quali2_cross, color=color2) | |
box_plot2 = pn.bind(boxplot_quali_quanti, quanti=quanti_qq, quali=quali_qq, df=df) | |
qq_plot = pn.bind(qqplot, quali=quali_qq, quanti=quanti_qq, modality=modality_qq, df=df) | |
ols_plot = pn.bind(ols_resid_plot, df=df, quanti=quanti_qq, quali=quali_qq) | |
##### Define Sidebar | |
### Exploration Sidebar (Page 1) | |
# Cards | |
data_card = pn.Card(pn.Column(*checkboxes.values()), title='Data') | |
histogram_card = pn.Card(pn.Column(count), title='Histogram') | |
scatter_card = pn.Card(pn.Column(dashboard_fit_line_checkbox, abscisse_scatter, ordonnee_scatter), title='Scatter Plot') | |
box_card = pn.Card(pn.Column(quanti, quali), title='Box Plot') | |
target_card = pn.Card(pn.Column(quali_target), title='Target Plot') | |
# Sidebar | |
exploration_sidebar = pn.Column('# Parameters\n This section changes parameters for exploration plots', | |
data_card, | |
histogram_card, | |
scatter_card, | |
box_card, | |
target_card, | |
sizing_mode='stretch_width', | |
) | |
### Modeling Sidebar (Page 2) | |
# Cards | |
regression_card = pn.Card(pn.Column(model_name_widget,target_widget), title='Regression',sizing_mode = "stretch_width") | |
classification_card = pn.Card(pn.Column(model_name_cl_widget, color_confusion), title='Classification',sizing_mode = "stretch_width") | |
# Sidebar | |
modeling_sidebar = pn.Column('# Parameters\n This section changes parameters for modeling plots', | |
regression_card, | |
classification_card, | |
sizing_mode='stretch_width' | |
) | |
### Analysis Sidebar (Page 3) | |
# Cards | |
quanti_quanti_card = pn.Card(pn.Column(color1,quanti1_corr,quanti2_corr), title='Quantitative vs Quantitative') | |
quali_quali_card = pn.Card(pn.Column(color2,quali1_cross, quali2_cross), title='Qualitative vs Qualitative') | |
quali_quanti_card = pn.Card(pn.Column(quanti_qq,pn.Column(quali_qq, modality_qq)), title='Qualitative vs Quantitative') | |
# Sidebar | |
analysis_sidebar = pn.Column('# Parameters\n This section changes parameters for further analysis plots', | |
quanti_quanti_card, | |
quali_quali_card, | |
quali_quanti_card, | |
sizing_mode='stretch_width' | |
) | |
##### Define Main | |
### Main Exploration (Page 1) | |
# Cards | |
description = "This dataset contains information about the performance of students in various subjects. The data includes their scores in math, reading, and writing, as well as their gender, race/ethnicity, parental education, and whether they qualify for free/reduced lunch." | |
description_card = pn.Card(description, title='Description') | |
dataset_card = pn.Card(pn.Row(pn.Column('# Data ', description), | |
pn.Column(dataset)), | |
title='Description') | |
boxplot_card = pn.Row(pn.Card(describe_table, title='Describe Table'), | |
pn.Card(box_plot, title='Box Plot')) | |
scatter_hist_card = pn.Row(pn.Card(histogram, title='Histogram'), | |
pn.Card(scatter_plot, title='Scatter Plot')) | |
target_card = pn.Card(target_plot, title='Target Plot') | |
# Content | |
exploration_main_content = pn.Column( | |
pn.Row(dataset_card), | |
pn.Row(scatter_hist_card), | |
pn.Row(boxplot_card), | |
pn.Row(target_card), | |
sizing_mode='stretch_width') | |
### Main Modeling (Page 2) | |
# Cards | |
evaluate_table_card = pn.Card(evaluate_reg_table, title="Evaluation") | |
residual_fitted_card = pn.Card(residual_fitted_plot ,title="Residual Plot") | |
qqplot_residual_card = pn.Card(qqplot_residual_plot,title="Normal Q-Q") | |
scale_location_card = pn.Card(scale_location_plot, title="Scale Location") | |
residual_leverage_card = pn.Card(residual_leverage_plot, title="Residuals vs Leverage") | |
# Regroup cards | |
regression_card = pn.Card(pn.Row(evaluate_table_card), | |
pn.Row(residual_fitted_card,qqplot_residual_card), | |
pn.Row(scale_location_card,residual_leverage_card), | |
title = 'Regression') | |
## Classification | |
evaluate_cl_card = pn.Card(evaluate_cl_table, title="Evaluation Table") | |
confusion_card = pn.Card(confusion_plot, title="Confusion Matrix") | |
roc_card = pn.Card(roc, title='ROC') | |
classification_card = pn.Card(pn.Row(evaluate_cl_card), | |
pn.Row(confusion_card,roc_card), | |
title='Classification') | |
# Content | |
modeling_main_content = pn.Column(pn.Row(regression_card), | |
pn.Row(classification_card), | |
sizing_mode='stretch_width') | |
### Main Analysis(Page 3) | |
# Cards | |
corr_card = pn.Card(corr_plot, title='Person Correlation Matrix') | |
joint_card = pn.Card(joint_plot, title='Bivariate Plot') | |
cross_card = pn.Card(cross_table, title='Contingency Table') | |
chi2_card = pn.Card(chi2_table, title='Chi2 Test') | |
cross_heatmap_card = pn.Card(cross_heatmap_plot, title='Contingency Heatmap') | |
boxplot_card = pn.Card(box_plot2, title='Box Plot') | |
qq_card = pn.Card(qq_plot, title='Q-Q Plot') | |
ols_card = pn.Card(ols_plot, title='OLS Residuals') | |
quanti_quanti_card = pn.Card(pn.Row(corr_card,joint_card), | |
title=f'Statistic Dependency {quanti1_corr.params.args[0].value} vs {quanti2_corr.params.args[0].value} (quantitative/quantitative)') | |
quali_quali_card = pn.Card(pn.Row(pn.Column(cross_card,chi2_card), | |
cross_heatmap_card), | |
title=f'Statistic Dependency {quali1_cross.params.args[0].value} vs {quali2_cross.params.args[0].value} (qualitative/qualitative)') | |
quali_quanti_card = pn.Card(pn.Row(boxplot_card), | |
pn.Row(ols_card,qq_card), | |
title=f'Statistic Dependency {quali_qq.params.args[0].value} vs {quanti_qq.params.args[0].value} (qualitative/quantitative)') | |
# Content | |
analysis_main_content = pn.Column(pn.Row(quanti_quanti_card), | |
pn.Row(quali_quali_card), | |
pn.Row(quali_quanti_card), | |
sizing_mode='stretch_width') | |
##### Create Callback to change sidebar content | |
main_tabs = pn.Tabs(('Exploration', exploration_main_content), | |
('Modeling', modeling_main_content), | |
('Further Analysis', analysis_main_content)) | |
def on_tab_change(event): | |
if event.new == 0: | |
exploration_sidebar.visible = True | |
modeling_sidebar.visible = False | |
analysis_sidebar.visible = False | |
elif event.new == 1: | |
exploration_sidebar.visible = False | |
modeling_sidebar.visible = True | |
analysis_sidebar.visible = False | |
else: | |
exploration_sidebar.visible = False | |
modeling_sidebar.visible = False | |
analysis_sidebar.visible = True | |
main_tabs.param.watch(on_tab_change, 'active') | |
##### Layout | |
template = pn.template.VanillaTemplate( | |
# title | |
title = "Student Performance in Exams", | |
# sidebar | |
sidebar = pn.Column(exploration_sidebar, modeling_sidebar, analysis_sidebar, sizing_mode='stretch_width'), | |
# main | |
main = main_tabs | |
) | |
#template.header.append(dark_mode_toggle) | |
##### Show Dashboard | |
template.servable() | |