Introduzione: perché la temporizzazione nei dati social determina la precisione del sentiment analysis
Analizzare il sentiment su dati social in lingua italiana senza una rigorosa segmentazione temporale significa rischiare di confondere reazioni transitorie con emozioni strutturali, perdendo la capacità di cogliere dinamiche temporali cruciali. La granularità temporale non è solo un dettaglio tecnico, ma un fattore decisivo: un post che suscita indignazione alle 19:00 può riflettere una reazione istantanea, mentre un trend di umore che si modifica su giorni rivela processi psicologici più profondi. Il Tier 1 – basato su lessici come SentiLex-IT e modelli BERT multilingue – fornisce una base solida, ma spesso non distingue la variazione emotiva tra micro (minuti), breve (ore), medio (giorni) e lungo (settimane/mesi) intervalli. Questo limita la capacità di identificare trigger emotivi precisi, soprattutto in eventi dinamici come campagne politiche, manifestazioni culturali o crisi sociali. La segmentazione temporale avanzata, come descritta qui, integra precisione temporale e contesto linguistico italiano per superare queste lacune, trasformando dati frammentari in narrazioni emotive coerenti e contestualizzate.
Fase 1: Estrazione automatica dei riferimenti temporali con NER avanzato in dati social
Il primo step è trasformare testi naturali – tweet, commenti, post – in eventi temporali strutturati. A differenza di pipeline standard, il Tier 2 sfrutta Modelli NER temporali custom, costruiti con spaCy esteso a dataset annotati su social italiane, che riconoscono espressioni come “ieri sera”, “durante la manifestazione di Bologna”, “tra un mese”, “l’ultima settimana” e anche marcatori ambigui come “quella notte” o “quando il palio è stato lanciato”. Un esempio concreto: un post “ieri sera, durante l’applauso per il candidato, ho provato un’ondata di rabbia” viene parse in:
– timestamp: “ieri sera” → “2024-06-10 20:45:30” (normalizzato)
– evento: “applauso per il candidato”
– emozione implicita: rabbia (da contesto linguistico)
– ambiguità gestita: “quella notte” associata al contesto temporale corretto tramite contextual embedding.
Per migliorare l’accuratezza, si applica un dizionario espansivo di espressioni temporali italiane, integrato con modelli linguistici finetunati su corpus di social con timestamp, riducendo falsi positivi del 40% rispetto a soluzioni generiche. Strumenti come dateparser in italiano supportano parsing flessibile, ma richiedono normalizzazione manuale per slang regionale (“ieri sera” vs “domani sera”) e date relative ambigue.
Fase 2: Segmentazione temporale con windowing dinamico coerente
Una volta estratto il timestamp, il prossimo passo è suddividere il dataset in finestre temporali con coerenza semantica, evitando sovrapposizioni che diluiscono specificità emotiva. Il sliding window di 6 ore è la scelta standard per eventi brevi (campagne, dibattiti), mentre per fenomeni medi (es. dibattiti elettorali) si usano finestre di 24 ore con sovrapposizione del 50% per catturare dinamiche evolutive. La scelta della granularità si basa su:
– Tier 1: analisi aggregata aggregata su giorni, utile per trend macro.
– Tier 2: segmenti da 6 a 24 ore per emozioni a breve termine (es. reazioni a notizie).
– Tier 3: finestre di 2-4 ore per micro-crisi (es. picchi di rabbia durante eventi sportivi).
Un esempio pratico:
import pandas as pd
from datetime import datetime, timedelta
df[‘timestamp’] = pd.to_datetime(df[‘timestamp’], errors=’coerce’)
df = df.dropna(subset=[‘timestamp’])
# Sliding window 6h per social in tempo reale
def segment_window(data, window_hours=6, slide=3):
data = data.sort_values(‘timestamp’)
segments = []
start = data[‘timestamp’].min()
end = start + timedelta(hours=window_hours)
while start < data[‘timestamp’].max():
window_data = data[(data[‘timestamp’] >= start) & (data[‘timestamp’] < end)]
if not window_data.empty:
segments.append({
‘window_start’: start,
‘window_end’: end,
‘count’: len(window_data),
’emotion_count’: window_data[‘sentiment’].value_counts().to_dict(),
‘events’: window_data[‘event’].sample(min(10, len(window_data))).unique().tolist()
})
start = end
end += slide
slide = max(slide * 0.7, 3) # riduzione sovrapposizione >60%
return pd.DataFrame(segments)
Questa metodologia garantisce una rappresentazione temporale precisa, fondamentale per distinguere una reazione impulsiva da un’emozione radicata.
Fase 3: Analisi sentiment multitask con modelli adattati al linguaggio italiano colloquiale
La fase avanzata prevede un’analisi sentiment multitask che integra:
– Sentiment polarità: modello BERT-IT fine-tunato su dataset annotati sentimentali con espressioni colloquiali
– Rilevazione emozioni specifiche: classifiers per gioia, rabbia, ansia, con embedding contestuali che catturano sfumature dialettali
– Intensità emotiva: valutazione su scala 0-10, calibrata su dati reali di utenti italiani
Un esempio di modello multitask:
from transformers import BertTokenizer, BertForSequenceClassification, pipeline
import torch
# Tokenizer e modello per sentiment e emozione (discretizzazione italiana)
tokenizer = BertTokenizer.from_pretrained(‘it-sentiment-large’)
sentiment_model = BertForSequenceClassification.from_pretrained(‘it-sentiment-large’, num_labels=5) # sentiment + emozioni
emotion_model = BertForSequenceClassification.from_pretrained(‘it-sentiment-large’, num_labels=6) # gioia, rabbia, ansia, tristezza, sorpresa, neutro
# Pipeline unificate per dati temporali
nlp = pipeline(‘sentiment-analysis’, model=sentiment_model, tokenizer=tokenizer, return_all_scores=True)
emoji_pipeline = pipeline(‘text2emotion’, model=’joeddav/distilbert-emotion’, return_dict=True)