Naive Bayes
Autor: Miruna Zăvelcă
Rezolvă în Colab: Naive Bayes
Ce înseamnă P(A) ? Ce valori poate să aibă?
...
Ce înseamnă P(A \cap B) ? Dar P(A \cup B) ?
...
Ce înseamnă P(A | B) ?
...
Ce știm despre variabilele independente?
P(A, B) = P(A) * P(B)
Cum putem interpreta probabilitatea de mai sus pentru variabile independente?
P(A, B | C) = P(A | C) * P(B | C)
Regula Bayes:
P(B|A) = \frac{P(A \cap B)}{P(A)} = \frac{P(A|B) * P(B)}{P(A)}
Cum arată clasificatorul Bayes?
h*(x) = argmax_{y} P(Y = y | X = x)
Fie y o clasă din universul de clase Y și x un feature din universul de features X. Pentru fiecare y, h* calculează probabilitatea ca aceasta să fie clasa căreia îi aparține elementul descris de x și păstrează clasa cu șansa cea mai mare. În alte cuvinte: h* clasifică un element x într-o clasă y.
Dacă aplicăm regula Bayes ajungem la:
h*(x) = argmax_{y} \frac{P(X = x | Y = y)\ *\ P(Y = y)}{P(X = x)}
Întrucât vrem să aflăm cel mai mare y pentru un x comun, putem neglija probabilitatea de la numitorul fracției:
h*(x) = argmax_{y} P(X = x | Y = y)\ *\ P(Y = y)
În realitate nu o să avemn niciodată un singur feature, ci un set. Putem presupune că toate trăsăturile din acest set sunt independente (presupunerea Bayes). Aplicând asta pe funcția noastră h* obținem:
h*(x) = argmax_{y} P(x_1, x_2, ... x_n | y)\ *\ P(y)
Deci:
h*(x) = argmax_{y} P(y)\ *\ ∏_{i = 1}^n P(x_i | y)
Care este labelul cel mai probabil știind că X = \{x_0, x_1, ... x_n\}
argmax_Y P(Y=y | X=x) = ?
P(Y=0 | X)\ ?\ P(Y=1 | X)
Teoreme:
Pentru A, B independente:
P(A, B | C) = P(A | C) * P(B | C)
Teorema lui Bayes:
P(A | B) = \frac{P(B|A) * P(A)}{P(B)}
Play Tennis – Dataset
| # | Outlook | Temperature | Humidity | Windy | Play Tennis |
|---|---|---|---|---|---|
| 0 | Rainy | Hot | High | False | No |
| 1 | Rainy | Hot | High | True | No |
| 2 | Overcast | Hot | High | False | Yes |
| 3 | Sunny | Mild | High | False | Yes |
| 4 | Sunny | Cool | Normal | False | Yes |
| 5 | Sunny | Cool | Normal | True | No |
| 6 | Overcast | Cool | Normal | True | Yes |
| 7 | Rainy | Mild | High | False | No |
| 8 | Rainy | Cool | Normal | False | Yes |
| 9 | Sunny | Mild | Normal | False | Yes |
| 10 | Rainy | Mild | Normal | True | Yes |
| 11 | Overcast | Mild | High | True | Yes |
| 12 | Overcast | Hot | Normal | False | Yes |
| 13 | Sunny | Mild | High | True | No |
Exercițiul 1
Folosește Naive Bayes pentru a prezice dacă se va juca tenis într-o zi X=(Sunny, Hot, Normal, False)
Soluție aici
Iris - Dataset
În secvența de cod de mai jos am încărcat un dataset din librăria scikit-learn și l-am împărțit în date de train și date de test. Variabila X conține lista de features pentru fiecare datapoint, în timp ce y conține lista de labels. Împărțirea am făcut-o automat cu ajutorul funcției train_test_split.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
X, y = load_iris(return_X_y=True)
df = pd.DataFrame(X)
df['label'] = y
df_train, df_test = train_test_split(df, test_size=0.2, random_state=0)
df_train
Exercițiul 2
Scrie o funcție care, pentru y parametru, calculează probabilitatea ca y să fie labelul corect raportat la setul de train.
0.325
Exercițiul 3
Scrie o funcție care, pentru x, i și y parametri, calculează probabilitatea P(x_i | y).
0.07692307692307693
Exercițiul 4
Scrie o funcție care calculează h*(x) pentru un x parametru.
0.000606888180852678
np.int64(2)
Exercițiul 5
Aplică h* pe setul de test și afișează acuratețea modelului creat.
Exercițiul 6
Creează o clasă NaiveBayes care să conțină:
- funcția fit, care primește matricea de features și lista de labels de antrenare și își calculează ponderile pe baza lor
- funcția predict, care primește o listă de features și returnează o listă cu labeluri prezise pentru fiecare dintre ele
Probabilities Further Reading: Monty Hall Problem
Tipuri de Naive Bayes
| Type | Input Features | Assumption | Best for |
|---|---|---|---|
| GaussianNB | Continuous (floats) | Features follow normal distribution | Numerical data (e.g. Iris) |
| MultinomialNB | Discrete counts | Frequencies of terms | Text classification (BoW) |
| BernoulliNB | Binary (0/1) | Feature presence/absence | Text with binary features |
GaussianNB
from sklearn.naive_bayes import GaussianNB
X_train = df_train.drop(columns=['label'])
y_train = df_train['label']
X_test = df_test.drop(columns=['label'])
y_test = df_test['label']
gnb = GaussianNB()
y_pred = gnb.fit(X_train, y_train).predict(X_test)
print("Model accuracy: ", accuracy_score(y_test, y_pred))
Model accuracy: 0.9666666666666667
În mod normal nu o să vrem să ne scriem modelele de mână. Ele sunt deja implementate în librării cunoscute, iar noi preferăm să ne concentrăm pe elemente mai "umane" ale întregului proces: observații pe care procesorul nu le poate face automat. Așadar o să preferăm să ne uităm la mai multe modele, mai multe features, mai mulți hiperparametrii etc. și să lăsăm librăriile să își consume timpul rulând modele în paralel.