Carmelob92 commited on
Commit
0e6c5ba
·
verified ·
1 Parent(s): acd137a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -155
app.py CHANGED
@@ -1,175 +1,93 @@
1
  import gradio as gr
2
  import pandas as pd
3
- import numpy as np
4
- import matplotlib.pyplot as plt
5
- from transformers import pipeline
6
  import io
7
- from PIL import Image
8
-
9
- # Caricamento del modello (avverrà quando l'app si avvia)
10
- sentiment_analyzer = pipeline(
11
- "sentiment-analysis",
12
- model="nlptown/bert-base-multilingual-uncased-sentiment"
13
- )
14
-
15
- def analyze_text(text):
16
- """Analizza un singolo testo e restituisce il sentiment"""
17
- result = sentiment_analyzer(text)[0]
18
- rating = int(result['label'].split()[0])
19
-
20
- # Classificazione
21
- if rating > 3:
22
- sentiment = "Positivo"
23
- elif rating < 3:
24
- sentiment = "Negativo"
25
- else:
26
- sentiment = "Neutro"
27
-
28
- return f"Sentiment: {sentiment} (Valutazione: {rating}/5)"
29
 
30
- def analyze_file(file):
31
- """Analizza i commenti da un file CSV o Excel caricato dall'utente"""
32
- try:
33
- # Leggi il file caricato
34
- if file.name.endswith('.csv'):
35
- df = pd.read_csv(file.name)
36
- elif file.name.endswith(('.xlsx', '.xls')):
37
- df = pd.read_excel(file.name)
38
- else:
39
- return "Errore: Formato file non supportato. Usa CSV o Excel.", None, None
40
-
41
- # Mostra le prime 5 righe per permettere all'utente di scegliere la colonna
42
- preview = df.head().to_string()
43
- return "File caricato con successo. Ecco un'anteprima:\n\n" + preview, df, list(df.columns)
44
- except Exception as e:
45
- return f"Errore nell'elaborazione del file: {str(e)}", None, None
46
 
47
- def process_column(df, column_name, max_samples=100):
48
- """Elabora la colonna selezionata"""
49
- if df is None:
50
- return "Errore: Carica prima un file valido.", None, "Nessun risultato disponibile.", None
51
-
52
- if not column_name or column_name not in df.columns:
53
- return "Errore: Seleziona una colonna valida.", None, "Nessun risultato disponibile.", None
54
-
55
- # Limitazione dei campioni
56
- if len(df) > max_samples:
57
- df_sample = df.sample(max_samples, random_state=42)
58
- else:
59
- df_sample = df
60
-
61
- # Estrai i testi
62
- texts = df_sample[column_name].dropna().astype(str).tolist()
63
-
64
- if not texts:
65
- return "Errore: La colonna selezionata non contiene dati validi.", None, "Nessun risultato disponibile.", None
66
-
67
- # Analisi dei testi
68
  results = []
69
- progress_text = "Elaborazione in corso...\n"
 
70
 
 
71
  for i, text in enumerate(texts):
72
- # Analisi
73
- sentiment = sentiment_analyzer(text)
74
- rating = int(sentiment[0]['label'].split()[0])
75
 
76
- # Classificazione
77
  if rating > 3:
78
- sentiment_class = "Positivo"
79
  elif rating < 3:
80
- sentiment_class = "Negativo"
81
  else:
82
- sentiment_class = "Neutro"
83
-
84
- results.append({
85
- 'testo': text[:100] + "..." if len(text) > 100 else text,
86
- 'rating': rating,
87
- 'sentiment': sentiment_class
88
- })
89
-
90
- if i % 10 == 0:
91
- progress_text += f"Completato {i}/{len(texts)} testi\n"
92
-
93
- # Crea DataFrame con i risultati
94
- results_df = pd.DataFrame(results)
95
 
96
- # Crea grafico
97
- plt.figure(figsize=(10, 6))
98
- sentiment_counts = results_df['sentiment'].value_counts()
99
- colors = {'Positivo': 'green', 'Neutro': 'gray', 'Negativo': 'red'}
100
- sentiment_counts.plot(kind='bar', color=[colors.get(x, 'blue') for x in sentiment_counts.index])
101
- plt.title('Distribuzione del Sentiment')
102
- plt.xlabel('Sentiment')
103
- plt.ylabel('Numero di commenti')
104
- plt.tight_layout()
105
-
106
- # Salva il grafico in un buffer
107
- buf = io.BytesIO()
108
- plt.savefig(buf, format='png')
109
- buf.seek(0)
110
- img = Image.open(buf)
111
-
112
- # Genera statistiche
113
- stats = f"""
114
- ### Risultati dell'analisi:
115
-
116
- - **Totale commenti analizzati:** {len(results_df)}
117
- - **Commenti positivi:** {len(results_df[results_df['sentiment'] == 'Positivo'])} ({len(results_df[results_df['sentiment'] == 'Positivo'])/len(results_df)*100:.1f}%)
118
- - **Commenti neutri:** {len(results_df[results_df['sentiment'] == 'Neutro'])} ({len(results_df[results_df['sentiment'] == 'Neutro'])/len(results_df)*100:.1f}%)
119
- - **Commenti negativi:** {len(results_df[results_df['sentiment'] == 'Negativo'])} ({len(results_df[results_df['sentiment'] == 'Negativo'])/len(results_df)*100:.1f}%)
120
- - **Rating medio:** {results_df['rating'].mean():.2f}/5
121
- """
122
-
123
- # Create CSV download link
124
- csv_data = results_df.to_csv(index=False)
125
-
126
- return progress_text + "\nAnalisi completata!", img, stats, csv_data
127
 
128
- # Definizione dell'interfaccia Gradio
129
- with gr.Blocks(title="Analisi Sentiment Multilingua") as demo:
130
- gr.Markdown("# 📊 Analisi del Sentiment Multilingua")
131
- gr.Markdown("Questa app analizza il sentiment di testi in diverse lingue utilizzando un modello BERT multilingua.")
132
-
133
- with gr.Tab("Analisi di un testo"):
134
- gr.Markdown("### Inserisci un testo da analizzare")
135
- with gr.Row():
136
- text_input = gr.Textbox(lines=5, placeholder="Scrivi o incolla il testo qui...")
137
- analyze_button = gr.Button("Analizza Sentiment")
138
- result_output = gr.Textbox(label="Risultato")
139
- analyze_button.click(analyze_text, inputs=text_input, outputs=result_output)
140
-
141
- with gr.Tab("Analisi di file CSV/Excel"):
142
- gr.Markdown("### Carica un file con commenti da analizzare")
143
- with gr.Row():
144
- file_input = gr.File(label="Carica file CSV o Excel")
145
-
146
- upload_button = gr.Button("Carica File")
147
- preview_output = gr.Textbox(label="Anteprima del file")
148
-
149
- # Variabili nascoste per memorizzare il dataframe
150
- df_state = gr.State()
151
- columns_state = gr.State()
152
-
153
- upload_button.click(analyze_file, inputs=file_input, outputs=[preview_output, df_state, columns_state])
154
 
155
- with gr.Row():
156
- column_select = gr.Dropdown(label="Seleziona la colonna con i testi da analizzare")
 
 
 
 
157
 
158
- # Aggiornamento dropdown quando cambia columns_state
159
- columns_state.change(lambda cols: gr.Dropdown.update(choices=cols if cols else []), inputs=columns_state, outputs=column_select)
160
 
161
- process_button = gr.Button("Analizza Sentiment")
162
- progress_output = gr.Textbox(label="Stato elaborazione")
163
- chart_output = gr.Image(label="Distribuzione del sentiment")
164
- stats_output = gr.Markdown(label="Statistiche")
165
 
166
- # Download button
167
- csv_output = gr.File(label="Scarica risultati (CSV)")
 
168
 
169
- process_button.click(
170
- process_column,
171
- inputs=[df_state, column_select],
172
- outputs=[progress_output, chart_output, stats_output, csv_output]
173
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
- demo.launch()
 
 
1
  import gradio as gr
2
  import pandas as pd
3
+ from openai import OpenAI
4
+ import os
 
5
  import io
6
+ import json
7
+ from transformers import pipeline
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ # Modello NLP open-source locale per il primo livello di analisi
10
+ sentiment_pipeline = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ # Funzione per analizzare i commenti con GPT solo se necessario
13
+ def analyze_comments(texts):
14
+ """ Usa prima un modello NLP locale, poi GPT-3.5/GPT-4 solo se serve."""
15
+ client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  results = []
17
+ to_send_gpt = []
18
+ index_map = {}
19
 
20
+ # 1️⃣ Analisi iniziale con modello open-source
21
  for i, text in enumerate(texts):
22
+ local_result = sentiment_pipeline(text)[0]['label']
23
+ rating = int(local_result.split()[0])
 
24
 
 
25
  if rating > 3:
26
+ results.append("Positive")
27
  elif rating < 3:
28
+ results.append("Negative")
29
  else:
30
+ results.append("Neutral")
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ return results
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+
35
+ def analyze_file(file):
36
+ """Carica un file e analizza il sentiment dei commenti nella prima colonna."""
37
+ try:
38
+ file_extension = os.path.splitext(file.name)[-1].lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ if file_extension == ".csv":
41
+ df = pd.read_csv(file)
42
+ elif file_extension in [".xls", ".xlsx"]:
43
+ df = pd.read_excel(file, engine='openpyxl')
44
+ else:
45
+ return "Error: Unsupported file format.", None
46
 
47
+ if df.empty or df.shape[1] < 1:
48
+ return "Error: No valid data in the file.", None
49
 
50
+ df = df.rename(columns={df.columns[0]: "Comment"})
51
+ batch_size = 10
52
+ sentiments = []
 
53
 
54
+ for i in range(0, len(df), batch_size):
55
+ batch = df['Comment'][i:i+batch_size].tolist()
56
+ sentiments.extend(analyze_comments(batch))
57
 
58
+ df["Sentiment"] = sentiments
59
+ output = io.BytesIO()
60
+ with pd.ExcelWriter(output, engine='openpyxl') as writer:
61
+ df.to_excel(writer, index=False)
62
+ output.seek(0)
63
+ return df, output
64
+ except Exception as e:
65
+ return f"Error processing file: {str(e)}", None
66
+
67
+
68
+ def sentiment_analysis_interface():
69
+ """Interfaccia Gradio per caricare file e ottenere analisi del sentiment."""
70
+ file_input = gr.File(label="📥 Upload a file (CSV, XLSX)")
71
+ results_output = gr.Dataframe()
72
+ download_button = gr.File(label="📥 Download Excel")
73
+
74
+ def process_file(uploaded_file):
75
+ df, excel_data = analyze_file(uploaded_file)
76
+ if isinstance(df, str):
77
+ return df, None
78
+ with open("sentiment_analysis.xlsx", "wb") as f:
79
+ f.write(excel_data.read())
80
+ return df, "sentiment_analysis.xlsx"
81
+
82
+ return gr.Interface(
83
+ fn=process_file,
84
+ inputs=[file_input],
85
+ outputs=[results_output, download_button],
86
+ title="📊 Sentiment Analysis",
87
+ description="Upload a file with comments and get sentiment analysis using an NLP model!"
88
+ )
89
+
90
+ iface = sentiment_analysis_interface()
91
 
92
+ if __name__ == "__main__":
93
+ iface.launch()