vIVANsy commited on
Commit
4757368
·
verified ·
1 Parent(s): 4442eaf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +218 -133
app.py CHANGED
@@ -1,46 +1,52 @@
1
  import streamlit as st
2
- import warnings
3
- from sentence_transformers import SentenceTransformer
4
- from scipy.spatial.distance import cosine
5
- from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
 
6
  from sklearn.metrics import pairwise_distances
7
- from nltk.translate.bleu_score import sentence_bleu
8
  from rouge_score import rouge_scorer
9
- import numpy as np
 
 
10
  import PyPDF2
11
- import seaborn as sns
12
- import matplotlib.pyplot as plt
13
- import pandas as pd
14
  from difflib import SequenceMatcher
15
- import streamlit_shadcn_ui as ui
16
- import bert_score
17
- import gensim.downloader as api
18
 
19
- # Suppress specific FutureWarning from transformers
20
- warnings.filterwarnings("ignore", category=FutureWarning, message=".*clean_up_tokenization_spaces.*")
 
 
 
21
 
22
  # Initialize models
23
- model = SentenceTransformer('all-mpnet-base-v2')
24
- tfidf_vectorizer = TfidfVectorizer()
 
 
 
 
 
 
25
 
26
  # Initialize session state for results table if not already present
27
  if 'results_df' not in st.session_state:
28
  st.session_state.results_df = pd.DataFrame(columns=[
29
- "LLM1", "LLM2",
30
- "Context Similarity (%)",
31
- "Levenshtein Similarity (%)",
32
- "Jaccard Similarity (%)",
33
- "BLEU Score",
34
- "ROUGE-L (%)",
35
- "BERTScore (%)",
36
- "WMD"
37
  ])
38
 
39
- # Function to chunk text into smaller parts
 
 
 
 
 
40
  def chunk_text(text, chunk_size=500):
41
  return [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)]
42
 
43
- # Function to create embeddings
44
  def create_embeddings(chunks):
45
  try:
46
  embeddings = model.encode(chunks, show_progress_bar=False)
@@ -49,7 +55,7 @@ def create_embeddings(chunks):
49
  st.error(f"Error creating embeddings: {e}")
50
  return np.array([])
51
 
52
- # Function to calculate similarity ratio and find matches
53
  def calculate_similarity_ratio_and_find_matches(embeddings1, embeddings2):
54
  try:
55
  similarities = np.dot(embeddings1, embeddings2.T) # Dot product
@@ -60,11 +66,13 @@ def calculate_similarity_ratio_and_find_matches(embeddings1, embeddings2):
60
  st.error(f"Error calculating similarity ratio: {e}")
61
  return np.array([]), 0
62
 
63
- # Function to calculate word similarity ratio
64
  def calculate_word_similarity_ratio(text1, text2):
65
  try:
66
- words1 = text1.split()
67
- words2 = text2.split()
 
 
68
 
69
  if not words1 or not words2:
70
  return 0
@@ -73,7 +81,7 @@ def calculate_word_similarity_ratio(text1, text2):
73
  word_embeddings2 = model.encode(words2)
74
 
75
  similarities = np.array([
76
- max([1 - cosine(emb1, emb2) for emb2 in word_embeddings2], default=0)
77
  for emb1 in word_embeddings1
78
  ])
79
 
@@ -83,27 +91,32 @@ def calculate_word_similarity_ratio(text1, text2):
83
  st.error(f"Error calculating word similarity ratio: {e}")
84
  return 0
85
 
86
- # Function to calculate BLEU score
87
  def calculate_bleu_score(reference, candidate):
 
88
  return sentence_bleu([reference.split()], candidate.split())
89
 
90
- # Function to calculate ROUGE-L score
91
  def calculate_rouge_l_score(reference, candidate):
92
  scorer = rouge_scorer.RougeScorer(['rougeL'], use_stemmer=True)
93
  scores = scorer.score(reference, candidate)
94
  return scores['rougeL'].fmeasure * 100
95
 
96
- # Function to calculate BERTScore
97
  def calculate_bertscore(reference, candidate):
 
98
  P, R, F1 = bert_score.score([candidate], [reference], model_type='bert-base-uncased')
99
  return F1.mean().item() * 100
100
 
101
- # Function to calculate WMD
102
  def calculate_wmd(reference, candidate):
103
- model = api.load("word2vec-google-news-300")
104
- return model.wmdistance(reference.split(), candidate.split())
 
 
 
105
 
106
- # Function to extract text from PDF
107
  def extract_pdf_text(pdf_file):
108
  try:
109
  reader = PyPDF2.PdfReader(pdf_file)
@@ -115,128 +128,200 @@ def extract_pdf_text(pdf_file):
115
  st.error(f"Error extracting text from PDF: {e}")
116
  return ""
117
 
118
- # Function to calculate Levenshtein distance
119
  def calculate_levenshtein_ratio(text1, text2):
120
  return SequenceMatcher(None, text1, text2).ratio()
121
 
122
- # Function to calculate Jaccard similarity
123
  def calculate_jaccard_similarity(text1, text2):
 
124
  vectorizer = CountVectorizer(binary=True).fit_transform([text1, text2])
125
  vectors = vectorizer.toarray()
126
- # Compute the intersection and union for Jaccard Similarity
127
  intersection = np.sum(np.minimum(vectors[0], vectors[1]))
128
  union = np.sum(np.maximum(vectors[0], vectors[1]))
129
  return intersection / union if union != 0 else 0
130
 
131
- # Function to calculate TF-IDF cosine similarity
132
  def calculate_tfidf_cosine_similarity(text1, text2):
133
  tfidf_matrix = tfidf_vectorizer.fit_transform([text1, text2])
134
  return 1 - pairwise_distances(tfidf_matrix, metric='cosine')[0, 1]
135
 
136
- # Streamlit UI
137
- st.sidebar.title("LLM Details")
138
- llm1_name = st.sidebar.text_input("What is LLM1?", "LLM1")
139
- llm2_name = st.sidebar.text_input("What is LLM2?", "LLM2")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
 
141
  st.title("Text-Based Similarity Comparison")
142
 
143
- # Create two columns for text input
144
- col1, col2 = st.columns(2)
145
 
146
  with col1:
147
- st.write(f"**{llm1_name} response**")
148
- upload_pdf_1 = st.file_uploader(f"Upload PDF for {llm1_name} response", type="pdf", key="pdf1")
149
- if upload_pdf_1:
150
- text_input_1 = extract_pdf_text(upload_pdf_1)
151
- else:
152
- text_input_1 = st.text_area(f" Text for {llm1_name}", height=150, key="text1")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
- with col2:
155
- st.write(f"**{llm2_name} response**")
156
- upload_pdf_2 = st.file_uploader(f"Upload PDF for {llm2_name} response", type="pdf", key="pdf2")
157
- if upload_pdf_2:
158
- text_input_2 = extract_pdf_text(upload_pdf_2)
159
- else:
160
- text_input_2 = st.text_area(f" Text for {llm2_name}", height=150, key="text2")
161
-
162
- if (text_input_1 and text_input_2) or (upload_pdf_1 and upload_pdf_2):
163
- if st.button("Submit"):
164
- # Process texts
165
- chunks_1 = chunk_text(text_input_1)
166
- chunks_2 = chunk_text(text_input_2)
167
- embeddings_1 = create_embeddings(chunks_1)
168
- embeddings_2 = create_embeddings(chunks_2)
169
 
170
- # Calculate and display similarity ratio
171
- if embeddings_1.size > 0 and embeddings_2.size > 0:
172
- similarities, similarity_ratio = calculate_similarity_ratio_and_find_matches(embeddings_1, embeddings_2)
173
-
174
- # Calculate word similarity ratios for chunks
175
- word_similarities = []
176
- min_chunks = min(len(chunks_1), len(chunks_2))
177
- for i in range(min_chunks):
178
- word_similarity_ratio = calculate_word_similarity_ratio(chunks_1[i], chunks_2[i])
179
- word_similarities.append(word_similarity_ratio * 100)
180
-
181
- # Calculate additional metrics
182
- levenshtein_ratio = calculate_levenshtein_ratio(text_input_1, text_input_2) * 100
183
- jaccard_similarity = calculate_jaccard_similarity(text_input_1, text_input_2) * 100
184
- tfidf_cosine_similarity = calculate_tfidf_cosine_similarity(text_input_1, text_input_2) * 100
185
- bleu_score = calculate_bleu_score(text_input_1, text_input_2) * 100
186
- rouge_l_score = calculate_rouge_l_score(text_input_1, text_input_2)
187
- bertscore = calculate_bertscore(text_input_1, text_input_2)
188
- wmd = calculate_wmd(text_input_1, text_input_2)
189
 
190
  # Update results table in session state
191
  new_row = pd.Series({
192
  "LLM1": llm1_name,
193
  "LLM2": llm2_name,
194
- "Context Similarity (%)": similarity_ratio * 100,
195
- "Levenshtein Similarity (%)": levenshtein_ratio,
196
- "Jaccard Similarity (%)": jaccard_similarity,
197
- "BLEU Score": bleu_score,
198
- "ROUGE-L (%)": rouge_l_score,
199
- "BERTScore (%)": bertscore,
200
- "WMD": wmd
201
  })
202
-
203
  st.session_state.results_df = pd.concat([st.session_state.results_df, new_row.to_frame().T], ignore_index=True)
204
 
205
- # Display metrics
 
 
 
 
 
 
 
 
206
  st.subheader("Results")
207
- st.write(f"**Context Similarity:** {similarity_ratio * 100:.2f}%")
208
- st.write(f"**Levenshtein Similarity:** {levenshtein_ratio:.2f}%")
209
- st.write(f"**Jaccard Similarity:** {jaccard_similarity:.2f}%")
210
- st.write(f"**TF-IDF Cosine Similarity:** {tfidf_cosine_similarity:.2f}%")
211
- st.write(f"**BLEU Score:** {bleu_score:.2f}")
212
- st.write(f"**ROUGE-L Score:** {rouge_l_score:.2f}%")
213
- st.write(f"**BERTScore:** {bertscore:.2f}%")
214
- st.write(f"**Word Mover's Distance (WMD):** {wmd:.4f}")
215
-
216
- # Visualize the data
217
- st.subheader("Metrics Comparison")
218
- sns.set(style="whitegrid")
219
- fig, ax = plt.subplots(figsize=(10, 6))
220
- sns.barplot(data=st.session_state.results_df.drop(columns=["LLM1", "LLM2", "WMD"]), palette="viridis")
221
- plt.xticks(rotation=45)
222
- plt.title("Text Similarity Metrics")
223
- plt.tight_layout()
224
- st.pyplot(fig)
225
-
226
- st.subheader("Similarity Over Chunks")
227
- fig, ax = plt.subplots(figsize=(10, 6))
228
- ax.plot(word_similarities, marker='o', linestyle='-', color='b', label='Word Similarity')
229
- ax.axhline(similarity_ratio * 100, color='r', linestyle='--', label='Context Similarity')
230
- plt.xlabel("Chunk Index")
231
- plt.ylabel("Similarity (%)")
232
- plt.legend()
233
- plt.title("Similarity across Text Chunks")
234
- plt.tight_layout()
235
- st.pyplot(fig)
236
-
237
- # Display results dataframe
238
- st.subheader("Detailed Results Table")
239
- st.write(st.session_state.results_df)
240
-
241
- else:
242
- st.warning("Please enter both responses or upload PDF files.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import numpy as np
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ from sklearn.feature_extraction.text import TfidfVectorizer
7
  from sklearn.metrics import pairwise_distances
 
8
  from rouge_score import rouge_scorer
9
+ import gensim.downloader as api
10
+ from sentence_transformers import SentenceTransformer
11
+ from scipy.spatial.distance import cosine
12
  import PyPDF2
13
+ import spacy
 
 
14
  from difflib import SequenceMatcher
 
 
 
15
 
16
+ # Load spaCy model
17
+ nlp = spacy.load('en_core_web_sm')
18
+
19
+ # Load stop words from spaCy
20
+ stop_words = set(nlp.Defaults.stop_words)
21
 
22
  # Initialize models
23
+ @st.cache_resource
24
+ def load_models():
25
+ model = SentenceTransformer('all-mpnet-base-v2')
26
+ tfidf_vectorizer = TfidfVectorizer()
27
+ word2vec_model = api.load("word2vec-google-news-300") # Load Word2Vec model
28
+ return model, tfidf_vectorizer, word2vec_model
29
+
30
+ model, tfidf_vectorizer, word2vec_model = load_models()
31
 
32
  # Initialize session state for results table if not already present
33
  if 'results_df' not in st.session_state:
34
  st.session_state.results_df = pd.DataFrame(columns=[
35
+ "LLM1", "LLM2", "Paraphrasing Similarity (%)",
36
+ "Direct Text Comparison (%)", "Summarization Similarity (%)",
37
+ "Combined Similarity (%)"
 
 
 
 
 
38
  ])
39
 
40
+ # Initialize session state for radar chart data if not already present
41
+ if 'radar_chart_data' not in st.session_state:
42
+ st.session_state.radar_chart_data = []
43
+
44
+ # Functions
45
+ @st.cache_data
46
  def chunk_text(text, chunk_size=500):
47
  return [text[i:i+chunk_size] for i in range(0, len(text), chunk_size)]
48
 
49
+ @st.cache_data
50
  def create_embeddings(chunks):
51
  try:
52
  embeddings = model.encode(chunks, show_progress_bar=False)
 
55
  st.error(f"Error creating embeddings: {e}")
56
  return np.array([])
57
 
58
+ @st.cache_data
59
  def calculate_similarity_ratio_and_find_matches(embeddings1, embeddings2):
60
  try:
61
  similarities = np.dot(embeddings1, embeddings2.T) # Dot product
 
66
  st.error(f"Error calculating similarity ratio: {e}")
67
  return np.array([]), 0
68
 
69
+ @st.cache_data
70
  def calculate_word_similarity_ratio(text1, text2):
71
  try:
72
+ doc1 = nlp(text1)
73
+ doc2 = nlp(text2)
74
+ words1 = [token.text for token in doc1 if not token.is_stop and not token.is_punct]
75
+ words2 = [token.text for token in doc2 if not token.is_stop and not token.is_punct]
76
 
77
  if not words1 or not words2:
78
  return 0
 
81
  word_embeddings2 = model.encode(words2)
82
 
83
  similarities = np.array([
84
+ max([1 - cosine(emb1, emb2) for emb2 in word_embeddings2], default=0)
85
  for emb1 in word_embeddings1
86
  ])
87
 
 
91
  st.error(f"Error calculating word similarity ratio: {e}")
92
  return 0
93
 
94
+ @st.cache_data
95
  def calculate_bleu_score(reference, candidate):
96
+ from nltk.translate.bleu_score import sentence_bleu
97
  return sentence_bleu([reference.split()], candidate.split())
98
 
99
+ @st.cache_data
100
  def calculate_rouge_l_score(reference, candidate):
101
  scorer = rouge_scorer.RougeScorer(['rougeL'], use_stemmer=True)
102
  scores = scorer.score(reference, candidate)
103
  return scores['rougeL'].fmeasure * 100
104
 
105
+ @st.cache_data
106
  def calculate_bertscore(reference, candidate):
107
+ import bert_score
108
  P, R, F1 = bert_score.score([candidate], [reference], model_type='bert-base-uncased')
109
  return F1.mean().item() * 100
110
 
111
+ @st.cache_data
112
  def calculate_wmd(reference, candidate):
113
+ doc1 = nlp(reference.lower())
114
+ doc2 = nlp(candidate.lower())
115
+ reference_tokens = [token.text for token in doc1 if not token.is_stop and not token.is_punct]
116
+ candidate_tokens = [token.text for token in doc2 if not token.is_stop and not token.is_punct]
117
+ return word2vec_model.wmdistance(reference_tokens, candidate_tokens)
118
 
119
+ @st.cache_data
120
  def extract_pdf_text(pdf_file):
121
  try:
122
  reader = PyPDF2.PdfReader(pdf_file)
 
128
  st.error(f"Error extracting text from PDF: {e}")
129
  return ""
130
 
131
+ @st.cache_data
132
  def calculate_levenshtein_ratio(text1, text2):
133
  return SequenceMatcher(None, text1, text2).ratio()
134
 
135
+ @st.cache_data
136
  def calculate_jaccard_similarity(text1, text2):
137
+ from sklearn.feature_extraction.text import CountVectorizer
138
  vectorizer = CountVectorizer(binary=True).fit_transform([text1, text2])
139
  vectors = vectorizer.toarray()
 
140
  intersection = np.sum(np.minimum(vectors[0], vectors[1]))
141
  union = np.sum(np.maximum(vectors[0], vectors[1]))
142
  return intersection / union if union != 0 else 0
143
 
144
+ @st.cache_data
145
  def calculate_tfidf_cosine_similarity(text1, text2):
146
  tfidf_matrix = tfidf_vectorizer.fit_transform([text1, text2])
147
  return 1 - pairwise_distances(tfidf_matrix, metric='cosine')[0, 1]
148
 
149
+ @st.cache_data
150
+ def calculate_paraphrasing_similarity(text1, text2):
151
+ try:
152
+ chunks_1 = chunk_text(text1)
153
+ chunks_2 = chunk_text(text2)
154
+ embeddings_1 = create_embeddings(chunks_1)
155
+ embeddings_2 = create_embeddings(chunks_2)
156
+
157
+ if embeddings_1.size > 0 and embeddings_2.size > 0:
158
+ similarities, average_similarity = calculate_similarity_ratio_and_find_matches(embeddings_1, embeddings_2)
159
+ return average_similarity * 100
160
+ return 0
161
+ except Exception as e:
162
+ st.error(f"Error calculating paraphrasing similarity: {e}")
163
+ return 0
164
+
165
+ @st.cache_data
166
+ def calculate_direct_text_comparison_similarity(text1, text2):
167
+ try:
168
+ levenshtein_ratio = calculate_levenshtein_ratio(text1, text2) * 100
169
+ jaccard_similarity = calculate_jaccard_similarity(text1, text2) * 100
170
+ tfidf_cosine_similarity = calculate_tfidf_cosine_similarity(text1, text2) * 100
171
+ bleu_score = calculate_bleu_score(text1, text2) * 100
172
+ rouge_l_score = calculate_rouge_l_score(text1, text2)
173
+ bertscore = calculate_bertscore(text1, text2)
174
+
175
+ return (levenshtein_ratio * 0.1 + jaccard_similarity * 0.2 +
176
+ tfidf_cosine_similarity * 0.2 + bleu_score * 0.2 +
177
+ rouge_l_score * 0.2 + bertscore * 0.2) / 1.1
178
+ except Exception as e:
179
+ st.error(f"Error calculating direct text comparison similarity: {e}")
180
+ return 0
181
+
182
+ @st.cache_data
183
+ def calculate_summarization_similarity(text1, text2):
184
+ try:
185
+ wmd = calculate_wmd(text1, text2)
186
+ return (1 - wmd) * 100
187
+ except Exception as e:
188
+ st.error(f"Error calculating summarization similarity: {e}")
189
+ return 0
190
 
191
+ # Streamlit UI
192
  st.title("Text-Based Similarity Comparison")
193
 
194
+ # Create a two-column layout for input
195
+ col1, col2 = st.columns([2, 1])
196
 
197
  with col1:
198
+ st.sidebar.title("LLM Details")
199
+ llm1_name = st.sidebar.text_input("What is LLM1?", "LLM1")
200
+ llm2_name = st.sidebar.text_input("What is LLM2?", "LLM2")
201
+
202
+ st.write("## Input")
203
+
204
+ # Create two columns for text input
205
+ input_col1, input_col2 = st.columns(2)
206
+
207
+ with input_col1:
208
+ st.write(f"{llm1_name} response")
209
+ upload_pdf_1 = st.file_uploader(f"Upload PDF for {llm1_name} response", type="pdf", key="pdf1")
210
+ if upload_pdf_1:
211
+ text_input_1 = extract_pdf_text(upload_pdf_1)
212
+ else:
213
+ text_input_1 = st.text_area(f"Text for {llm1_name}", height=150, key="text1")
214
+
215
+ with input_col2:
216
+ st.write(f"{llm2_name} response")
217
+ upload_pdf_2 = st.file_uploader(f"Upload PDF for {llm2_name} response", type="pdf", key="pdf2")
218
+ if upload_pdf_2:
219
+ text_input_2 = extract_pdf_text(upload_pdf_2)
220
+ else:
221
+ text_input_2 = st.text_area(f"Text for {llm2_name}", height=150, key="text2")
222
 
223
+ if (text_input_1 and text_input_2) or (upload_pdf_1 and upload_pdf_2):
224
+ if st.button("Submit"):
225
+ # Calculate similarity metrics
226
+ paraphrasing_similarity = calculate_paraphrasing_similarity(text_input_1, text_input_2)
227
+ direct_text_comparison_similarity = calculate_direct_text_comparison_similarity(text_input_1, text_input_2)
228
+ summarization_similarity = calculate_summarization_similarity(text_input_1, text_input_2)
 
 
 
 
 
 
 
 
 
229
 
230
+ # Combine all metrics into a single similarity score
231
+ total_similarity = (paraphrasing_similarity * 0.33 +
232
+ direct_text_comparison_similarity * 0.33 +
233
+ summarization_similarity * 0.33)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
 
235
  # Update results table in session state
236
  new_row = pd.Series({
237
  "LLM1": llm1_name,
238
  "LLM2": llm2_name,
239
+ "Paraphrasing Similarity (%)": paraphrasing_similarity,
240
+ "Direct Text Comparison (%)": direct_text_comparison_similarity,
241
+ "Summarization Similarity (%)": summarization_similarity,
242
+ "Combined Similarity (%)": total_similarity
 
 
 
243
  })
 
244
  st.session_state.results_df = pd.concat([st.session_state.results_df, new_row.to_frame().T], ignore_index=True)
245
 
246
+ # Add new data for radar chart
247
+ st.session_state.radar_chart_data.append({
248
+ "name": f"{llm1_name} vs {llm2_name}",
249
+ "paraphrasing_similarity": paraphrasing_similarity,
250
+ "direct_text_comparison_similarity": direct_text_comparison_similarity,
251
+ "summarization_similarity": summarization_similarity
252
+ })
253
+
254
+ # Display metrics with large and bold text
255
  st.subheader("Results")
256
+ st.markdown(f"Paraphrasing Similarity: {paraphrasing_similarity:.2f}%", unsafe_allow_html=True)
257
+ st.markdown(f"Direct Text Comparison Similarity: {direct_text_comparison_similarity:.2f}%", unsafe_allow_html=True)
258
+ st.markdown(f"Summarization Similarity: {summarization_similarity:.2f}%", unsafe_allow_html=True)
259
+ st.markdown(f"Combined Similarity Score: {total_similarity:.2f}%", unsafe_allow_html=True)
260
+
261
+ with col2:
262
+ st.write("## Metrics and Results")
263
+
264
+ # Display radar chart
265
+ if st.session_state.radar_chart_data:
266
+ st.subheader("Metrics Comparison")
267
+ labels = ["Paraphrasing Similarity", "Direct Text Comparison Similarity", "Summarization Similarity"]
268
+ num_vars = len(labels)
269
+ angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()
270
+ angles += angles[:1]
271
+
272
+ fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
273
+
274
+ # Plot each response with a different color
275
+ color_palette = sns.color_palette("husl", len(st.session_state.radar_chart_data))
276
+ for idx, data in enumerate(st.session_state.radar_chart_data):
277
+ values = [
278
+ data["paraphrasing_similarity"],
279
+ data["direct_text_comparison_similarity"],
280
+ data["summarization_similarity"]
281
+ ]
282
+ values += values[:1]
283
+ ax.fill(angles, values, color=color_palette[idx], alpha=0.25, label=data["name"])
284
+ ax.plot(angles, values, color=color_palette[idx], linewidth=2, linestyle='solid')
285
+
286
+ ax.set_yticklabels([])
287
+ ax.set_xticks(angles[:-1])
288
+ ax.set_xticklabels(labels)
289
+ plt.title("Radar Chart of Similarity Metrics")
290
+ plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
291
+ st.pyplot(fig)
292
+
293
+ # Display metrics sliders beside the radar chart
294
+ if st.session_state.radar_chart_data:
295
+ st.subheader("Metrics Position")
296
+ metrics = st.session_state.radar_chart_data[-1]
297
+ for metric_name in ["paraphrasing_similarity", "direct_text_comparison_similarity", "summarization_similarity"]:
298
+ st.slider(
299
+ metric_name.replace("_", " ").title(),
300
+ 0, 100,
301
+ int(metrics[metric_name]),
302
+ key=metric_name,
303
+ disabled=True, # Make the slider non-editable
304
+ format="%.0f" # Format the slider value to be an integer
305
+ )
306
+
307
+ # Create a three-column layout for the results table and action buttons
308
+ results_col, actions_col = st.columns([2, 1])
309
+
310
+ with results_col:
311
+ st.write("## Detailed Results Table")
312
+ if not st.session_state.results_df.empty:
313
+ st.write(st.session_state.results_df)
314
+
315
+ # Download the results as a CSV file
316
+ csv_data = st.session_state.results_df.to_csv(index=False).encode('utf-8')
317
+ st.download_button(label="Download Results as CSV", data=csv_data, file_name='similarity_results.csv', mime='text/csv')
318
+
319
+ with actions_col:
320
+ if st.button("Reset Table"):
321
+ st.session_state.results_df = pd.DataFrame(columns=[
322
+ "LLM1", "LLM2", "Paraphrasing Similarity (%)",
323
+ "Direct Text Comparison (%)", "Summarization Similarity (%)",
324
+ "Combined Similarity (%)"
325
+ ])
326
+ st.session_state.radar_chart_data = []
327
+ st.write("Results table has been reset.")