-->

Intelligenza Artificiale

A un certo punto non fu più la biologia a dominare il destino dell'uomo, ma il prodotto del suo cervello: la cultura.
Cosicché: "Le uniche leggi della materia sono quelle che la nostra mente deve architettare e le uniche leggi della mente sono architettate per essa dalla materia".
JAMES CLERK MAXWELL

Regressione AntiSpam


Creare un Filtro Anti-Spam con la Regressione Lineare

Creare un Filtro Anti-Spam con la Regressione Lineare

La regressione lineare è un modello matematico utilizzato principalmente per prevedere valori numerici, ma con alcune modifiche può essere adattato a problemi di classificazione binaria, come distinguere tra email *spam* e *ham* (non spam). In questo articolo, vedremo come implementare un filtro anti-spam con Python utilizzando la regressione lineare.

Concetti Fondamentali

La regressione lineare cerca di stabilire una relazione tra una o più variabili indipendenti (features) e una variabile dipendente. Sebbene non sia progettata per classificazione binaria, possiamo interpretare l'output della regressione (un valore continuo) come una probabilità: - Valore > 0.5: Etichettato come spam.
- Valore ≤ 0.5: Etichettato come ham.

Dataset

Per questo esempio, utilizzeremo il dataset "SMS Spam Collection Dataset"
disponibile su [Kaggle](https://www.kaggle.com/uciml/sms-spam-collection-dataset).

Installare le Dipendenze

Prima di iniziare, assicurati di avere Python e le librerie necessarie installate:

pip install pandas scikit-learn nltk

Caricare e Pre-elaborare il Dataset

Il dataset contiene due colonne: - label: indica se un messaggio è spam o ham.
- text: il contenuto del messaggio.
Caricheremo e pre-elaboreremo i dati per rimuovere stopword, caratteri speciali e normalizzare il testo.

Codice Completo



import pandas as pd
import numpy as np
import re
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LinearRegression
from sklearn.metrics import accuracy_score

# Pre-elaborazione del testo
def preprocess_text(text):
    # Converti in lowercase
    text = text.lower()
    # Rimuovi caratteri speciali e numeri
    text = re.sub(r'[^a-z\s]', '', text)
    # Tokenizza e rimuovi stopword
    from nltk.corpus import stopwords
    from nltk.tokenize import word_tokenize
    import nltk
    nltk.download('stopwords')
    nltk.download('punkt')
    stop_words = set(stopwords.words("english"))
    text = " ".join(word for word in word_tokenize(text) if word not in stop_words)
    return text

# Caricare il dataset
dataset = pd.read_csv("spam.csv", encoding="latin-1")

# Rinominare le colonne per semplicità
dataset = dataset.rename(columns={"v1": "label", "v2": "text"})

# Mantenere solo le colonne necessarie
dataset = dataset[["label", "text"]]

# Convertire le etichette in valori numerici
dataset["label"] = dataset["label"].map({"ham": 0, "spam": 1})

# Applicare la pre-elaborazione al testo
dataset["text"] = dataset["text"].apply(preprocess_text)

# Separare le caratteristiche (X) e il target (y)
X = dataset["text"]
y = dataset["label"]

# Convertire il testo in una rappresentazione numerica (bag-of-words)
vectorizer = CountVectorizer()
X_vectorized = vectorizer.fit_transform(X).toarray()

# Dividere il dataset in training e test set
X_train, X_test, y_train, y_test = train_test_split(X_vectorized, y, test_size=0.2, random_state=42)

# Inizializzare e addestrare il modello di regressione lineare
model = LinearRegression()
model.fit(X_train, y_train)

# Predire i valori sul test set
y_pred = model.predict(X_test)

# Convertire le probabilità in classificazioni (0 o 1)
y_pred_class = [1 if prob > 0.5 else 0 for prob in y_pred]

# Calcolare l'accuratezza
accuracy = accuracy_score(y_test, y_pred_class)
print("Accuracy del filtro anti-spam con regressione lineare:", accuracy)

# Testare nuovi messaggi
new_emails = [
    "Congratulations! You've won a $1,000 Walmart gift card. Go to http://spam.com to claim now.",
    "Hey, are we still meeting for lunch today?",
]

# Pre-elaborare e trasformare i nuovi messaggi
new_emails_processed = [preprocess_text(email) for email in new_emails]
new_features = vectorizer.transform(new_emails_processed).toarray()

# Predire se i nuovi messaggi sono spam o ham
new_predictions = model.predict(new_features)
new_predictions_class = [1 if prob > 0.5 else 0 for prob in new_predictions]

# Stampare i risultati
for email, label in zip(new_emails, new_predictions_class):
    print(f"Messaggio: {email}")
    print(f"Classificazione: {'Spam' if label == 1 else 'Ham'}\n")

Analisi dei Risultati

La regressione lineare, sebbene efficace, non è ottimale per problemi di classificazione rispetto a metodi come Naive Bayes o le reti neurali.
Tuttavia, in situazioni semplici e con un dataset ben bilanciato, può ottenere buone prestazioni.

Possibili Miglioramenti

1. Normalizzazione delle feature: Standardizzare i dati per rendere più stabile il modello.
2. Metrica alternativa: Usare l'errore logaritmico invece della somma dei quadrati per problemi di classificazione.
3. Regolarizzazione: Aggiungere tecniche come Ridge o Lasso per migliorare la generalizzazione del modello.

Conclusione

La regressione lineare può essere utilizzata per costruire un filtro anti-spam di base, ma è importante considerare i suoi limiti intrinseci rispetto ad altri algoritmi di classificazione.
Questo approccio può essere un punto di partenza per chi vuole esplorare la costruzione di modelli di machine learning semplici e interpretabili.