Spaces:
Sleeping
Sleeping
Ryan
commited on
Commit
·
a800293
1
Parent(s):
14bac19
update
Browse files- .DS_Store +0 -0
- _archive/app copy.py +0 -355
- _archive/app.py +0 -63
- app.bak.py +0 -7
- app.py +155 -63
- ui/analysis_screen.py +72 -39
- visualization/bow_visualizer.py +9 -0
.DS_Store
CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
|
|
_archive/app copy.py
DELETED
@@ -1,355 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
from ui.dataset_input import create_dataset_input, load_example_dataset
|
3 |
-
from ui.analysis_screen import create_analysis_screen, process_analysis_request
|
4 |
-
from visualization.bow_visualizer import process_and_visualize_analysis
|
5 |
-
import nltk
|
6 |
-
import os
|
7 |
-
import json
|
8 |
-
|
9 |
-
# Download necessary NLTK resources function remains unchanged
|
10 |
-
def download_nltk_resources():
|
11 |
-
"""Download required NLTK resources if not already downloaded"""
|
12 |
-
try:
|
13 |
-
# Create nltk_data directory in the user's home directory if it doesn't exist
|
14 |
-
nltk_data_path = os.path.expanduser("~/nltk_data")
|
15 |
-
os.makedirs(nltk_data_path, exist_ok=True)
|
16 |
-
|
17 |
-
# Add this path to NLTK's data path
|
18 |
-
nltk.data.path.append(nltk_data_path)
|
19 |
-
|
20 |
-
# Download required resources
|
21 |
-
resources = ['punkt', 'wordnet', 'stopwords', 'punkt_tab']
|
22 |
-
for resource in resources:
|
23 |
-
try:
|
24 |
-
# Different resources can be in different directories in NLTK
|
25 |
-
locations = [
|
26 |
-
f'tokenizers/{resource}',
|
27 |
-
f'corpora/{resource}',
|
28 |
-
f'taggers/{resource}',
|
29 |
-
f'{resource}'
|
30 |
-
]
|
31 |
-
|
32 |
-
found = False
|
33 |
-
for location in locations:
|
34 |
-
try:
|
35 |
-
nltk.data.find(location)
|
36 |
-
print(f"Resource {resource} already downloaded")
|
37 |
-
found = True
|
38 |
-
break
|
39 |
-
except LookupError:
|
40 |
-
continue
|
41 |
-
|
42 |
-
if not found:
|
43 |
-
print(f"Downloading {resource}...")
|
44 |
-
nltk.download(resource, quiet=True)
|
45 |
-
except Exception as e:
|
46 |
-
print(f"Error with resource {resource}: {e}")
|
47 |
-
|
48 |
-
print("NLTK resources check completed")
|
49 |
-
except Exception as e:
|
50 |
-
print(f"Error downloading NLTK resources: {e}")
|
51 |
-
|
52 |
-
def create_app():
|
53 |
-
"""
|
54 |
-
Create a streamlined Gradio app for dataset input and Bag of Words analysis.
|
55 |
-
|
56 |
-
Returns:
|
57 |
-
gr.Blocks: The Gradio application
|
58 |
-
"""
|
59 |
-
with gr.Blocks(title="LLM Response Comparator") as app:
|
60 |
-
# Application state to share data between tabs
|
61 |
-
dataset_state = gr.State({})
|
62 |
-
analysis_results_state = gr.State({})
|
63 |
-
|
64 |
-
# Dataset Input Tab
|
65 |
-
with gr.Tab("Dataset Input"):
|
66 |
-
dataset_inputs, example_dropdown, load_example_btn, create_btn, prompt, response1, model1, response2, model2 = create_dataset_input()
|
67 |
-
|
68 |
-
# Add status indicator to show when dataset is created
|
69 |
-
dataset_status = gr.Markdown("*No dataset loaded*")
|
70 |
-
|
71 |
-
# Load example dataset
|
72 |
-
load_example_btn.click(
|
73 |
-
fn=load_example_dataset,
|
74 |
-
inputs=[example_dropdown],
|
75 |
-
outputs=[prompt, response1, model1, response2, model2] # Update all field values
|
76 |
-
)
|
77 |
-
|
78 |
-
# Save dataset to state and update status
|
79 |
-
def create_dataset(p, r1, m1, r2, m2):
|
80 |
-
if not p or not r1 or not r2:
|
81 |
-
return {}, "❌ **Error:** Please fill in at least the prompt and both responses"
|
82 |
-
|
83 |
-
dataset = {
|
84 |
-
"entries": [
|
85 |
-
{"prompt": p, "response": r1, "model": m1 or "Model 1"},
|
86 |
-
{"prompt": p, "response": r2, "model": m2 or "Model 2"}
|
87 |
-
]
|
88 |
-
}
|
89 |
-
return dataset, "✅ **Dataset created successfully!** You can now go to the Analysis tab"
|
90 |
-
|
91 |
-
create_btn.click(
|
92 |
-
fn=create_dataset,
|
93 |
-
inputs=[prompt, response1, model1, response2, model2],
|
94 |
-
outputs=[dataset_state, dataset_status]
|
95 |
-
)
|
96 |
-
|
97 |
-
# Analysis Tab
|
98 |
-
with gr.Tab("Analysis"):
|
99 |
-
# Use create_analysis_screen to get UI components including visualization container
|
100 |
-
analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider = create_analysis_screen()
|
101 |
-
|
102 |
-
# Pre-create visualization components (initially hidden)
|
103 |
-
visualization_area_visible = gr.Checkbox(value=False, visible=False, label="Visualization Visible")
|
104 |
-
analysis_title = gr.Markdown("## Analysis Results", visible=False)
|
105 |
-
prompt_title = gr.Markdown(visible=False)
|
106 |
-
models_compared = gr.Markdown(visible=False)
|
107 |
-
|
108 |
-
# Container for model 1 words
|
109 |
-
model1_title = gr.Markdown(visible=False)
|
110 |
-
model1_words = gr.Markdown(visible=False)
|
111 |
-
|
112 |
-
# Container for model 2 words
|
113 |
-
model2_title = gr.Markdown(visible=False)
|
114 |
-
model2_words = gr.Markdown(visible=False)
|
115 |
-
|
116 |
-
# Similarity metrics
|
117 |
-
similarity_metrics_title = gr.Markdown("### Similarity Metrics", visible=False)
|
118 |
-
similarity_metrics = gr.Markdown(visible=False)
|
119 |
-
|
120 |
-
# Status or error message area
|
121 |
-
status_message_visible = gr.Checkbox(value=False, visible=False, label="Status Message Visible")
|
122 |
-
status_message = gr.Markdown(visible=False)
|
123 |
-
|
124 |
-
# Define a helper function to extract parameter values and run the analysis
|
125 |
-
def run_analysis(dataset, selected_analyses, bow_top, ngram_n, ngram_top):
|
126 |
-
try:
|
127 |
-
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
128 |
-
return (
|
129 |
-
{}, # analysis_results_state
|
130 |
-
False, # analysis_output visibility
|
131 |
-
False, # visualization_area_visible
|
132 |
-
gr.update(visible=False), # analysis_title
|
133 |
-
gr.update(visible=False), # prompt_title
|
134 |
-
gr.update(visible=False), # models_compared
|
135 |
-
gr.update(visible=False), # model1_title
|
136 |
-
gr.update(visible=False), # model1_words
|
137 |
-
gr.update(visible=False), # model2_title
|
138 |
-
gr.update(visible=False), # model2_words
|
139 |
-
gr.update(visible=False), # similarity_metrics_title
|
140 |
-
gr.update(visible=False), # similarity_metrics
|
141 |
-
True, # status_message_visible
|
142 |
-
gr.update(visible=True, value="❌ **Error:** No dataset loaded. Please create or load a dataset first.") # status_message
|
143 |
-
)
|
144 |
-
|
145 |
-
parameters = {
|
146 |
-
"bow_top": bow_top,
|
147 |
-
"ngram_n": ngram_n,
|
148 |
-
"ngram_top": ngram_top
|
149 |
-
}
|
150 |
-
print("Running analysis with parameters:", parameters)
|
151 |
-
|
152 |
-
# Process the analysis request
|
153 |
-
analysis_results, _ = process_analysis_request(dataset, selected_analyses, parameters)
|
154 |
-
|
155 |
-
# If there's an error or no results
|
156 |
-
if not analysis_results or "analyses" not in analysis_results or not analysis_results["analyses"]:
|
157 |
-
return (
|
158 |
-
analysis_results,
|
159 |
-
False,
|
160 |
-
False,
|
161 |
-
gr.update(visible=False),
|
162 |
-
gr.update(visible=False),
|
163 |
-
gr.update(visible=False),
|
164 |
-
gr.update(visible=False),
|
165 |
-
gr.update(visible=False),
|
166 |
-
gr.update(visible=False),
|
167 |
-
gr.update(visible=False),
|
168 |
-
gr.update(visible=False),
|
169 |
-
gr.update(visible=False),
|
170 |
-
True,
|
171 |
-
gr.update(visible=True, value="❌ **No results found.** Try different analysis options.")
|
172 |
-
)
|
173 |
-
|
174 |
-
# Extract information to display in components
|
175 |
-
prompt = list(analysis_results["analyses"].keys())[0]
|
176 |
-
analyses = analysis_results["analyses"][prompt]
|
177 |
-
|
178 |
-
if "bag_of_words" not in analyses:
|
179 |
-
return (
|
180 |
-
analysis_results,
|
181 |
-
False,
|
182 |
-
False,
|
183 |
-
gr.update(visible=False),
|
184 |
-
gr.update(visible=False),
|
185 |
-
gr.update(visible=False),
|
186 |
-
gr.update(visible=False),
|
187 |
-
gr.update(visible=False),
|
188 |
-
gr.update(visible=False),
|
189 |
-
gr.update(visible=False),
|
190 |
-
gr.update(visible=False),
|
191 |
-
gr.update(visible=False),
|
192 |
-
True,
|
193 |
-
gr.update(visible=True, value="❌ **No Bag of Words analysis found.** Make sure to select it in the options.")
|
194 |
-
)
|
195 |
-
|
196 |
-
bow_results = analyses["bag_of_words"]
|
197 |
-
models = bow_results.get("models", [])
|
198 |
-
|
199 |
-
if len(models) < 2:
|
200 |
-
return (
|
201 |
-
analysis_results,
|
202 |
-
False,
|
203 |
-
False,
|
204 |
-
gr.update(visible=False),
|
205 |
-
gr.update(visible=False),
|
206 |
-
gr.update(visible=False),
|
207 |
-
gr.update(visible=False),
|
208 |
-
gr.update(visible=False),
|
209 |
-
gr.update(visible=False),
|
210 |
-
gr.update(visible=False),
|
211 |
-
gr.update(visible=False),
|
212 |
-
gr.update(visible=False),
|
213 |
-
True,
|
214 |
-
gr.update(visible=True, value="❌ **Not enough models to compare.** Please ensure you have two model responses.")
|
215 |
-
)
|
216 |
-
|
217 |
-
# Extract and format information for display
|
218 |
-
model1_name = models[0]
|
219 |
-
model2_name = models[1]
|
220 |
-
|
221 |
-
# Format important words for each model
|
222 |
-
important_words = bow_results.get("important_words", {})
|
223 |
-
model1_words_text = "No important words found"
|
224 |
-
model2_words_text = "No important words found"
|
225 |
-
|
226 |
-
if model1_name in important_words:
|
227 |
-
word_list = [f"**{item['word']}** ({item['count']})" for item in important_words[model1_name][:10]]
|
228 |
-
model1_words_text = ", ".join(word_list)
|
229 |
-
|
230 |
-
if model2_name in important_words:
|
231 |
-
word_list = [f"**{item['word']}** ({item['count']})" for item in important_words[model2_name][:10]]
|
232 |
-
model2_words_text = ", ".join(word_list)
|
233 |
-
|
234 |
-
# Format similarity metrics
|
235 |
-
similarity_text = "No similarity metrics found"
|
236 |
-
comparisons = bow_results.get("comparisons", {})
|
237 |
-
comparison_key = f"{model1_name} vs {model2_name}"
|
238 |
-
|
239 |
-
if comparison_key in comparisons:
|
240 |
-
metrics = comparisons[comparison_key]
|
241 |
-
cosine = metrics.get("cosine_similarity", 0)
|
242 |
-
jaccard = metrics.get("jaccard_similarity", 0)
|
243 |
-
semantic = metrics.get("semantic_similarity", 0) # Add semantic similarity
|
244 |
-
common_words = metrics.get("common_word_count", 0)
|
245 |
-
|
246 |
-
similarity_text = f"""
|
247 |
-
- **Cosine Similarity**: {cosine:.2f} (higher means more similar word frequency patterns)
|
248 |
-
- **Jaccard Similarity**: {jaccard:.2f} (higher means more word overlap)
|
249 |
-
- **Semantic Similarity**: {semantic:.2f} (higher means more similar meaning)
|
250 |
-
- **Common Words**: {common_words} words appear in both responses
|
251 |
-
"""
|
252 |
-
|
253 |
-
# Return all updated component values
|
254 |
-
return (
|
255 |
-
analysis_results, # analysis_results_state
|
256 |
-
False, # analysis_output visibility
|
257 |
-
True, # visualization_area_visible
|
258 |
-
gr.update(visible=True), # analysis_title
|
259 |
-
gr.update(visible=True, value=f"## Analysis of Prompt: \"{prompt[:100]}...\""), # prompt_title
|
260 |
-
gr.update(visible=True, value=f"### Comparing responses from {model1_name} and {model2_name}"), # models_compared
|
261 |
-
gr.update(visible=True, value=f"#### Top Words Used by {model1_name}"), # model1_title
|
262 |
-
gr.update(visible=True, value=model1_words_text), # model1_words
|
263 |
-
gr.update(visible=True, value=f"#### Top Words Used by {model2_name}"), # model2_title
|
264 |
-
gr.update(visible=True, value=model2_words_text), # model2_words
|
265 |
-
gr.update(visible=True), # similarity_metrics_title
|
266 |
-
gr.update(visible=True, value=similarity_text), # similarity_metrics
|
267 |
-
False, # status_message_visible
|
268 |
-
gr.update(visible=False) # status_message
|
269 |
-
)
|
270 |
-
|
271 |
-
except Exception as e:
|
272 |
-
import traceback
|
273 |
-
error_msg = f"Error in analysis: {str(e)}\n{traceback.format_exc()}"
|
274 |
-
print(error_msg)
|
275 |
-
|
276 |
-
return (
|
277 |
-
{"error": error_msg}, # analysis_results_state
|
278 |
-
True, # analysis_output visibility (show raw JSON for debugging)
|
279 |
-
False, # visualization_area_visible
|
280 |
-
gr.update(visible=False),
|
281 |
-
gr.update(visible=False),
|
282 |
-
gr.update(visible=False),
|
283 |
-
gr.update(visible=False),
|
284 |
-
gr.update(visible=False),
|
285 |
-
gr.update(visible=False),
|
286 |
-
gr.update(visible=False),
|
287 |
-
gr.update(visible=False),
|
288 |
-
gr.update(visible=False),
|
289 |
-
True, # status_message_visible
|
290 |
-
gr.update(visible=True, value=f"❌ **Error during analysis:**\n\n```\n{str(e)}\n```") # status_message
|
291 |
-
)
|
292 |
-
|
293 |
-
# Function to update visibility based on checkbox state
|
294 |
-
def update_visibility(viz_visible, status_visible):
|
295 |
-
return [
|
296 |
-
gr.update(visible=viz_visible), # analysis_title
|
297 |
-
gr.update(visible=viz_visible), # prompt_title
|
298 |
-
gr.update(visible=viz_visible), # models_compared
|
299 |
-
gr.update(visible=viz_visible), # model1_title
|
300 |
-
gr.update(visible=viz_visible), # model1_words
|
301 |
-
gr.update(visible=viz_visible), # model2_title
|
302 |
-
gr.update(visible=viz_visible), # model2_words
|
303 |
-
gr.update(visible=viz_visible), # similarity_metrics_title
|
304 |
-
gr.update(visible=viz_visible), # similarity_metrics
|
305 |
-
gr.update(visible=status_visible) # status_message
|
306 |
-
]
|
307 |
-
|
308 |
-
# Connect visibility checkboxes to update function
|
309 |
-
visualization_area_visible.change(
|
310 |
-
fn=update_visibility,
|
311 |
-
inputs=[visualization_area_visible, status_message_visible],
|
312 |
-
outputs=[
|
313 |
-
analysis_title,
|
314 |
-
prompt_title,
|
315 |
-
models_compared,
|
316 |
-
model1_title,
|
317 |
-
model1_words,
|
318 |
-
model2_title,
|
319 |
-
model2_words,
|
320 |
-
similarity_metrics_title,
|
321 |
-
similarity_metrics,
|
322 |
-
status_message
|
323 |
-
]
|
324 |
-
)
|
325 |
-
|
326 |
-
# Run analysis with proper parameters
|
327 |
-
run_analysis_btn.click(
|
328 |
-
fn=run_analysis,
|
329 |
-
inputs=[dataset_state, analysis_options, bow_top_slider, ngram_n, ngram_top],
|
330 |
-
outputs=[
|
331 |
-
analysis_results_state,
|
332 |
-
analysis_output,
|
333 |
-
visualization_area_visible,
|
334 |
-
analysis_title,
|
335 |
-
prompt_title,
|
336 |
-
models_compared,
|
337 |
-
model1_title,
|
338 |
-
model1_words,
|
339 |
-
model2_title,
|
340 |
-
model2_words,
|
341 |
-
similarity_metrics_title,
|
342 |
-
similarity_metrics,
|
343 |
-
status_message_visible,
|
344 |
-
status_message
|
345 |
-
]
|
346 |
-
)
|
347 |
-
|
348 |
-
return app
|
349 |
-
|
350 |
-
if __name__ == "__main__":
|
351 |
-
# Download required NLTK resources before launching the app
|
352 |
-
download_nltk_resources()
|
353 |
-
|
354 |
-
app = create_app()
|
355 |
-
app.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_archive/app.py
DELETED
@@ -1,63 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
import os
|
3 |
-
from ui.dataset_input import create_dataset_input, load_example_dataset
|
4 |
-
from ui.analysis_screen import process_analysis_request
|
5 |
-
|
6 |
-
def create_app():
|
7 |
-
"""
|
8 |
-
Create a streamlined Gradio app for dataset input and Bag of Words analysis.
|
9 |
-
|
10 |
-
Returns:
|
11 |
-
gr.Blocks: The Gradio application
|
12 |
-
"""
|
13 |
-
with gr.Blocks(title="LLM Response Comparator") as app:
|
14 |
-
# Application state to share data between tabs
|
15 |
-
dataset_state = gr.State({})
|
16 |
-
analysis_results_state = gr.State({})
|
17 |
-
|
18 |
-
# Dataset Input Tab
|
19 |
-
with gr.Tab("Dataset Input"):
|
20 |
-
dataset_inputs, example_dropdown, load_example_btn, create_btn, prompt, response1, model1, response2, model2 = create_dataset_input()
|
21 |
-
|
22 |
-
# Load example dataset
|
23 |
-
load_example_btn.click(
|
24 |
-
fn=load_example_dataset,
|
25 |
-
inputs=[example_dropdown],
|
26 |
-
outputs=[dataset_inputs] # Ensure `load_example_dataset` returns compatible data
|
27 |
-
)
|
28 |
-
|
29 |
-
# Save dataset to state
|
30 |
-
create_btn.click(
|
31 |
-
fn=lambda p, r1, m1, r2, m2: {
|
32 |
-
"entries": [
|
33 |
-
{"prompt": p, "response": r1, "model": m1},
|
34 |
-
{"prompt": p, "response": r2, "model": m2}
|
35 |
-
]
|
36 |
-
},
|
37 |
-
inputs=[prompt, response1, model1, response2, model2], # Ensure these are valid Gradio components
|
38 |
-
outputs=[dataset_state] # Ensure `dataset_state` is correctly defined
|
39 |
-
)
|
40 |
-
|
41 |
-
# Analysis Tab
|
42 |
-
with gr.Tab("Analysis"):
|
43 |
-
analysis_options = gr.CheckboxGroup(
|
44 |
-
choices=["Bag of Words"],
|
45 |
-
value=["Bag of Words"],
|
46 |
-
label="Select Analyses to Run"
|
47 |
-
)
|
48 |
-
run_analysis_btn = gr.Button("Run Analysis", variant="primary")
|
49 |
-
analysis_output = gr.JSON(label="Analysis Results", visible=False)
|
50 |
-
|
51 |
-
# Run analysis
|
52 |
-
run_analysis_btn.click(
|
53 |
-
fn=process_analysis_request,
|
54 |
-
inputs=[dataset_state, analysis_options], # Removed None
|
55 |
-
outputs=[analysis_results_state, analysis_output]
|
56 |
-
)
|
57 |
-
|
58 |
-
return app
|
59 |
-
|
60 |
-
if __name__ == "__main__":
|
61 |
-
# Create and launch the app
|
62 |
-
app = create_app()
|
63 |
-
app.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.bak.py
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
|
3 |
-
def greet(name):
|
4 |
-
return "Hello " + name + "!!"
|
5 |
-
|
6 |
-
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
|
7 |
-
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
@@ -97,7 +97,7 @@ def create_app():
|
|
97 |
# Analysis Tab
|
98 |
with gr.Tab("Analysis"):
|
99 |
# Use create_analysis_screen to get UI components including visualization container
|
100 |
-
analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top = create_analysis_screen()
|
101 |
|
102 |
# Pre-create visualization components (initially hidden)
|
103 |
visualization_area_visible = gr.Checkbox(value=False, visible=False, label="Visualization Visible")
|
@@ -122,7 +122,7 @@ def create_app():
|
|
122 |
status_message = gr.Markdown(visible=False)
|
123 |
|
124 |
# Define a helper function to extract parameter values and run the analysis
|
125 |
-
def run_analysis(dataset,
|
126 |
try:
|
127 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
128 |
return (
|
@@ -145,12 +145,14 @@ def create_app():
|
|
145 |
parameters = {
|
146 |
"bow_top": bow_top,
|
147 |
"ngram_n": ngram_n,
|
148 |
-
"ngram_top": ngram_top
|
|
|
149 |
}
|
150 |
-
print("Running analysis with
|
|
|
151 |
|
152 |
-
# Process the analysis request
|
153 |
-
analysis_results, _ = process_analysis_request(dataset,
|
154 |
|
155 |
# If there's an error or no results
|
156 |
if not analysis_results or "analyses" not in analysis_results or not analysis_results["analyses"]:
|
@@ -168,7 +170,7 @@ def create_app():
|
|
168 |
gr.update(visible=False),
|
169 |
gr.update(visible=False),
|
170 |
True,
|
171 |
-
gr.update(visible=True, value="❌ **No results found.** Try different analysis
|
172 |
)
|
173 |
|
174 |
# Extract information to display in components
|
@@ -196,6 +198,25 @@ def create_app():
|
|
196 |
similarity_metrics_visible = False
|
197 |
similarity_metrics_value = ""
|
198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
199 |
# Check for Bag of Words analysis
|
200 |
if "bag_of_words" in analyses:
|
201 |
visualization_area_visible = True
|
@@ -252,8 +273,8 @@ def create_app():
|
|
252 |
- **Common Words**: {common_words} words appear in both responses
|
253 |
"""
|
254 |
|
255 |
-
# Check for N-gram analysis
|
256 |
-
if "ngram_analysis" in analyses
|
257 |
visualization_area_visible = True
|
258 |
ngram_results = analyses["ngram_analysis"]
|
259 |
models = ngram_results.get("models", [])
|
@@ -304,6 +325,78 @@ def create_app():
|
|
304 |
- **Common {size_name}**: {common_count} {size_name.lower()} appear in both responses
|
305 |
"""
|
306 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
# If we don't have visualization data from any analysis
|
308 |
if not visualization_area_visible:
|
309 |
return (
|
@@ -320,7 +413,7 @@ def create_app():
|
|
320 |
gr.update(visible=False),
|
321 |
gr.update(visible=False),
|
322 |
True,
|
323 |
-
gr.update(visible=True, value="❌ **No visualization data found.** Make sure to select
|
324 |
)
|
325 |
|
326 |
# Return all updated component values
|
@@ -363,60 +456,59 @@ def create_app():
|
|
363 |
gr.update(visible=True, value=f"❌ **Error during analysis:**\n\n```\n{str(e)}\n```") # status_message
|
364 |
)
|
365 |
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
]
|
380 |
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
|
421 |
return app
|
422 |
|
@@ -425,4 +517,4 @@ if __name__ == "__main__":
|
|
425 |
download_nltk_resources()
|
426 |
|
427 |
app = create_app()
|
428 |
-
app.launch()
|
|
|
97 |
# Analysis Tab
|
98 |
with gr.Tab("Analysis"):
|
99 |
# Use create_analysis_screen to get UI components including visualization container
|
100 |
+
analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top, topic_count = create_analysis_screen()
|
101 |
|
102 |
# Pre-create visualization components (initially hidden)
|
103 |
visualization_area_visible = gr.Checkbox(value=False, visible=False, label="Visualization Visible")
|
|
|
122 |
status_message = gr.Markdown(visible=False)
|
123 |
|
124 |
# Define a helper function to extract parameter values and run the analysis
|
125 |
+
def run_analysis(dataset, selected_analysis, bow_top, ngram_n, ngram_top, topic_count):
|
126 |
try:
|
127 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
128 |
return (
|
|
|
145 |
parameters = {
|
146 |
"bow_top": bow_top,
|
147 |
"ngram_n": ngram_n,
|
148 |
+
"ngram_top": ngram_top,
|
149 |
+
"topic_count": topic_count
|
150 |
}
|
151 |
+
print(f"Running analysis with selected type: {selected_analysis}")
|
152 |
+
print("Parameters:", parameters)
|
153 |
|
154 |
+
# Process the analysis request - note we're now passing selected_analysis as a string, not a list
|
155 |
+
analysis_results, _ = process_analysis_request(dataset, selected_analysis, parameters)
|
156 |
|
157 |
# If there's an error or no results
|
158 |
if not analysis_results or "analyses" not in analysis_results or not analysis_results["analyses"]:
|
|
|
170 |
gr.update(visible=False),
|
171 |
gr.update(visible=False),
|
172 |
True,
|
173 |
+
gr.update(visible=True, value="❌ **No results found.** Try a different analysis option.")
|
174 |
)
|
175 |
|
176 |
# Extract information to display in components
|
|
|
198 |
similarity_metrics_visible = False
|
199 |
similarity_metrics_value = ""
|
200 |
|
201 |
+
# Check for messages from placeholder analyses
|
202 |
+
if "message" in analyses:
|
203 |
+
return (
|
204 |
+
analysis_results,
|
205 |
+
False,
|
206 |
+
False,
|
207 |
+
gr.update(visible=False),
|
208 |
+
gr.update(visible=False),
|
209 |
+
gr.update(visible=False),
|
210 |
+
gr.update(visible=False),
|
211 |
+
gr.update(visible=False),
|
212 |
+
gr.update(visible=False),
|
213 |
+
gr.update(visible=False),
|
214 |
+
gr.update(visible=False),
|
215 |
+
gr.update(visible=False),
|
216 |
+
True,
|
217 |
+
gr.update(visible=True, value=f"ℹ️ **{analyses['message']}**")
|
218 |
+
)
|
219 |
+
|
220 |
# Check for Bag of Words analysis
|
221 |
if "bag_of_words" in analyses:
|
222 |
visualization_area_visible = True
|
|
|
273 |
- **Common Words**: {common_words} words appear in both responses
|
274 |
"""
|
275 |
|
276 |
+
# Check for N-gram analysis
|
277 |
+
if "ngram_analysis" in analyses:
|
278 |
visualization_area_visible = True
|
279 |
ngram_results = analyses["ngram_analysis"]
|
280 |
models = ngram_results.get("models", [])
|
|
|
325 |
- **Common {size_name}**: {common_count} {size_name.lower()} appear in both responses
|
326 |
"""
|
327 |
|
328 |
+
# Check for Topic Modeling analysis
|
329 |
+
if "topic_modeling" in analyses:
|
330 |
+
visualization_area_visible = True
|
331 |
+
topic_results = analyses["topic_modeling"]
|
332 |
+
models = topic_results.get("models", [])
|
333 |
+
method = topic_results.get("method", "lda").upper()
|
334 |
+
n_topics = topic_results.get("n_topics", 3)
|
335 |
+
|
336 |
+
if len(models) >= 2:
|
337 |
+
prompt_title_visible = True
|
338 |
+
prompt_title_value = f"## Analysis of Prompt: \"{prompt[:100]}...\""
|
339 |
+
|
340 |
+
models_compared_visible = True
|
341 |
+
models_compared_value = f"### Topic Modeling Analysis ({method}, {n_topics} topics)"
|
342 |
+
|
343 |
+
# Extract and format topic information
|
344 |
+
topics = topic_results.get("topics", [])
|
345 |
+
|
346 |
+
if topics:
|
347 |
+
# Format topic info for display
|
348 |
+
topic_info = []
|
349 |
+
for topic in topics[:3]: # Show first 3 topics
|
350 |
+
topic_id = topic.get("id", 0)
|
351 |
+
words = topic.get("words", [])[:5] # Top 5 words per topic
|
352 |
+
|
353 |
+
if words:
|
354 |
+
topic_info.append(f"**Topic {topic_id+1}**: {', '.join(words)}")
|
355 |
+
|
356 |
+
if topic_info:
|
357 |
+
model1_title_visible = True
|
358 |
+
model1_title_value = "#### Discovered Topics"
|
359 |
+
model1_words_visible = True
|
360 |
+
model1_words_value = "\n".join(topic_info)
|
361 |
+
|
362 |
+
# Get topic distributions for models
|
363 |
+
model_topics = topic_results.get("model_topics", {})
|
364 |
+
|
365 |
+
if model_topics:
|
366 |
+
model1_name = models[0]
|
367 |
+
model2_name = models[1]
|
368 |
+
|
369 |
+
# Format topic distribution info
|
370 |
+
if model1_name in model_topics and model2_name in model_topics:
|
371 |
+
model2_title_visible = True
|
372 |
+
model2_title_value = "#### Topic Distribution"
|
373 |
+
model2_words_visible = True
|
374 |
+
|
375 |
+
# Simple distribution display
|
376 |
+
dist1 = model_topics[model1_name]
|
377 |
+
dist2 = model_topics[model2_name]
|
378 |
+
|
379 |
+
model2_words_value = f"""
|
380 |
+
**{model1_name}**: {', '.join([f"Topic {i+1}: {v:.2f}" for i, v in enumerate(dist1[:3])])}
|
381 |
+
|
382 |
+
**{model2_name}**: {', '.join([f"Topic {i+1}: {v:.2f}" for i, v in enumerate(dist2[:3])])}
|
383 |
+
"""
|
384 |
+
|
385 |
+
# Add similarity metrics if available
|
386 |
+
comparisons = topic_results.get("comparisons", {})
|
387 |
+
if comparisons:
|
388 |
+
comparison_key = f"{model1_name} vs {model2_name}"
|
389 |
+
|
390 |
+
if comparison_key in comparisons:
|
391 |
+
metrics = comparisons[comparison_key]
|
392 |
+
js_div = metrics.get("js_divergence", 0)
|
393 |
+
|
394 |
+
similarity_title_visible = True
|
395 |
+
similarity_metrics_visible = True
|
396 |
+
similarity_metrics_value = f"""
|
397 |
+
- **Topic Distribution Divergence**: {js_div:.4f} (lower means more similar topic distributions)
|
398 |
+
"""
|
399 |
+
|
400 |
# If we don't have visualization data from any analysis
|
401 |
if not visualization_area_visible:
|
402 |
return (
|
|
|
413 |
gr.update(visible=False),
|
414 |
gr.update(visible=False),
|
415 |
True,
|
416 |
+
gr.update(visible=True, value="❌ **No visualization data found.** Make sure to select a valid analysis option.")
|
417 |
)
|
418 |
|
419 |
# Return all updated component values
|
|
|
456 |
gr.update(visible=True, value=f"❌ **Error during analysis:**\n\n```\n{str(e)}\n```") # status_message
|
457 |
)
|
458 |
|
459 |
+
def update_visibility(viz_visible, status_visible):
|
460 |
+
return [
|
461 |
+
gr.update(visible=viz_visible), # analysis_title
|
462 |
+
gr.update(visible=viz_visible), # prompt_title
|
463 |
+
gr.update(visible=viz_visible), # models_compared
|
464 |
+
gr.update(visible=viz_visible), # model1_title
|
465 |
+
gr.update(visible=viz_visible), # model1_words
|
466 |
+
gr.update(visible=viz_visible), # model2_title
|
467 |
+
gr.update(visible=viz_visible), # model2_words
|
468 |
+
gr.update(visible=viz_visible), # similarity_metrics_title
|
469 |
+
gr.update(visible=viz_visible), # similarity_metrics
|
470 |
+
gr.update(visible=status_visible) # status_message
|
471 |
+
]
|
|
|
472 |
|
473 |
+
# Connect visibility checkboxes to update function
|
474 |
+
visualization_area_visible.change(
|
475 |
+
fn=update_visibility,
|
476 |
+
inputs=[visualization_area_visible, status_message_visible],
|
477 |
+
outputs=[
|
478 |
+
analysis_title,
|
479 |
+
prompt_title,
|
480 |
+
models_compared,
|
481 |
+
model1_title,
|
482 |
+
model1_words,
|
483 |
+
model2_title,
|
484 |
+
model2_words,
|
485 |
+
similarity_metrics_title,
|
486 |
+
similarity_metrics,
|
487 |
+
status_message
|
488 |
+
]
|
489 |
+
)
|
490 |
|
491 |
+
# Run analysis with proper parameters - update to include topic_count
|
492 |
+
run_analysis_btn.click(
|
493 |
+
fn=run_analysis,
|
494 |
+
inputs=[dataset_state, analysis_options, bow_top_slider, ngram_n, ngram_top, topic_count],
|
495 |
+
outputs=[
|
496 |
+
analysis_results_state,
|
497 |
+
analysis_output,
|
498 |
+
visualization_area_visible,
|
499 |
+
analysis_title,
|
500 |
+
prompt_title,
|
501 |
+
models_compared,
|
502 |
+
model1_title,
|
503 |
+
model1_words,
|
504 |
+
model2_title,
|
505 |
+
model2_words,
|
506 |
+
similarity_metrics_title,
|
507 |
+
similarity_metrics,
|
508 |
+
status_message_visible,
|
509 |
+
status_message
|
510 |
+
]
|
511 |
+
)
|
512 |
|
513 |
return app
|
514 |
|
|
|
517 |
download_nltk_resources()
|
518 |
|
519 |
app = create_app()
|
520 |
+
app.launch()
|
ui/analysis_screen.py
CHANGED
@@ -3,8 +3,7 @@ import json
|
|
3 |
from visualization.bow_visualizer import process_and_visualize_analysis
|
4 |
|
5 |
# Import analysis modules
|
6 |
-
|
7 |
-
# from processors.topic_modeling import extract_topics, compare_topics
|
8 |
from processors.ngram_analysis import compare_ngrams
|
9 |
# from processors.bias_detection import compare_bias
|
10 |
from processors.bow_analysis import compare_bow
|
@@ -16,27 +15,25 @@ def create_analysis_screen():
|
|
16 |
Create the analysis options screen
|
17 |
|
18 |
Returns:
|
19 |
-
tuple: (analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top)
|
20 |
"""
|
21 |
with gr.Column() as analysis_screen:
|
22 |
gr.Markdown("## Analysis Options")
|
23 |
-
gr.Markdown("Select which
|
24 |
|
25 |
-
#
|
26 |
with gr.Group():
|
27 |
-
analysis_options = gr.
|
28 |
choices=[
|
29 |
-
"
|
30 |
"N-gram Analysis",
|
|
|
31 |
"Bias Detection",
|
32 |
-
"
|
33 |
-
"
|
34 |
-
"Difference Highlighting"
|
35 |
],
|
36 |
-
value=
|
37 |
-
|
38 |
-
],
|
39 |
-
label="Select Analyses to Run"
|
40 |
)
|
41 |
|
42 |
# Create slider directly here for easier access
|
@@ -59,13 +56,19 @@ def create_analysis_screen():
|
|
59 |
visible=False
|
60 |
)
|
61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
# Parameters for each analysis type
|
63 |
with gr.Group() as analysis_params:
|
64 |
# Topic modeling parameters
|
65 |
with gr.Group(visible=False) as topic_params:
|
66 |
gr.Markdown("### Topic Modeling Parameters")
|
67 |
-
|
68 |
-
label="Number of Topics")
|
69 |
|
70 |
# N-gram parameters group (using external ngram_n and ngram_top)
|
71 |
with gr.Group(visible=False) as ngram_params:
|
@@ -81,32 +84,45 @@ def create_analysis_screen():
|
|
81 |
label="Bias Detection Methods"
|
82 |
)
|
83 |
|
84 |
-
#
|
85 |
-
with gr.Group(visible=False) as
|
86 |
-
gr.Markdown("###
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
)
|
|
|
92 |
|
93 |
-
# Function to update parameter visibility based on selected
|
94 |
def update_params_visibility(selected):
|
95 |
-
ngram_visible = "N-gram Analysis" in selected
|
96 |
return {
|
97 |
-
topic_params: gr.update(visible="Topic Modeling"
|
98 |
-
ngram_params: gr.update(visible=
|
99 |
-
bias_params: gr.update(visible="Bias Detection"
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
103 |
}
|
104 |
|
105 |
# Set up event handler for analysis selection
|
106 |
analysis_options.change(
|
107 |
fn=update_params_visibility,
|
108 |
inputs=[analysis_options],
|
109 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
)
|
111 |
|
112 |
# Run analysis button
|
@@ -116,15 +132,15 @@ def create_analysis_screen():
|
|
116 |
analysis_output = gr.JSON(label="Analysis Results", visible=False)
|
117 |
|
118 |
# Return the components needed by app.py
|
119 |
-
return analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top
|
120 |
|
121 |
# Process analysis request function
|
122 |
-
def process_analysis_request(dataset,
|
123 |
"""
|
124 |
-
Process the analysis request and run selected
|
125 |
"""
|
126 |
try:
|
127 |
-
print(f"Processing analysis request with: {
|
128 |
print(f"Parameters: {parameters}")
|
129 |
|
130 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
@@ -144,19 +160,36 @@ def process_analysis_request(dataset, selected_analyses, parameters):
|
|
144 |
analysis_results["analyses"][prompt] = {}
|
145 |
|
146 |
# Run Bag of Words analysis if selected
|
147 |
-
if "Bag of Words"
|
148 |
top_words = parameters.get("bow_top", 25)
|
149 |
print(f"Running BOW analysis with top_words={top_words}")
|
150 |
bow_results = compare_bow(response_texts, model_names, top_words)
|
151 |
analysis_results["analyses"][prompt]["bag_of_words"] = bow_results
|
152 |
|
153 |
# Run N-gram analysis if selected
|
154 |
-
|
155 |
ngram_n = int(parameters.get("ngram_n", "2"))
|
156 |
ngram_top = parameters.get("ngram_top", 10)
|
157 |
print(f"Running N-gram analysis with n={ngram_n}, top_n={ngram_top}")
|
158 |
ngram_results = compare_ngrams(response_texts, model_names, ngram_n, ngram_top)
|
159 |
analysis_results["analyses"][prompt]["ngram_analysis"] = ngram_results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
print("Analysis complete - results:", analysis_results)
|
162 |
|
|
|
3 |
from visualization.bow_visualizer import process_and_visualize_analysis
|
4 |
|
5 |
# Import analysis modules
|
6 |
+
from processors.topic_modeling import compare_topics # Added import
|
|
|
7 |
from processors.ngram_analysis import compare_ngrams
|
8 |
# from processors.bias_detection import compare_bias
|
9 |
from processors.bow_analysis import compare_bow
|
|
|
15 |
Create the analysis options screen
|
16 |
|
17 |
Returns:
|
18 |
+
tuple: (analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top, topic_count)
|
19 |
"""
|
20 |
with gr.Column() as analysis_screen:
|
21 |
gr.Markdown("## Analysis Options")
|
22 |
+
gr.Markdown("Select which analysis you want to run on the LLM responses.")
|
23 |
|
24 |
+
# Change from CheckboxGroup to Radio for analysis selection
|
25 |
with gr.Group():
|
26 |
+
analysis_options = gr.Radio(
|
27 |
choices=[
|
28 |
+
"Bag of Words",
|
29 |
"N-gram Analysis",
|
30 |
+
"Topic Modeling",
|
31 |
"Bias Detection",
|
32 |
+
"Classifier", # New option for future development
|
33 |
+
"LLM Analysis" # New option for future development
|
|
|
34 |
],
|
35 |
+
value="Bag of Words", # Default selection
|
36 |
+
label="Select Analysis Type"
|
|
|
|
|
37 |
)
|
38 |
|
39 |
# Create slider directly here for easier access
|
|
|
56 |
visible=False
|
57 |
)
|
58 |
|
59 |
+
# Create topic modeling parameter accessible at top level
|
60 |
+
topic_count = gr.Slider(
|
61 |
+
minimum=2, maximum=10, value=3, step=1,
|
62 |
+
label="Number of Topics",
|
63 |
+
visible=False
|
64 |
+
)
|
65 |
+
|
66 |
# Parameters for each analysis type
|
67 |
with gr.Group() as analysis_params:
|
68 |
# Topic modeling parameters
|
69 |
with gr.Group(visible=False) as topic_params:
|
70 |
gr.Markdown("### Topic Modeling Parameters")
|
71 |
+
# We'll use the topic_count defined above
|
|
|
72 |
|
73 |
# N-gram parameters group (using external ngram_n and ngram_top)
|
74 |
with gr.Group(visible=False) as ngram_params:
|
|
|
84 |
label="Bias Detection Methods"
|
85 |
)
|
86 |
|
87 |
+
# Classifier parameters for future development
|
88 |
+
with gr.Group(visible=False) as classifier_params:
|
89 |
+
gr.Markdown("### Classifier Parameters")
|
90 |
+
gr.Markdown("*Classifier options will be available in a future update*")
|
91 |
+
|
92 |
+
# LLM Analysis parameters for future development
|
93 |
+
with gr.Group(visible=False) as llm_params:
|
94 |
+
gr.Markdown("### LLM Analysis Parameters")
|
95 |
+
gr.Markdown("*LLM Analysis options will be available in a future update*")
|
96 |
|
97 |
+
# Function to update parameter visibility based on selected analysis
|
98 |
def update_params_visibility(selected):
|
|
|
99 |
return {
|
100 |
+
topic_params: gr.update(visible=selected == "Topic Modeling"),
|
101 |
+
ngram_params: gr.update(visible=selected == "N-gram Analysis"),
|
102 |
+
bias_params: gr.update(visible=selected == "Bias Detection"),
|
103 |
+
classifier_params: gr.update(visible=selected == "Classifier"),
|
104 |
+
llm_params: gr.update(visible=selected == "LLM Analysis"),
|
105 |
+
ngram_n: gr.update(visible=selected == "N-gram Analysis"),
|
106 |
+
ngram_top: gr.update(visible=selected == "N-gram Analysis"),
|
107 |
+
topic_count: gr.update(visible=selected == "Topic Modeling"),
|
108 |
+
bow_top_slider: gr.update(visible=selected == "Bag of Words")
|
109 |
}
|
110 |
|
111 |
# Set up event handler for analysis selection
|
112 |
analysis_options.change(
|
113 |
fn=update_params_visibility,
|
114 |
inputs=[analysis_options],
|
115 |
+
outputs=[
|
116 |
+
topic_params,
|
117 |
+
ngram_params,
|
118 |
+
bias_params,
|
119 |
+
classifier_params,
|
120 |
+
llm_params,
|
121 |
+
ngram_n,
|
122 |
+
ngram_top,
|
123 |
+
topic_count,
|
124 |
+
bow_top_slider
|
125 |
+
]
|
126 |
)
|
127 |
|
128 |
# Run analysis button
|
|
|
132 |
analysis_output = gr.JSON(label="Analysis Results", visible=False)
|
133 |
|
134 |
# Return the components needed by app.py
|
135 |
+
return analysis_options, analysis_params, run_analysis_btn, analysis_output, bow_top_slider, ngram_n, ngram_top, topic_count
|
136 |
|
137 |
# Process analysis request function
|
138 |
+
def process_analysis_request(dataset, selected_analysis, parameters):
|
139 |
"""
|
140 |
+
Process the analysis request and run selected analysis
|
141 |
"""
|
142 |
try:
|
143 |
+
print(f"Processing analysis request with: {selected_analysis}")
|
144 |
print(f"Parameters: {parameters}")
|
145 |
|
146 |
if not dataset or "entries" not in dataset or not dataset["entries"]:
|
|
|
160 |
analysis_results["analyses"][prompt] = {}
|
161 |
|
162 |
# Run Bag of Words analysis if selected
|
163 |
+
if selected_analysis == "Bag of Words":
|
164 |
top_words = parameters.get("bow_top", 25)
|
165 |
print(f"Running BOW analysis with top_words={top_words}")
|
166 |
bow_results = compare_bow(response_texts, model_names, top_words)
|
167 |
analysis_results["analyses"][prompt]["bag_of_words"] = bow_results
|
168 |
|
169 |
# Run N-gram analysis if selected
|
170 |
+
elif selected_analysis == "N-gram Analysis":
|
171 |
ngram_n = int(parameters.get("ngram_n", "2"))
|
172 |
ngram_top = parameters.get("ngram_top", 10)
|
173 |
print(f"Running N-gram analysis with n={ngram_n}, top_n={ngram_top}")
|
174 |
ngram_results = compare_ngrams(response_texts, model_names, ngram_n, ngram_top)
|
175 |
analysis_results["analyses"][prompt]["ngram_analysis"] = ngram_results
|
176 |
+
|
177 |
+
# Run Topic Modeling analysis if selected
|
178 |
+
elif selected_analysis == "Topic Modeling":
|
179 |
+
topic_count = int(parameters.get("topic_count", 3))
|
180 |
+
print(f"Running Topic Modeling analysis with topic_count={topic_count}")
|
181 |
+
topic_results = compare_topics(response_texts, model_names, n_topics=topic_count)
|
182 |
+
analysis_results["analyses"][prompt]["topic_modeling"] = topic_results
|
183 |
+
|
184 |
+
# Add placeholder for future analysis types
|
185 |
+
elif selected_analysis == "Bias Detection":
|
186 |
+
analysis_results["analyses"][prompt]["message"] = "Bias Detection will be available in a future update"
|
187 |
+
|
188 |
+
elif selected_analysis == "Classifier":
|
189 |
+
analysis_results["analyses"][prompt]["message"] = "Classifier will be available in a future update"
|
190 |
+
|
191 |
+
elif selected_analysis == "LLM Analysis":
|
192 |
+
analysis_results["analyses"][prompt]["message"] = "LLM Analysis will be available in a future update"
|
193 |
|
194 |
print("Analysis complete - results:", analysis_results)
|
195 |
|
visualization/bow_visualizer.py
CHANGED
@@ -8,6 +8,7 @@ import pandas as pd
|
|
8 |
from difflib import SequenceMatcher
|
9 |
|
10 |
from visualization.ngram_visualizer import create_ngram_visualization
|
|
|
11 |
|
12 |
def create_bow_visualization(analysis_results):
|
13 |
"""
|
@@ -203,6 +204,14 @@ def process_and_visualize_analysis(analysis_results):
|
|
203 |
ngram_components = create_ngram_visualization(
|
204 |
{"analyses": {prompt: {"ngram_analysis": analyses["ngram_analysis"]}}})
|
205 |
components.extend(ngram_components)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
|
207 |
if not components:
|
208 |
components.append(gr.Markdown("No visualization components could be created from the analysis results."))
|
|
|
8 |
from difflib import SequenceMatcher
|
9 |
|
10 |
from visualization.ngram_visualizer import create_ngram_visualization
|
11 |
+
from visualization.topic_visualizer import process_and_visualize_topic_analysis # Added import
|
12 |
|
13 |
def create_bow_visualization(analysis_results):
|
14 |
"""
|
|
|
204 |
ngram_components = create_ngram_visualization(
|
205 |
{"analyses": {prompt: {"ngram_analysis": analyses["ngram_analysis"]}}})
|
206 |
components.extend(ngram_components)
|
207 |
+
|
208 |
+
# Check for Topic Modeling analysis
|
209 |
+
if "topic_modeling" in analyses:
|
210 |
+
print("Processing Topic Modeling visualization")
|
211 |
+
# Use the dedicated topic visualization function
|
212 |
+
topic_components = process_and_visualize_topic_analysis(
|
213 |
+
{"analyses": {prompt: {"topic_modeling": analyses["topic_modeling"]}}})
|
214 |
+
components.extend(topic_components)
|
215 |
|
216 |
if not components:
|
217 |
components.append(gr.Markdown("No visualization components could be created from the analysis results."))
|