Applicazioni pratiche di machine learning/Identificazione dei social bot
Caricamento librerie
[modifica | modifica sorgente] library(ggplot2)
library(dplyr)
library(caret)
Parte 1: Dati
[modifica | modifica sorgente]I social bot sono programmi che distribuiscono messaggi di propaganda politica attraverso i social media e hanno il compito di influenzare le discussioni e/o le opinioni dei loro lettori .
Il dataset users.csv scaricabile da qui : https://www.nbcnews.com/tech/social-media/now-available-more-200-000-deleted-russian-troll-tweets-n844731 contiene social bot russi di Twitter che sono stati utilizzati per influenzare le elezioni presidenziali degli Stati Uniti nel 2016. In particolare per screditare i democratici ci sono per esempio tweets, che danno fake news sulla stregoneria praticata da alcuni democratici, oppure li dipingono come attivisti dell'organizzazione Black Lives Matter, impegnata nella lotta contro il razzismo nei confronti dei neri . Il dataset users_regular.csv contiene invece dati relativi a utenti regolari di Twitter.
Le variabili dei datasets che si utilizzano per identificare i social bot, rispetto agli utenti normali sono :
- followers_count: Numero di account Twitter che seguono questo account
- following_count: Numero di account Twitter seguiti da questo account
- friends_count: Numeri di amici di questo account
- statuses_count: Numero di post pubblici creati da questo account
- listed_count: Numero di liste in cui appare questo account
Caricamento dei dati:
users_bot <- read.csv("users_bot.csv")
users_regular <- read.csv("users_regular.csv")
Inserisco nei datasets la variabile da predire Tipo_di_utente che può assumere i valori human o bot
users_bot <- cbind(users_bot,Tipo_di_utente="bot")
users_regular <- cbind(users_regular,Tipo_di_utente="human")
variables<- c("statuses_count","followers_count","friends_count","favourites_count","listed_count","Tipo_di_utente")
df <-rbind(users_bot[, variables],users_regular[, variables])
Alcuni dati statistici come min, max, media, mediana, 1° quartile, 3° quartile si ottengono con la funzione summary
summary(df)
statuses_count followers_count friends_count Min. : 1 Min. : 0 Min. : 0.0 1st Qu.: 1545 1st Qu.: 154 1st Qu.: 175.0 Median : 5386 Median : 372 Median : 340.0 Mean : 15734 Mean : 1726 Mean : 802.6 3rd Qu.: 17775 3rd Qu.: 944 3rd Qu.: 739.0 Max. :399555 Max. :986837 Max. :46310.0 NA's :70 NA's :70 NA's :70 favourites_count listed_count Tipo_di_utente Min. : 0 Min. : 0.00 bot : 453 1st Qu.: 259 1st Qu.: 0.00 human:3474 Median : 1285 Median : 3.00 Mean : 4380 Mean : 21.36 3rd Qu.: 4300 3rd Qu.: 10.00 Max. :313954 Max. :6166.00 NA's :70 NA's :70
Elimino le righe del dataset contententi valori mancanti NA:
df <- df[-which(is.na(df)),]
colSums(is.na(df))
statuses_count followers_count friends_count favourites_count 0 0 0 0 listed_count Tipo_di_utente 0 0
Parte 2: Domanda di ricerca
[modifica | modifica sorgente]Si vuole costruire un modello previsionale di machine learning che consenta di distinguere gli utenti regolari di Twitter dai social bot.
Parte 3: Esplorazione dei dati
[modifica | modifica sorgente] df %>%
ggplot(aes(Tipo_di_utente, fill=Tipo_di_utente))+
geom_bar()+
scale_y_continuous(breaks=seq(0,4000,500))+
ggtitle("Numero di utenti del campione",subtitle = "suddivisi in base alla variabile Tipo_di_utente")
Le variabili che si utilizzano come predictors nell'analisi sono tutte fortemente distorte a destra, nel senso che la maggiorparte degli utenti di Twitter hanno pochi followers, pochi amici ecc. e ci sono invece pochi utenti che ne hanno tantissimi al punto da potersi considerare outliers o valori anomali
df %>%
ggplot(aes(Tipo_di_utente,friends_count , fill=Tipo_di_utente))+
geom_boxplot()+
ggtitle("Boxplots della variabile friends_count", subtitle = "in base al tipo di utente")
Parte 4: Modellizzazione e previsione
[modifica | modifica sorgente]Divido il dataframe df, contenente sia utenti regolari che social bot, in un training set costituito dal 70% delle osservazioni casuali, ottenendo 2.701 utenti, ed in un testing set costituito dai rimanenti 1.156 utenti:
train <- createDataPartition(df$Tipo_di_utente ,p=0.7, list = FALSE)
training <- df[train,]
testing <- df[-train,]
Utilizzando l'algoritmo di machine learning Random Forest ottendo un'Accuracy quasi del 100% sul training set e del 95,76% sul testing set, quindi un buon modello che consente di distinguere gli utenti regolari di Twitter dai social bot.
model <- train( Tipo_di_utente ~ .,data=training, method="rf", ntree=10 )
p1 <- predict(model,newdata = training)
print(confusionMatrix(p1,training$Tipo_di_utente))
p1 <- predict(model,newdata = testing)
print(confusionMatrix(p1,testing$Tipo_di_utente))
Confusion Matrix and Statistics Reference Prediction bot human bot 260 2 human 9 2430 Accuracy : 0.9959 95% CI : (0.9927, 0.998) No Information Rate : 0.9004 P-Value [Acc > NIR] : < 2e-16 Kappa : 0.977 Mcnemar's Test P-Value : 0.07044 Sensitivity : 0.96654 Specificity : 0.99918 Pos Pred Value : 0.99237 Neg Pred Value : 0.99631 Prevalence : 0.09959 Detection Rate : 0.09626 Detection Prevalence : 0.09700 Balanced Accuracy : 0.98286 'Positive' Class : bot
Confusion Matrix and Statistics Reference Prediction bot human bot 80 15 human 34 1027 Accuracy : 0.9576 95% CI : (0.9443, 0.9685) No Information Rate : 0.9014 P-Value [Acc > NIR] : 7.282e-13 Kappa : 0.7425 Mcnemar's Test P-Value : 0.01013 Sensitivity : 0.70175 Specificity : 0.98560 Pos Pred Value : 0.84211 Neg Pred Value : 0.96795 Prevalence : 0.09862 Detection Rate : 0.06920 Detection Prevalence : 0.08218 Balanced Accuracy : 0.84368 'Positive' Class : bot
Identificazione di un utente di Twitter
[modifica | modifica sorgente]Un utente di Twitter con i seguenti dati per il modello è umano, non è un social bot:
predict(model, newdata = data.frame(statuses_count=6742, followers_count=650, friends_count=896, favourites_count=7237, listed_count=30))
[1] human Levels: bot human