Machine Learning per il rilevamento delle anomalie

 Un'applicazione che potrebbe anche interessare la digital forensics e la cybersecurity potrebbe essere quella di creare un programma di machine learning in grado di rilevare delle anomalie, per esempio, tra delle connessioni di rete di qualcuno.

Ipotizziamo di leggere un tabulato composto da data, orario ed indirizzo IP di qualcuno (azienda o privato) e cerchiamo di capire se vi sono delle connessioni anomale, diverse dal solito, questa è la "anomaly detection".

Possiamo raggiungere l'obbiettivo manualmente o creando filtri o altro, ma perché non affidare il compito ad un sistema di Intelligenza Artificiale?

Quali vantaggi potrebbero scaturirne?

I vantaggi sono dati dal fatto che il machine learning impara dai dati e se nota degli scostamenti su dei dati che sono abbastanza regolari e quindi matematicamente parlando sono come dei punti geometrici che cadono più o meno nella stessa zona, se immaginiamo degli assi cartesiani, allora nel momento in cui vi è un oggetto che si discosta di un certo valore da tutti gli altri, ecco che viene rilevato come "anomalo".

Per creare questo programma di machine learning dobbiamo pensare ad un algoritmo non supervisionato (unsupervised), quindi il dataset non deve avere delle "label" ma solo delle "features", perché deve essere la macchina a predire il valore e classificarlo, basandosi su quello che capisce dall'addestramento su gli altri dati.

In sostanza, nel machine learning supervisionato, il dataset ha la colonna delle "label" (etichette), che servono ad far capire all'algoritmo che un oggetto X appartiene alla categoria A, mentre l'oggetto Y appartiene alla categoria B e così via, quando invece la variabile è continua, quindi non categorizzata dall'etichette, sarà la macchina a capire da sola come "aggregare" certi dati tali da farli appartenere a qualcosa, insomma come se qualcuno ci facesse vedere tanti gatti e tanti cani, senza che noi sappiamo che sono gatti e cani, nessuno ci ha detto che come si chiamano questi strani animali, poi un bel giorno qualcuno ci porta un gatto, automaticamente lo inseriremo noi nel gruppo degli animali con i baffi lunghi, le pupille ellittiche e la faccia da furbetto! 

E' utile introdurre anche il concetto del cosìdetto "clustering", 

Il clustering è un tipo di algoritmo di apprendimento automatico non supervisionato. Viene utilizzato per raggruppare i punti dati con caratteristiche simili ai cluster.
Idealmente, i punti dati nello stesso cluster dovrebbero mostrare proprietà simili e i punti in diversi cluster dovrebbero essere il più dissimili possibile.

L'Isolation Forest è un algoritmo non supervisionato e quindi non necessita di etichette per identificare il valore anomalo / anomalia

Il fondamento dell'algoritmo è quello di "isolare" le anomalie creando alberi decisionali su attributi casuali, questo partizionamento casuale produce percorsi più brevi per le anomalie quindi, se ci sono poche anomalie ci saranno partizioni più piccole di dati, perché i valori delle anomalie hanno maggiori probabilità di essere separati nel partizionamento iniziale

Quindi, quando una foresta di alberi casuali produce lunghezze di percorso più brevi per alcuni punti particolari, è molto probabile che siano anomalie.

In sintesi:

Fig. 1 - ci sono tante partizioni sui dati per isolare un singolo punto normale

Fig. 2 - ci sono solo quattro partizioni per isolare il punto anomalo

Quindi, per esser chiari l'algoritmo se riesce ad isolare un punto con poche partizioni dei dati, dopo che ha pure preso dei campioni di tutti i dati, per semplificare e velocizzare ancor di più, allora il punto è molto probabilmente un'anomalia (outlier), se invece ha bisogno di più partizionamenti per isolarlo, allora il punto sarà normale.

Detto tutto questo, vediamo il mio solito orribile programmino didattico basato sul mio solito e striminzito dataset!

IL DATASET

Chiaramente, non volendo/potendo risolvere le conversioni da testo a numero, per far digerire i dati all'algoritmo, ho trasformato gli indirizzi IP in numeri eliminando il puntino ".", quindi 192168001010 è in realtà: 192.168.001.010, stessa cosa per le date e gli orari: 160504 è 16:05:04.

Chiusa la mia parentesi di inettitudine e pigrizia, vediamo il programma (didattico):

# -*- coding: utf-8 -*-
"""
Created on Thu Mar 11 11:42:49 2021

@author: nanni bassetti - nannibassetti.com
"""

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest


df = pd.read_csv('ip.csv', names=['date', 'time', 'ip'], header=0)

F = df[['time','ip']]

model=IsolationForest(n_estimators=50, max_samples='auto', contamination=float(0.05),max_features=1.0)
model.fit(F)
df['scores']=model.decision_function(F)
df['anomaly']=model.fit_predict(F)

anomaly=df.loc[df['anomaly']==-1]
normal=df.loc[df['anomaly'] == 1]

anomaly_index=list(anomaly.index)
outliers_counter = len(df[df['anomaly'] < 0])

print(anomaly)
print ('Anomalies number: ',outliers_counter)
print("Accuracy percentage:", 100*list(df['anomaly']).count(-1)/(outliers_counter))

p1 = plt.scatter(normal, normal, c="green", s=50, edgecolor="black")
p2 = plt.scatter(anomaly, anomaly, c="red", s=50, edgecolor="black")
plt.xlim((-0.3, 0.3))
plt.ylim((-0.3, 0.3))
plt.legend(
    [p1, p2],
    ["normal", "anomalous"],
    loc="lower right",
)

plt.show()


In sostanza il programma legge il dataset ip.csv, carica la variabile F con i valori dell'orario e dell'indirizzo IP, lancia il modello IsolationForest e trova le anomalie che sono gli output valorizzati con "-1", mentre i valori normali hanno output  uguale a "1", inoltre calcola anche dei punteggi dati dall'elaborazione del modello.
Infine, disegna un grafico che rende meglio l'idea di dove sono i punti anomali e quanto distano dalla massa di punti normali.
Chiaramente, lavorando sul dataset e sugli iperparametri del modello, si può fare un tuning migliore.
Ed ecco il risultato:


Notiamo che ha beccato l'indirizzo IP: 010.175.021.210 che appare solo una volta nel dataset e fin qui è banale, ma la cosa interessante è aver preso anche il 192.168.001.010 che invece è uno degli indirizzi IP più "consueti" e normali del dataset, ma l'anomalia sta nell'orario di connessione ossia le 04:32:11, che è un orario non solito nell'attività listata nel dataset.

Il sorgente è QUI.




Commenti