L’analisi di Twitter tramite il software R. Breve guida pratica. Prima Parte.

Alessio Aversano
14 min readSep 29, 2020

--

Twitter è diventato uno dei social network più utilizzati dalla politica e dai brand. Tantissime informazioni e comunicazioni vengono veicolate ogni giorno sulla piattaforma di micro-blogging. Questa breve guida introduttiva aiuta, tramite il linguaggio R, ad esplorare e ad analizzare i principali trend della piattaforma dei cinguettii.

Design e grafica di WebSherpa

Gli esempi utilizzati in questa guida sono stati usati a scopo puramente didattico/illustrativo. I pacchetti e le funzioni utilizzate sono scritte in grassetto.

Vantaggi della Social Media Analysis su Twitter

Il vantaggio nell’uso di Twitter per l’analisi dei social media è che le API della piattaforma, a differenza di altri social network, sono aperte e facilmente accessibili. Inoltre, tramite gli hashtag è facile individuare conversazioni su brand, eventi, personaggi famosi e politici.

L’utilizzo dei dati di Twitter permette di capire i trending topics, capire la customer opinion, comprendere il public sentiment e la reach (in particolare per quanto riguarda gli esponenti politici, ma anche personaggi famosi o eventi importanti) e individuare particolari avvenimenti come proteste o epidemie.

Prerequisiti fondamentali e pacchetti

Per poter effettuare la Twitter social media analysis con il software R sono necessari alcuni passaggi preliminari e l’installazione di diversi pacchetti R. In questa sede sè stato utilizzato RStudio con la versione R i386 4.0.2.

Innanzitutto, per poter accedere alla API della piattaforma è necessario avere un account Twitter e abilitarlo nella versione Twitter devolopers. Il social offre diverse versioni per sviluppatori (Standard search APIs, Enterprise search APIs e Premium search APIs) e per far pratica è sufficiente attivare l’account base Standard, che permette un certo numero di analisi e offre meno opzioni rispetto ai due pacchetti professionali, ma comunque utile per iniziare. Infine, è necessario disabilitare il blocco pop-up del proprio browser.

Pacchetti necessari per poter eseguire l’analisi di Twitter su R.

Estrazione di tweet

Funzione stream_tweets

Una volta effettuate le operazioni preliminari abilitando account e scaricando i pacchetti, si procede all’estrazione dei tweet.

La prima funzione del pacchetto rtweet che andremo a vedere è stream_tweets() , che permette di raccogliere l’1% dei tweet pubblicati nei trenta secondi (se si lasciano gli argomenti di default) in cui si elabora la query. Il campione è causale.

Ogni prima volta che verrà eseguita l’operazione, si aprirà una finestra del browser web che richiede l’autorizzazione, tramite Twitter developers, di prelevare le API dalla piattaforma. Questo passaggio è fondamentale per comprendere se tutte le operazioni preliminari sono state eseguite nel modo corretto.

Se l’operazione è andata a buon fine verrà creato l’oggetto tweetPupli: un dataframe di 1432 righe e 90 variabili.

Uno degli argomenti della funzione stream_tweets( ) è timeout, ovvero la fascia di tempo di estrazione dei tweet. Di default è impostato su 30 secondi, ma si possono scegliere tempi diversi.

library(rtweet)
library(readr)
#estrazione 1% tweet pubblici ultimi 30 seconditweetPubli <- stream_tweets("")dim(tweetPubli)

In questo caso ci troveremo con un dataframe di 2709 osservazioni e 90 variabili di tweet raccolti negli ultimi 60 secondi. Se invece si vuol ottenere un flusso di tweet su un topic particolare, un personaggio, un evento o qualsiasi altra cosa di tendenza si può selezionare un preciso argomento come input della funzione. Prendiamo ad esempio il flusso di tweet con hashtag #DonaldTrump degli ultimi 90 secondi.

L’oggetto creato ha 90 variabili: tra queste ci sono informazioni molto interessanti come l’utente (screen_name), i metadati (ora e luogo del tweet) e soprattutto il contenuto del tweet (text). Molte di queste variabili non sono disponibili e il loro risultato è NA. Proviamo adesso a ripulire, tramite il pacchetto dplyr, l’oggetto stream_Trump e creare un oggetto con le sole variabili che ci interessa mantenere. Questa operazione è possibile tramite la funzione select(), che permette di scegliere le uniche variabili da mantenere nel nuovo oggetto creato.

#pulizia di stream_Trump lasciando solo variabili che ci interessanoTrumpStreamClean <- Stream_Trump %>%
select(screen_name, created_at, text, hashtags, retweet_text)

Estrazione di tweet su temi particolari

Funzione search_tweets

Tramite le funzione search_tweets() si possono cercare tweet che rispecchiano una certa query di ricerca. Tuttavia, con l’account Standard APIs la ricerca è limitata ai tweet degli ultimi 7 giorni e per un numero massimo di 18000. E’ possibile estendere la ricerca oltre 18000 risultati tramite l’argomento retryonratelimit.

Estraiamo tweet degli ultimi sette giorni con l’hashtag #dark (in riferimento alla serie tv Netflix). Gli argomenti della funzione sono:

· dentro le virgolette la query di ricerca, con n il numero di tweet da estrarre;

· il numero di tweet da estrarre ( n );

· se includere o no tweet che hanno avuto retweet (include_rts = TRUE/FALSE);

· la lingua dei tweet (nel nostro caso abbiamo scelto l’inglese con “en”)

DartTweets <- search_tweets("Dark", n = 1000, include_rts = F, lang = "en")

Il risultato è l’oggetto DarkTweets, un dataframe di 982 osservazioni e 90 variabili.

Funzione get_timeline

La funzione get_timeline() estrae tweet postati da uno specifico utente, fino ad un numero massimo di 3200.

#estrazione 200 tweet Donald TrumpTrumpTweets <- get_timeline("@realDonaldTrump", n = 200)#estrazione prime 5 colonne e 10 righe head(TrumpTweets[ ,1:5],10]

Componenti essenziali dei dati di Twitter

I dataframe ottenuti estraendo dati dai tweet ci offrono tantissimi metadati e informazioni interessanti per poter analizzare ciò che avviene nella piattaforma e come si muovono gli utenti. Tra i componenti da tenere in considerazione ci sono:

· screen_name: per capire l’utente e i suoi interessi;

· followers_count: utile per comprende se l’attività dell’utente è quella di influencer;

· retweet_count e text: per identificare i tweet popolari.

Comprendere gli interessi dell’utente e il numero di tweet attraverso l’analisi di screen_name

Per comprendere gli interessi degli utenti su un dato tema e identificare gli utenti che sono più attivi su quel dato argomento bisogna innanzitutto capire quali hashtag utilizzare.

#creazione dataframe di utenti e tweet per #DarkDarkUsers <- search_tweets("#Dark", n = 1000)DarkUsersName <- table(DarkUsers$screen_name)head(DarkUsersName)

Per cercare quali sono gli utenti che hanno postato più tweet sul tema #Dark, dopo aver creato il dataframe ed estratto la variabile screen_name, tramite la funzione sort() possiamo ordinarli e ottenere la lista di utenti con maggiore attività sul tema.

#ordiniamo gli utenti sul tema #DarkDarkUsersSorted <- sort(DarkUsersName, decreasing = TRUE)head(DarkUsersNameSorted)

Calcolare il numero di follower

Tramite la funzione lookup_users() si possono estrarre informazioni sugli utenti della piattaforma. Basta inserire come input della funzione il nickname dell’account. Prendiamo ad esempio alcuni leader politici europei.

#estrazione dati da account leader politici europeileaderEurop <- lookup_users(c("GiuseppeConteIT", "EmmanuelMacron", "BorisJohnson"))head(leaderEurop)#creazione dataframe con colonne screen_name e followe_countleaderEuropCount <- leaderEurop[,c("screen_name", "followers_count")]head(leaderEuropCount)

Possiamo ordinarli per numero di followers, questa volta utilizzando il verbo arrange() del pacchetto dplyr:

leaderEurFollow <- leaderEuropaCount %>%
arrange(desc(followers_count))
head(leaderEurFollow)

Identificare i tweet e retweet popolari

#creazione dataframe con colonne text e retweet_countEurleadTxtRt <- leaderEurop[, c("text", "retweet_count")]#ordinare retweetEurleadTxRtSort <- EurleadTxRt %>%
arrange(desc(retweet_count))
head(EurleadTxRtSort)

In questo caso il tweet di Giuseppe Conte è stato il più retwittato rispetto a quello degli altri leader.

#esempio alternativo utilizzando #DarkDarkRetweet <- search_tweets("#Dark", n = 1000)DarkTxtRt <- DarkRetweet[,c("text", "retweet_count")]DarkTxtRtSort <- DarkTxtRt %>%
arrange(desc(retweet_count))

In questo caso però, essendoci un numero di tweet elevato, bisogna ripulire quelli duplicati, tramite la funzione unique()

#esclusione tweet duplicatiDark_tweet_unici <- unique(DarkTxtRtSort, by = "text"head(Dark_tweet_unici, 10)

Così abbiamo ottenuto la lista dei primi 10 tweet pubblicati sul topic #Dark in ordine di retweet.

#tweet sul topic #Dark in lingua ingleseDarkEn <- search_tweets("#Dark", n = 1000, lang = "en")DarkTxEnDf <- DarkEn[,c("text", "retweet_count")]DarkTxEnSort <- DarkTxEnDf %>%
arrange(desc(retweet_count))
Dark_en_unici <- unique(DarkTxEnSort, by = "text")head(Dark_en_unici, 10)

La stessa ricerca si può fare estraendo solo i tweet di una determinata lingua.

Filtrare i tweet

Per filtrare i tweet originali, ovvero che non sono @quote, retweet o @reply si utilizza il -filter:

· -filter:retweet esclude tutti i retweet

· -filter:quote esclude tutti i quote

· -filter:replies esclude tutti i replies

I -filter si applicano dopo la query di ricerca all’interno delle stesse virgolette.

Oggetto <- search_tweets("query ricerca -filter:retweet, -filter:quote, -filter:replies", n = 1000)

Proviamo a cercare dei tweet sul tema Nba:

NbaTweets <- search_tweets("Nba", n = 500)

Tra le variabili del dataframe avremo reply_to_screen_name, is_quote, is_retweet. Attraverso la funzione count() del pacchetto dplyr possiamo calcolarli:

#osserviamo le repliescount(NbaTweets$reply_to_screen_name)
#osserviamo le quotescount(NbaTweets$is_quote)
#osserviamo i retweetcount(NbaTweets$is_retweet)

Proviamo adesso ad elaborare la stessa query applicando i -filter

#estrazione 100 tweet originali NbaNbaTwOr <- search_tweets("Nba -filter:quote -filter:reetwet -filter:replies", n = 100)#controlliamo i retweetcount(NbaTwOr$is_retweet)
#controlliamo le quotescount(NbaTwOr$is_quote)
#controlliamo le repliescount(NbaTwOr$reply_to_screen_name)

Adesso abbiamo il dataframe NBATwOr, che contiene solo tweet originali che non sono stati retwittati, citati o hanno fatto utilizzo del reply.

Applicare il filtro per lingua

Ai diversi filtri, si può aggiungere un ulteriore filtro: i tweet per lingua. Per filtrare i tweet per lingua si aggiunge come argomento della funzione “lang”.

#estrazione 100 tweet originali sul tema #NASA in lingua spagnolaNasa_es_orig <- search_tweets("#NASA -filter:quote -filter:retweets -filter:replies", n = 100, lang = "es")head(Nasa_es_org, 10)
#controlliamo il texthead(Nasa_es_org$text, 4)

Le lingue principali per la funzione sono:

“en” : inglese

“es” : spagnolo

“de”: tedesco

“it” : italiano

“fr” : francese

Filtrare per retweet e favoriti

È altresì possibile filtrare i tweet in base al numero minimo di retweet e di like, tramite due argomenti della funzione search_tweets(): min_retweet e min_faves. Si possono utilizzare entrambi nella stessa query tramite l’operatore AND.

#estrazione tweet popolari #Tesla con almeno 100 retweet e 100 likeTeslaPop <- search_tweets("#Tesla min_faves:100 AND min_retweets:100")head(TeslaPop)

A questo punto possiamo creare un dataframe che contenga i retweet e i like:

#creazione dataframe per retweet_count e favorite_countTesla_pop_count <- TeslaPop[,c("retweet_count", "favorite_count")]head(Tesla_pop_count

L’analisi degli utenti

Il rapporto di influenza

L’analisi degli utenti Twitter può fornirci informazioni interessanti. Per comprendere l’influenza di un utente della piattaforma si può utilizzare il rapporto di influenza, ossia il numero di followers diviso il numero di utenti che l’utente segue.

Un rapporto positivo indica che l’utente ha più followers rispetto a utenti che segue, mentre un rapporto negativo indica che l’utente segue più utenti rispetto al numero di followers che possiede.

Per calcolare questo rapporto iniziamo col cercare tweet su un determinato tema. Successivamente utilizziamo la funzione users_data() per estrarre informazioni sugli utenti che twittano sul tema.

#estrazione tweet tema #DarkDark_tweet <- search_tweets("#Dark", n = 1000)#estrazione informazioni utentiDark_tweet_users <- users_data(Dark_tweet)names(Dark_tweet_users)

A questo punto possiamo estrarre dai metadati degli utenti follower_count e friends_count, tramite il pacchetto dplyr.

Dark_users_ratio <- Dark_tweet_users %>%
select(screen_name, followers_count, friends_count) %>%
summarize(influencer_ratio = followers_count / friends_count * 100)
#creazione dataframe con rapporta influenza ordinatoDark_users_df <- Dark_users_ratio[,c("screen_name", "follower_count", "friends_count")] %>%
mutate(influenceRt = followers_count / friends_count) %>%
arrange(desc(influenceRt))
head(Dark_users_df, 15)

Inoltre, possiamo vedere quali sono gli utenti che soddisfano un certo numero di follower e il loro rapporto influenza.

#utenti con più di 3000 followersTop_followers <- Dark_users_df %>%
filter(followers_count > 3000) %>%
select(-friends_count) %>%
arrange(desc(followers_count))
head(Top_followers, 10)
#controlliamo utenti con maggior rapporto influenzaTop_influence_rt <- Dark_users_df %>%
filter(followers_count > 3000) %>%
select(-friends_count) %>%
arrange(desc(influenceRt))
head(Top_influence_rt, 10)

Analisi tramite le liste

Possiamo estrarre informazioni importanti sugli utenti cercandoli attraverso le liste, con la funzione lists_users().

#estrazione lista utenti TeslaTesla_list <- lists_users("Tesla")Tesla_list[,1:4]

Con queste informazioni, possiamo estrarre la lista di utenti iscritti in queste liste, tramite la funzione lists_subscribers()

#estrazione utenti dalla lista Tesla Owner ClubsTesla_own_club <-lists_subscribers(slug = "tesla-owner-clubs", owner_user = "Tesla")Tesla_own_club$screen_name

Ottenuto l’elenco degli utenti della lista, possiamo ricavare le informazioni di questi tramite la funzione lookup_users(). Prima creiamo un oggetto scegliendo alcuni utenti, sulla base di quello che si vuole cercare (followers, località, tweet, etc):

#estrazione informazioni utentiTesla_users <- c("jexlag", "ubutao", "ryorb55", "falcitron")Tesla_users_info <- lookup_users(Tesla_users)head(Tesla_users_info)

Trend di Twitter

I trend su twitter

I trend di Twitter sono utili per una social media analysis. Dai trend presenti sulla piattaforma si possono intercettare mode o argomenti di attualità. Per ottenere un elenco dei trending topics attuali si utilizza la funzione get_trends().

#estrazione trend topics attualitrend_topics <- get_trends()head(trend_topics$trend, 10)

L’output sarà quello di diversi trend di tutte le lingue. Per limitare la ricerca e focalizzarsi solo su una certa audience in base alla località si usa invece la funzione trends_available().

#estrazione località trending topicstrends_dis <- trends_available()trends_it <- get_trends("Italy")head(trend_it$trend)
trends_berlin <- get_trends("Berlin")head(trends_berlin$trend)

Cercare i trend più retwittati

Si possono cercare i trend più retwittati tramite la colonna tweet_volume creata dalla funzione precedente. Purtroppo, questa funzione è disponibile solo per alcuni trends.

#aggregazione trends e tweet_volumetopic_trends_it <- trends_it %>%
select(trend, tweet_volume) %>&
arrange(desc(tweet_volume))
head(topic_trends_it, 10)

Mostrare i dati nel tempo

Si possono estrarre tweet e visualizzarli in una serie temporale partendo dalla funzione search_tweets(). Successivamente, per visualizzare i tweet si utilizzerà la funzione ts_plot(), con argomenti: l’oggetto creato, “hours” e il colore della linea.

#estrazione e visualizzazione tweet #NetflixTweet_netflix <- search_tweets("#Netflix", n = 1000, include_rts = FALSE)ts_plot(Tweet_netflix, by = "hours", color = "blue")

L’analisi del testo

Elaborazione dei testi

I passi da fare per l’elaborazione dei testi dei tweet sono:

- Rimuovere le informazioni ridondanti come gli url, i caratteri speciali, le emoticon, la punteggiatura e i numeri;

- Convertire il testo in un corpus;

- Trasformare tutto il testo in minuscolo;

  • Rimuovere le parole comuni o vuote;
#estrazione tweet Covid19covid19_tweets <- search_tweets("#Covid19", n = 1000, include_rts = F, lang = "en"#preleviamo colonna text e salviamola come dataframecovid19text <- covid19$texthead(covid19text)

Per rimuovere gli url dal testo si utilizza la funzione rm_twitter_url() del pacchetto qdapRegex.

#rimozione url dal testolibrary(qdapRegex)covid19_nourl <- rm_twitter_url(covid19text)head(covid19_nourl, 5)

Per rimuovere i caratteri speciali, la punteggiatura e i numeri e i numeri si utilizza invece la funzione gsub().

#rimozione caratteri specialicovid19_nosp <- gsub("[^A-Za-z]", " ", covid19_nourl)head(covid19_nosp, 5)

Per convertire il testo in un corpus si usa il pacchetto tm.

#conversione testo in corpuslibrary(tm)covid_corpus <- covid19_nosp %>%
VectorSource() %>%
Corpus()
covid_corpus[[3]]$content

Per trasformare tutte le parole in minuscolo si usa la funzione tm_map()

#conversione testo in minuscolocovid19_min <- tm_map(covid_corpus, tolower)covid19_min[[3]]$content

Le stop words vengono isolate tramite il pacchetto tm con la funzione tm_map(), che ha una lista di stop words in lingua inglese. Per controllare quali parole sono inserite nelle stop words basta richiamare la funzione stopwords(), con argomento la lingua da selezionare.

#stopwords in lingua inglesestopwords("en")
#stopwords in lingua italianastopwords("it")

L’elenco in italiano ha molte più parole, data la complessità della nostra lingua.

Proviamo adesso a rimuovere le stop words dal nostro corpus creato, così da focalizzarci sulle parole chiave.

#rimozione stop wordscovid19_nostwo <- tm_map(covid19_min, removeWords, stopwords("en"))covid19_nostwo[[3]]$content

Infine, rimuoviamo gli spazi creati dal corpus, ripulito dalla stopwords, attraverso l’argomento stripWhitespace.

#rimozione spazi dal corpus pulitocovid19_final <- tm_map(covid19_nostwo, striWhitespace)covid19final[[3]]$content

Visualizzare le parole più importanti

Per estrarre la frequenza delle parole nel corpus, si utilizza la funzione freq_terms() del pacchetto qdap. Nel caso ci siano difficoltà nel caricare il pacchetto qdap e rjava, provate a reinstallare o installare l’ultima versione di Java sul computer.

#estrazione frequenza della parolelibrary(rJava)
library(qdap)
freq_covid <- freq_terms(covid19_final, 40)head(freq_covid, 40)

In questo caso, molte parole che non hanno senso ma non sono incluse nella lista di stop words in lingua inglese compariranno nella nostra frequenza dei termini. A questo punto possiamo creare un vettore di parole personalizzate dove inserire i termini da escludere e ripulire ulteriormente il corpus.

#creazione vettore parole personalizzate da usare come stop wordsparolepers <- c("s", "amp", "t", "can", "now")freq_def <- tm_map(covid19_finale, removeWords, parolepers)freq_covid_def <- freq_terms(freq_def, 10)head(freq_covid_def, 10)

Visualizzare i termini più popolari

Il primo passo per visualizzare i termini più popolari è quello di creare un dataframe con un tot numero di termini più utilizzati, grazie alla funzione subset().

#creazione dataframe con termini frequenza > 50top50term <- subset(freq_covid_def, FREQ > 50)head(top50term)

Una volta ottenute le frequenze, tramite il pacchetto ggplot2 possiamo visualizzare le parole più utilizzate.

library(ggplot2)ggplot(top50term, aes(x = reorder(WORD, -FREQ), y = FREQ)) + geom_bar(stat_ "identity", fill = "cadetblue3") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) + xlab("Termini") + ylab("Frequenza") + labs(title = "Termini con frequenza maggiori di 50")
Il grafico è ovviamente personalizzabile tramite le tantissime funzioni e argomenti del pacchetto ggplot.

Creazione di una wordcloud

Per creare una word cloud si utilizza la funzione wordcloud() del pacchetto omonimo.

#creazione wordcloud con i termini più utilizzatilibrary(wordcloud)wordcloud(freq_covid_def, min.freq = 50, colors = "blue", scale = c(3, 0.5), random.order = FALSE)

La funzione utilizza diversi argomenti: la frequenza minima delle parole da inserire, il colore, la scala di grandezza dei termini e l’ordine. Per renderla più colorata si può utilizzare il pacchetto RColorBrewer.

library(RColorBrewer)wordcloud(freq_covid_def, max.words = 25, colors = brewer.pal(5, "Dark2"), scale = c(2.5, 1), randome.order = FALSE)

Seguimi su Medium| LinkedIn | GitHub | Tableau

--

--

No responses yet