Spaces:
Paused
Paused
File size: 13,955 Bytes
ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e 9d38733 ff47c9e e4fe207 7f80a20 e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e aec2e12 ff47c9e e4fe207 ff47c9e e4fe207 ff47c9e e4fe207 aec2e12 e4fe207 aec2e12 e4fe207 aec2e12 e4fe207 aec2e12 e4fe207 aec2e12 e4fe207 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# import gspread
import pandas as pd
# from oauth2client.service_account import ServiceAccountCredentials
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch
import re
import streamlit as st
import hydralit_components as hc
from matplotlib import pyplot as plt
# import numpy as np
from wordcloud import WordCloud
import plotly.graph_objs as go
# import plotly.express as px
# import plotly.figure_factory as ff
# from PIL import ImageFont
# from app5_selectbox.langchain_llama_gpu import llm_chain
from app5_selectbox.g4f_prompt import g4f_prompt
# from app5_selectbox.llama2_prompt import llama_prompt
from app5_selectbox.naive_bayes_cl import nb_clf
# from HF_inference import analyze_sintement
from HF_pipeline import analyze_sintement
models = ['BERT-BASE MODEL', 'BERT-LARGE MODEL', 'DISTILIBERT MODEL', 'NAIVE BAYES MODEL']
# old path
# model_list = [
# r"/home/aibo/prototype_v1/BERT_BASE/bert_sentiment_model",
# r"/home/aibo/prototype_v1/BERT_LARGE/bert_sentiment_model",
# r"/home/aibo/prototype_v1/DISTILIBERT/bert_sentiment_model"
# ]
# new path
model_list = [
r"/home/aibo/prototype_v1/HF_MODELS/HUB/stud-fac-eval-bert-base-uncased",
r"/home/aibo/prototype_v1/HF_MODELS/HUB/stud-fac-eval-bert-large-uncased",
r"/home/aibo/prototype_v1/HF_MODELS/HUB/stud-fac-eval-distilbert-base-uncased",
]
model_tokenizer_list = ['bert-base-uncased', 'bert-large-uncased', 'distilbert-base-uncased']
selected_model = 0
llama2_g4f = False # true == llama2
# if 'chkbx_selected_model' in st.session_state:
# st.write("selected model: ",models.index(st.session_state.chkbx_selected_model))
# if 'chkbx_selected_model' not in st.session_state:
# st.write("no selected!")
def clean_text(text_list):
cleaned_samples = []
for text_sample in text_list:
# Case folding and normalization
cleaned_text = str(text_sample).lower()
# Removing non-alphabetic characters
cleaned_text = re.sub(r'[^a-zA-Z\s]', '', cleaned_text)
cleaned_samples.append(cleaned_text)
return cleaned_samples
# # local model
# def classify_sentiments(text_samples, tokenizer, model):
# instructor_comments = []
# predicted_sentiments = []
# predicted_sentiments_scores = []
# # Iterate through the text samples and classify the sentiment
# for idx, text_sample in enumerate(text_samples):
# # Tokenize the text sample
# inputs = tokenizer(text_sample, return_tensors="pt")
# # Perform sentiment classification
# outputs = model(**inputs)
# # Get the predicted sentiment (positive/negative)
# predicted_class = torch.argmax(outputs.logits, dim=1).item()
# # Get the probabilities for each class
# probabilities = torch.softmax(outputs.logits, dim=1).tolist()[0]
# # Store results
# instructor_comments.append(text_sample)
# predicted_sentiments.append("positive" if predicted_class == 1 else "negative")
# predicted_sentiments_scores.append({"positive": probabilities[1]*100, "negative": probabilities[0]*100})
# return instructor_comments, predicted_sentiments, predicted_sentiments_scores
# inference
def classify_sentiments(text_samples, model):
instructor_comments = []
predicted_sentiments = []
predicted_sentiments_scores = []
# text = ["i love this", "nice one!", "happy!"]
selected_model = model
results = [analyze_sintement(t, selected_model) for t in text_samples]
for idx, result in enumerate(results):
# st.text(result[0])
# predicted_class, probabilities = analyze_sintement(text_sample, model)
# Store results
instructor_comments.append(text_samples[idx])
predicted_sentiments.append("positive" if result[0] == "LABEL_1" else "negative")
predicted_sentiments_scores.append({"positive": result[1]*100, "negative": 100-(result[1]*100)})
# st.write(instructor_comments)
return instructor_comments, predicted_sentiments, predicted_sentiments_scores
def calculate_average_scores(probability_list):
total_comments = len(probability_list)
total_positive = 0
total_negative = 0
for prob_dict in probability_list:
total_positive += prob_dict['positive']
total_negative += prob_dict['negative']
average_positive = total_positive / total_comments
average_negative = total_negative / total_comments
return average_positive, average_negative
def eval_analysis(instructor, instructor_comment, criteria_results, selected_model):
if selected_model < 3:
## local model
# model = model_list[selected_model]
# model_tokenizer = model_tokenizer_list[selected_model]
# model_tokenizer = model_list[selected_model]
# loaded_model = AutoModelForSequenceClassification.from_pretrained(model)
# tokenizer = AutoTokenizer.from_pretrained(model_tokenizer)
clean_instructor_comment = clean_text(instructor_comment)
# print(models[selected_model])
# predicted_sentiments_transformer = classify_sentiments(clean_instructor_comment, tokenizer, loaded_model) # local model
predicted_sentiments_transformer = classify_sentiments(clean_instructor_comment, models[selected_model]) # inference
predicted_sentiments = predicted_sentiments_transformer[1]
scores = predicted_sentiments_transformer[2]
elif selected_model == 3:
try:
instructor_comment, predicted_sentiments, scores = nb_clf(instructor_comment)
# scores = scores[1]
except Exception as e:
st.exception(e)
else: pass
sample_predictions = []
comments_data = []
negative_count = 0
neutral_count = 0
positive_count = 0
# average_sintement_score = np.average(scores['positive'])
average_positive, average_negative = calculate_average_scores(scores)
# st.text(calculate_average_scores(scores))
for text, prediction, score in zip(instructor_comment, predicted_sentiments, scores):
sample_predictions.append(prediction)
comments_data.append((text, prediction, score['positive']))
if prediction == "negative":
negative_count += 1
elif prediction == "neutral":
neutral_count += 1
else:
positive_count += 1
sentiment_texts = {
'positive': [],
'negative': []
}
for text, sentiment in zip(instructor_comment, sample_predictions):
sentiment_texts[sentiment].append(text)
text_for_llama = ""
def sentiment_tbl():
# Create DataFrame
comments_df = pd.DataFrame(instructor_comment, columns=["Comments"])
# Drop index
comments_df_display = comments_df.copy()
comments_df_display.reset_index(drop=True, inplace=True)
# Create DataFrame
comments_data_df = pd.DataFrame(comments_data, columns=["Comments", "Sentiment", "Score"])
# Define a function to apply row-wise styling
def highlight_row(row):
if row["Sentiment"] == "positive":
return ['background-color: lightgreen'] * len(row)
elif row["Sentiment"] == "negative":
return ['background-color: lightcoral'] * len(row)
else:
return [''] * len(row)
# Set index to start at 1
comments_data_df.index += 1
# Apply styling
styled_df = comments_data_df.style.apply(highlight_row, axis=1)
# Display styled DataFrame
st.table(styled_df)
theme_bad = {'bgcolor': '#FFF0F0','title_color': 'red','content_color': 'red','icon_color': 'red', 'icon': 'fa fa-times-circle'}
theme_good = {'bgcolor': '#EFF8F7','title_color': 'green','content_color': 'green','icon_color': 'green', 'icon': 'fa fa-check-circle'}
st.write(f"### SENTIMENTS/RECOMENDATION INSIGHTS")
with st.expander("Sentiment Analysis"):
st.title("Sentiment Analysis Dashboard")
st.write(f"## Using {models[selected_model]}")
st.write("### Sentiment Rating")
cc = st.columns(2)
with cc[0]:
# can just use 'good', 'bad', 'neutral' sentiment to auto color the card
hc.info_card(title='Positive', content=str(round(average_positive,6))+ '%', sentiment='good', bar_value=round(average_positive,6))
with cc[1]:
hc.info_card(title='Negative', content=str(round(average_negative,6))+ '%', sentiment='bad', bar_value=round(average_negative,6))
# st.write(f"#### Positive: {positive_count} - {round(average_positive,6)} %")
# st.write(f"#### Negative: {negative_count} - {round(average_negative,6)} %")
# st.write("### Sentiment Rating")
# st.write(f"#### Positive: {round(average_positive*100,2)} %")
# st.write(f"#### Negative: {round(average_negative*100,2)} %")
sentiment_counts = pd.Series(sample_predictions).value_counts()
desired_order = ['positive', 'negative']
sentiment_counts = sentiment_counts.reindex(desired_order, fill_value=0)
percentage_distribution = sentiment_counts / len(sample_predictions) * 100
sentiment_tbl()
st.write("### Sentiment Distribution")
fig = go.Figure(layout=dict(
autosize=True, # Set autosize to True for automatic adjustment
))
fig.add_trace(go.Bar(
x=percentage_distribution.index,
y=sentiment_counts.values,
marker_color=['green', 'red'],
text=[f'{percentage:.2f}% {des_order.upper()}' for percentage, des_order in zip(percentage_distribution, desired_order)],
textposition='auto'
))
fig.update_layout(
width=600,
height=500,
xaxis=dict(title='Sentiment', tickangle=45),
yaxis=dict(title='Count'),
title='Sentiment Distribution in Sample Predictions',
)
st.plotly_chart(fig)
for sentiment, texts in sentiment_texts.items():
combined_texts = ' '.join(texts)
combined_texts = combined_texts.split()
filtered_words = [word for word in combined_texts if len(word) > 2]
combined_texts = ' '.join(filtered_words)
if combined_texts == "":
continue
font_path = "/home/aibo/prototype_v1/prototype/app5_selectbox/QuartzoBold-W9lv.ttf"
wordcloud = WordCloud(font_path=font_path, width=800, height=600, background_color='white', max_words=15, min_word_length=3, stopwords={}).generate(combined_texts)
st.write(f"### Word Cloud for {sentiment.capitalize()} Sentiment")
plt.figure(figsize=(10, 6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
wordcloud_fig = plt.gcf()
st.pyplot(wordcloud_fig)
if sentiment == "negative":
text_for_llama = sentiment_texts[sentiment]
# Generate a word cloud from all the text data
all_text = ' '.join(instructor_comment)
all_text = all_text.split()
filtered_words = [word for word in all_text if len(word) > 2]
all_text = ' '.join(filtered_words)
st.write("### Word Cloud for All Sentiments")
wordcloud = WordCloud(font_path=font_path, width=800, height=800, background_color='white', max_words=200, min_word_length=3, stopwords={}).generate(all_text)
# Create a Matplotlib figure
plt.figure(figsize=(8, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
wordcloud_fig = plt.gcf()
st.pyplot(wordcloud_fig)
if text_for_llama == "":
with st.expander("Expressing Gratitude and Dedication"):
st.title("Expressing Gratitude and Dedication")
text_for_llama = f"""
There's no negative feedback or comment for the instructor; give him or her a short letter to say.
[Your Name] = The Management
[Instructor's Name] = {instructor}
"""
prompt = text_for_llama
while True:
try:
with st.spinner("Generating...."):
# if not llama2_g4f: st.write(g4f_prompt(prompt)) #################
# else: st.write(llama_prompt(prompt)) #################
st.success("Generation Complete!")
break
except Exception as e:
pass
else:
with st.expander("Recommendation"):
# st.title('Recommendation:')
# text_for_llama = text_for_llama.split()
text_for_llama = ", ".join(text_for_llama)
text_for_llama = f"""
Based on these students' feedback: {str(text_for_llama)}. \n
Please generate a short letter to the instructor with ten recommendations in bullet format. Make it in sentence type and English only.
Define the best letter's subject based on the recommendation.
Subject is Recommendations for Effective Teaching
Sender's Name is 'The Management'
receiver's or Instructor's Name is {instructor}
"""
prompt = text_for_llama
while True:
try:
with st.spinner("Generating...."):
# if not llama2_g4f: st.write(g4f_prompt(prompt)) #################
# else: st.write(llama_prompt(prompt)) #################
st.success("Generation Complete!")
break
except Exception as e:
pass |