Update output rq2 table
Browse files
app.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
# app.py
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
import matplotlib.pyplot as plt
|
@@ -8,20 +8,17 @@ from sklearn.preprocessing import StandardScaler
|
|
8 |
from sklearn.ensemble import RandomForestClassifier
|
9 |
from sklearn.model_selection import train_test_split
|
10 |
from sklearn.metrics import classification_report, roc_auc_score
|
11 |
-
from tabulate import tabulate
|
12 |
import warnings
|
13 |
-
import traceback
|
14 |
import gradio as gr
|
15 |
import os
|
16 |
import git
|
17 |
|
18 |
-
# --- Main Class
|
19 |
warnings.filterwarnings('ignore')
|
20 |
plt.style.use('default')
|
21 |
sns.set_palette("husl")
|
22 |
|
23 |
class EnhancedAIvsRealGazeAnalyzer:
|
24 |
-
# ... (The entire class from before remains unchanged up to run_prediction_model) ...
|
25 |
def __init__(self):
|
26 |
self.questions = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6']
|
27 |
self.correct_answers = {'Pair1': 'B', 'Pair2': 'B', 'Pair3': 'B', 'Pair4': 'B', 'Pair5': 'B', 'Pair6': 'B'}
|
@@ -77,7 +74,6 @@ class EnhancedAIvsRealGazeAnalyzer:
|
|
77 |
return fig, summary
|
78 |
|
79 |
def run_prediction_model(self, test_size, n_estimators):
|
80 |
-
"""Runs the RandomForest model with given parameters for RQ2."""
|
81 |
leaky_features = ['Total_Correct', 'Overall_Accuracy', 'Correct']
|
82 |
features_to_use = [col for col in self.numeric_cols if col not in leaky_features]
|
83 |
features = self.combined_data[features_to_use].copy()
|
@@ -96,9 +92,11 @@ class EnhancedAIvsRealGazeAnalyzer:
|
|
96 |
report = classification_report(y_test, y_pred, target_names=['Incorrect', 'Correct'], output_dict=True)
|
97 |
auc_score = roc_auc_score(y_test, y_pred_proba)
|
98 |
|
99 |
-
# ---
|
|
|
100 |
report_df = pd.DataFrame(report).transpose().round(3)
|
101 |
-
|
|
|
102 |
|
103 |
report_md = f"""
|
104 |
### Model Performance
|
@@ -108,6 +106,7 @@ class EnhancedAIvsRealGazeAnalyzer:
|
|
108 |
**Classification Report:**
|
109 |
{report_table}
|
110 |
"""
|
|
|
111 |
|
112 |
feature_importance = pd.DataFrame({'Feature': features.columns, 'Importance': model.feature_importances_})
|
113 |
feature_importance = feature_importance.sort_values('Importance', ascending=False).head(15)
|
@@ -117,7 +116,7 @@ class EnhancedAIvsRealGazeAnalyzer:
|
|
117 |
plt.tight_layout()
|
118 |
return report_md, fig
|
119 |
|
120 |
-
# --- DATA SETUP
|
121 |
def setup_and_load_data():
|
122 |
repo_url = "https://github.com/RextonRZ/GenAIEyeTrackingCleanedDataset"
|
123 |
repo_dir = "GenAIEyeTrackingCleanedDataset"
|
@@ -152,47 +151,31 @@ description = """
|
|
152 |
Explore the eye-tracking dataset by interacting with the controls below. The data is automatically loaded from the public GitHub repository.
|
153 |
"""
|
154 |
|
155 |
-
# --- CHANGE 2: Restructure the layout with columns ---
|
156 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
157 |
gr.Markdown(description)
|
158 |
-
|
159 |
with gr.Tabs():
|
160 |
with gr.TabItem("RQ1: Viewing Time vs. Correctness"):
|
161 |
-
gr.Markdown("### Does viewing time differ based on whether a participant's answer was correct?")
|
162 |
with gr.Row():
|
163 |
with gr.Column(scale=1):
|
164 |
-
rq1_metric_dropdown = gr.Dropdown(
|
165 |
-
choices=analyzer.time_metrics,
|
166 |
-
label="Select a Time-Based Metric to Analyze",
|
167 |
-
value=analyzer.time_metrics[0] if analyzer.time_metrics else None
|
168 |
-
)
|
169 |
rq1_summary_output = gr.Markdown(label="Statistical Summary")
|
170 |
with gr.Column(scale=2):
|
171 |
rq1_plot_output = gr.Plot(label="Metric Comparison")
|
172 |
-
|
173 |
with gr.TabItem("RQ2: Predicting Correctness from Gaze"):
|
174 |
-
gr.Markdown("### Can we build a model to predict answer correctness from gaze patterns?")
|
175 |
with gr.Row():
|
176 |
-
# --- LEFT COLUMN FOR CONTROLS ---
|
177 |
with gr.Column(scale=1):
|
178 |
gr.Markdown("#### Tune Model Hyperparameters")
|
179 |
-
rq2_test_size_slider = gr.Slider(
|
180 |
-
|
181 |
-
)
|
182 |
-
rq2_estimators_slider = gr.Slider(
|
183 |
-
minimum=10, maximum=200, step=10, value=100, label="Number of Trees (n_estimators)"
|
184 |
-
)
|
185 |
-
# --- RIGHT COLUMN FOR OUTPUTS ---
|
186 |
with gr.Column(scale=2):
|
187 |
-
|
|
|
188 |
rq2_plot_output = gr.Plot(label="Feature Importance")
|
189 |
|
190 |
-
# Wire up the interactive components
|
191 |
rq1_metric_dropdown.change(fn=update_rq1_visuals, inputs=[rq1_metric_dropdown], outputs=[rq1_plot_output, rq1_summary_output])
|
192 |
rq2_test_size_slider.release(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
193 |
rq2_estimators_slider.release(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
194 |
|
195 |
-
# Load initial state
|
196 |
demo.load(fn=update_rq1_visuals, inputs=[rq1_metric_dropdown], outputs=[rq1_plot_output, rq1_summary_output])
|
197 |
demo.load(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
198 |
|
|
|
1 |
+
# app.py
|
2 |
import pandas as pd
|
3 |
import numpy as np
|
4 |
import matplotlib.pyplot as plt
|
|
|
8 |
from sklearn.ensemble import RandomForestClassifier
|
9 |
from sklearn.model_selection import train_test_split
|
10 |
from sklearn.metrics import classification_report, roc_auc_score
|
|
|
11 |
import warnings
|
|
|
12 |
import gradio as gr
|
13 |
import os
|
14 |
import git
|
15 |
|
16 |
+
# --- Main Class ---
|
17 |
warnings.filterwarnings('ignore')
|
18 |
plt.style.use('default')
|
19 |
sns.set_palette("husl")
|
20 |
|
21 |
class EnhancedAIvsRealGazeAnalyzer:
|
|
|
22 |
def __init__(self):
|
23 |
self.questions = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6']
|
24 |
self.correct_answers = {'Pair1': 'B', 'Pair2': 'B', 'Pair3': 'B', 'Pair4': 'B', 'Pair5': 'B', 'Pair6': 'B'}
|
|
|
74 |
return fig, summary
|
75 |
|
76 |
def run_prediction_model(self, test_size, n_estimators):
|
|
|
77 |
leaky_features = ['Total_Correct', 'Overall_Accuracy', 'Correct']
|
78 |
features_to_use = [col for col in self.numeric_cols if col not in leaky_features]
|
79 |
features = self.combined_data[features_to_use].copy()
|
|
|
92 |
report = classification_report(y_test, y_pred, target_names=['Incorrect', 'Correct'], output_dict=True)
|
93 |
auc_score = roc_auc_score(y_test, y_pred_proba)
|
94 |
|
95 |
+
# --- THIS IS THE KEY FIX ---
|
96 |
+
# 1. Convert the report dictionary to a DataFrame
|
97 |
report_df = pd.DataFrame(report).transpose().round(3)
|
98 |
+
# 2. Use the built-in .to_markdown() method for perfect formatting
|
99 |
+
report_table = report_df.to_markdown()
|
100 |
|
101 |
report_md = f"""
|
102 |
### Model Performance
|
|
|
106 |
**Classification Report:**
|
107 |
{report_table}
|
108 |
"""
|
109 |
+
# --- END OF FIX ---
|
110 |
|
111 |
feature_importance = pd.DataFrame({'Feature': features.columns, 'Importance': model.feature_importances_})
|
112 |
feature_importance = feature_importance.sort_values('Importance', ascending=False).head(15)
|
|
|
116 |
plt.tight_layout()
|
117 |
return report_md, fig
|
118 |
|
119 |
+
# --- DATA SETUP ---
|
120 |
def setup_and_load_data():
|
121 |
repo_url = "https://github.com/RextonRZ/GenAIEyeTrackingCleanedDataset"
|
122 |
repo_dir = "GenAIEyeTrackingCleanedDataset"
|
|
|
151 |
Explore the eye-tracking dataset by interacting with the controls below. The data is automatically loaded from the public GitHub repository.
|
152 |
"""
|
153 |
|
|
|
154 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
155 |
gr.Markdown(description)
|
|
|
156 |
with gr.Tabs():
|
157 |
with gr.TabItem("RQ1: Viewing Time vs. Correctness"):
|
|
|
158 |
with gr.Row():
|
159 |
with gr.Column(scale=1):
|
160 |
+
rq1_metric_dropdown = gr.Dropdown(choices=analyzer.time_metrics, label="Select a Time-Based Metric", value=analyzer.time_metrics[0] if analyzer.time_metrics else None)
|
|
|
|
|
|
|
|
|
161 |
rq1_summary_output = gr.Markdown(label="Statistical Summary")
|
162 |
with gr.Column(scale=2):
|
163 |
rq1_plot_output = gr.Plot(label="Metric Comparison")
|
|
|
164 |
with gr.TabItem("RQ2: Predicting Correctness from Gaze"):
|
|
|
165 |
with gr.Row():
|
|
|
166 |
with gr.Column(scale=1):
|
167 |
gr.Markdown("#### Tune Model Hyperparameters")
|
168 |
+
rq2_test_size_slider = gr.Slider(minimum=0.1, maximum=0.5, step=0.05, value=0.3, label="Test Set Size")
|
169 |
+
rq2_estimators_slider = gr.Slider(minimum=10, maximum=200, step=10, value=100, label="Number of Trees (n_estimators)")
|
|
|
|
|
|
|
|
|
|
|
170 |
with gr.Column(scale=2):
|
171 |
+
# Ensure this is gr.Markdown()
|
172 |
+
rq2_report_output = gr.Markdown(label="Model Performance Report")
|
173 |
rq2_plot_output = gr.Plot(label="Feature Importance")
|
174 |
|
|
|
175 |
rq1_metric_dropdown.change(fn=update_rq1_visuals, inputs=[rq1_metric_dropdown], outputs=[rq1_plot_output, rq1_summary_output])
|
176 |
rq2_test_size_slider.release(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
177 |
rq2_estimators_slider.release(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
178 |
|
|
|
179 |
demo.load(fn=update_rq1_visuals, inputs=[rq1_metric_dropdown], outputs=[rq1_plot_output, rq1_summary_output])
|
180 |
demo.load(fn=update_rq2_model, inputs=[rq2_test_size_slider, rq2_estimators_slider], outputs=[rq2_report_output, rq2_plot_output])
|
181 |
|