|
|
import gradio as gr |
|
|
import pandas as pd |
|
|
import matplotlib.pyplot as plt |
|
|
from transformers import pipeline |
|
|
|
|
|
|
|
|
pipe = pipeline("text-classification", model="cardiffnlp/twitter-roberta-base-sentiment-latest") |
|
|
|
|
|
|
|
|
def process_csv(file): |
|
|
df = pd.read_csv(file.name) |
|
|
departments = ['All'] + df['Department'].unique().tolist() |
|
|
questions = ['All'] + df['Question'].unique().tolist() |
|
|
return gr.update(choices=departments), gr.update(choices=questions) |
|
|
|
|
|
|
|
|
def get_analysis(department, question, file): |
|
|
df = pd.read_csv(file.name) |
|
|
|
|
|
|
|
|
if department != 'All': |
|
|
df = df[df['Department'] == department] |
|
|
if question != 'All': |
|
|
df = df[df['Question'] == question] |
|
|
|
|
|
|
|
|
df['Sentiment'] = df['Feedback'].apply(lambda x: pipe(x)[0]['label']) |
|
|
|
|
|
|
|
|
employee_counts = df.groupby('Department')['Employee'].nunique().reset_index() |
|
|
employee_counts.columns = ['Department', 'Total Employees'] |
|
|
|
|
|
|
|
|
sentiment_counts = df.groupby(['Department', 'Sentiment']).size().unstack(fill_value=0) |
|
|
sentiment_counts = sentiment_counts.reindex(columns=['positive', 'neutral', 'negative'], fill_value=0) |
|
|
|
|
|
|
|
|
summary_df = employee_counts.merge(sentiment_counts, on="Department", how="left") |
|
|
|
|
|
|
|
|
total_row = pd.DataFrame({ |
|
|
'Department': ['Total'], |
|
|
'Total Employees': [df['Employee'].nunique()], |
|
|
'positive': [summary_df['positive'].sum()], |
|
|
'neutral': [summary_df['neutral'].sum()], |
|
|
'negative': [summary_df['negative'].sum()] |
|
|
}) |
|
|
|
|
|
summary_df = pd.concat([summary_df, total_row], ignore_index=True) |
|
|
|
|
|
|
|
|
def generate_html_table(df): |
|
|
html = """<style> |
|
|
table {width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; text-align: center;} |
|
|
th {background-color: gray; padding: 10px;} |
|
|
td, th {border: 1px solid #ddd; padding: 8px;} |
|
|
tr:nth-child(even) {background-color: #f2f2f2;} |
|
|
.total {background-color: lightgray; font-weight: bold;} |
|
|
.positive {color: green; font-weight: bold;} |
|
|
.neutral {color: gray; font-weight: bold;} |
|
|
.negative {color: red; font-weight: bold;} |
|
|
</style> |
|
|
<table> |
|
|
<tr> |
|
|
<th>Department</th><th>Total Employees</th> |
|
|
<th>Positive</th><th>Neutral</th><th>Negative</th> |
|
|
</tr>""" |
|
|
for _, row in df.iterrows(): |
|
|
row_class = "total" if row["Department"] == "Total" else "" |
|
|
html += f""" |
|
|
<tr class="{row_class}"> |
|
|
<td>{row["Department"]}</td> |
|
|
<td>{row["Total Employees"]}</td> |
|
|
<td class="positive">{row["positive"]}</td> |
|
|
<td class="neutral">{row["neutral"]}</td> |
|
|
<td class="negative">{row["negative"]}</td> |
|
|
</tr>""" |
|
|
html += "</table>" |
|
|
return html |
|
|
|
|
|
table_html = generate_html_table(summary_df) |
|
|
|
|
|
|
|
|
plt.figure(figsize=(10, 6)) |
|
|
sentiment_counts.plot(kind='bar', stacked=False, color=['green', 'gray', 'red'], width=0.6) |
|
|
plt.xlabel("Department") |
|
|
plt.ylabel("Count") |
|
|
plt.title("Department-wise Sentiment Analysis") |
|
|
plt.xticks(rotation=45) |
|
|
plt.legend(title="Sentiment", loc="upper right") |
|
|
plt.grid(axis='y', linestyle='--', alpha=0.7) |
|
|
plt.tight_layout() |
|
|
|
|
|
return table_html, plt.gcf() |
|
|
|
|
|
|
|
|
with gr.Blocks() as demo: |
|
|
gr.Markdown(""" |
|
|
<h1 style="font-size: 36px; text-align: center;">Employee Sentiment Analysis</h1> |
|
|
""") |
|
|
|
|
|
file_input = gr.File(label="Upload CSV", file_types=[".csv"]) |
|
|
process_button = gr.Button("Process CSV") |
|
|
|
|
|
dept_dropdown = gr.Dropdown(label="Department", choices=["All"], interactive=True) |
|
|
question_dropdown = gr.Dropdown(label="Question", choices=["All"], interactive=True) |
|
|
|
|
|
analyze_button = gr.Button("Get Analysis") |
|
|
|
|
|
output_table = gr.HTML(label="Department-wise Sentiment Summary") |
|
|
output_plot = gr.Plot(label="Department-wise Sentiment Distribution") |
|
|
|
|
|
process_button.click(process_csv, inputs=file_input, outputs=[dept_dropdown, question_dropdown]) |
|
|
analyze_button.click(get_analysis, inputs=[dept_dropdown, question_dropdown, file_input], outputs=[output_table, output_plot]) |
|
|
|
|
|
demo.launch(share=True) |
|
|
|