Applicazioni pratiche di machine learning/Identificazione dei social bot

Caricamento librerie

modifica
 library(ggplot2)
 library(dplyr)
 library(caret)


Parte 1: Dati

modifica

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

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
 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

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

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