| from transformers import AutoTokenizer, AutoModelForSeq2SeqLM, AutoModelForSequenceClassification, TextClassificationPipeline |
| import torch |
| import gradio as gr |
| from openpyxl import load_workbook |
| from numpy import mean |
| import pandas as pd |
| import matplotlib.pyplot as plt |
|
|
| theme = gr.themes.Soft( |
| primary_hue="amber", |
| secondary_hue="amber", |
| neutral_hue="stone", |
| ) |
|
|
| |
| tokenizer = AutoTokenizer.from_pretrained("suriya7/bart-finetuned-text-summarization") |
| model = AutoModelForSeq2SeqLM.from_pretrained("suriya7/bart-finetuned-text-summarization") |
|
|
| tokenizer_keywords = AutoTokenizer.from_pretrained("transformer3/H2-keywordextractor") |
| model_keywords = AutoModelForSeq2SeqLM.from_pretrained("transformer3/H2-keywordextractor") |
|
|
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") |
| new_model = AutoModelForSequenceClassification.from_pretrained('roberta-rating') |
| new_tokenizer = AutoTokenizer.from_pretrained('roberta-rating') |
|
|
| classifier = TextClassificationPipeline(model=new_model, tokenizer=new_tokenizer, device=device) |
|
|
| label_mapping = {1: '1/5', 2: '2/5', 3: '3/5', 4: '4/5', 5: '5/5'} |
|
|
| |
| def filter_xl(file, keywords): |
| |
| workbook = load_workbook(filename=file) |
| sheet = workbook.active |
| data = sheet.values |
| columns = next(data)[0:] |
| df = pd.DataFrame(data, columns=columns) |
| |
| if keywords: |
| keyword_list = keywords.split(',') |
| for keyword in keyword_list: |
| df = df[df.apply(lambda row: row.astype(str).str.contains(keyword.strip(), case=False).any(), axis=1)] |
| |
| return df |
|
|
| |
| def calculate_rating(filtered_df): |
| reviews = filtered_df.to_numpy().flatten() |
| ratings = [] |
| for review in reviews: |
| if pd.notna(review): |
| rating = int(classifier(review)[0]['label'].split('_')[1]) |
| ratings.append(rating) |
| |
| return round(mean(ratings), 2), ratings |
|
|
| |
| def calculate_results(file, keywords): |
| filtered_df = filter_xl(file, keywords) |
| overall_rating, ratings = calculate_rating(filtered_df) |
| |
| |
| text = " ".join(filtered_df.to_numpy().flatten()) |
| inputs = tokenizer([text], max_length=1024, truncation=True, return_tensors="pt") |
| summary_ids = model.generate(inputs["input_ids"], num_beams=2, min_length=10, max_length=50) |
| summary = tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] |
| summary = summary.replace("I", "They").replace("my", "their").replace("me", "them") |
|
|
| inputs_keywords = tokenizer_keywords([text], max_length=1024, truncation=True, return_tensors="pt") |
| summary_ids_keywords = model_keywords.generate(inputs_keywords["input_ids"], num_beams=2, min_length=0, max_length=100) |
| keywords = tokenizer_keywords.batch_decode(summary_ids_keywords, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] |
|
|
| |
| sentiments = [] |
| for review in filtered_df.to_numpy().flatten(): |
| if pd.notna(review): |
| sentiment = classifier(review)[0]['label'] |
| sentiment_label = "Positive" if sentiment == "LABEL_4" or sentiment == "LABEL_5" else "Negative" if sentiment == "LABEL_1" or sentiment == "LABEL_2" else "Neutral" |
| sentiments.append(sentiment_label) |
| |
| overall_sentiment = "Positive" if sentiments.count("Positive") > sentiments.count("Negative") else "Negative" if sentiments.count("Negative") > sentiments.count("Positive") else "Neutral" |
|
|
| return overall_rating, summary, keywords, overall_sentiment, ratings, sentiments |
|
|
| |
| def analyze_review(review): |
| if not review.strip(): |
| return "Error: No text provided", "Error: No text provided", "Error: No text provided", "Error: No text provided" |
| |
| |
| rating = int(classifier(review)[0]['label'].split('_')[1]) |
| |
| |
| inputs = tokenizer([review], max_length=1024, truncation=True, return_tensors="pt") |
| summary_ids = model.generate(inputs["input_ids"], num_beams=2, min_length=10, max_length=50) |
| summary = tokenizer.batch_decode(summary_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] |
| summary = summary.replace("I", "he/she").replace("my", "his/her").replace("me", "him/her") |
|
|
| |
| inputs_keywords = tokenizer_keywords([review], max_length=1024, truncation=True, return_tensors="pt") |
| summary_ids_keywords = model_keywords.generate(inputs_keywords["input_ids"], num_beams=2, min_length=0, max_length=100) |
| keywords = tokenizer_keywords.batch_decode(summary_ids_keywords, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0] |
|
|
| |
| sentiment = classifier(review)[0]['label'] |
| sentiment_label = "Positive" if sentiment == "LABEL_4" or sentiment == "LABEL_5" else "Negative" if sentiment == "LABEL_1" or sentiment == "LABEL_2" else "Neutral" |
|
|
| return rating, summary, keywords, sentiment_label |
|
|
| |
| def count_rows(filtered_df): |
| return len(filtered_df) |
|
|
| |
| def plot_ratings(ratings): |
| plt.figure(figsize=(10, 5)) |
| plt.hist(ratings, bins=range(1, 7), edgecolor='black', align='left') |
| plt.xlabel('Rating') |
| plt.ylabel('Frequency') |
| plt.title('Distribution of Ratings') |
| plt.xticks(range(1, 6)) |
| plt.grid(True) |
| plt.savefig('ratings_distribution.png') |
| return 'ratings_distribution.png' |
|
|
| |
| def plot_sentiments(sentiments): |
| sentiment_counts = pd.Series(sentiments).value_counts() |
| plt.figure(figsize=(10, 5)) |
| sentiment_counts.plot(kind='bar', color=['green', 'red', 'blue']) |
| plt.xlabel('Sentiment') |
| plt.ylabel('Frequency') |
| plt.title('Distribution of Sentiments') |
| plt.grid(True) |
| plt.savefig('sentiments_distribution.png') |
| return 'sentiments_distribution.png' |
|
|
| |
| with gr.Blocks(theme=theme) as demo: |
| gr.Markdown("<h1 style='text-align: center;'>Feedback and Auditing Survey AI Analyzer</h1><br>") |
| with gr.Tabs(): |
| with gr.TabItem("Upload and Filter"): |
| with gr.Row(): |
| with gr.Column(scale=1): |
| excel_file = gr.File(label="Upload Excel File") |
| |
| keywords_input = gr.Textbox(label="Filter by Keywords (comma-separated)") |
| display_button = gr.Button("Display and Filter Excel Data") |
| clear_button_upload = gr.Button("Clear") |
| row_count = gr.Textbox(label="Number of Rows", interactive=False) |
| with gr.Column(scale=3): |
| filtered_data = gr.Dataframe(label="Filtered Excel Contents") |
| |
| with gr.TabItem("Calculate Results"): |
| with gr.Row(): |
| with gr.Column(): |
| overall_rating = gr.Textbox(label="Overall Rating") |
| summary = gr.Textbox(label="Summary") |
| keywords_output = gr.Textbox(label="Keywords") |
| overall_sentiment = gr.Textbox(label="Overall Sentiment") |
| calculate_button = gr.Button("Calculate Results") |
| with gr.Column(): |
| ratings_graph = gr.Image(label="Ratings Distribution") |
| sentiments_graph = gr.Image(label="Sentiments Distribution") |
| calculate_graph_button = gr.Button("Calculate Graph Results") |
| |
| with gr.TabItem("Testing Area / Write a Review"): |
| with gr.Row(): |
| with gr.Column(scale=2): |
| review_input = gr.Textbox(label="Write your review here") |
| analyze_button = gr.Button("Analyze Review") |
| clear_button_review = gr.Button("Clear") |
| with gr.Column(scale=2): |
| review_rating = gr.Textbox(label="Rating") |
| review_summary = gr.Textbox(label="Summary") |
| review_keywords = gr.Textbox(label="Keywords") |
| review_sentiment = gr.Textbox(label="Sentiment") |
|
|
| display_button.click(lambda file, keywords: (filter_xl(file, keywords), count_rows(filter_xl(file, keywords))), inputs=[excel_file, keywords_input], outputs=[filtered_data, row_count]) |
| calculate_graph_button.click(lambda file, keywords: (*calculate_results(file, keywords)[:4], plot_ratings(calculate_results(file, keywords)[4]), plot_sentiments(calculate_results(file, keywords)[5])), inputs=[excel_file, keywords_input], outputs=[overall_rating, summary, keywords_output, overall_sentiment, ratings_graph, sentiments_graph]) |
| calculate_button.click(lambda file, keywords: (*calculate_results(file, keywords)[:4], plot_ratings(calculate_results(file, keywords)[4])), inputs=[excel_file, keywords_input], outputs=[overall_rating, summary, keywords_output, overall_sentiment]) |
| analyze_button.click(analyze_review, inputs=review_input, outputs=[review_rating, review_summary, review_keywords, review_sentiment]) |
| clear_button_upload.click(lambda: (""), outputs=[keywords_input]) |
| clear_button_review.click(lambda: ("", "", "", "", ""), outputs=[review_input, review_rating, review_summary, review_keywords, review_sentiment]) |
|
|
| demo.launch(share=True) |