Tafel:
Intro
Naive Bayes is een machine learning-algoritme voor classificatie dat is gebaseerd op de stelling van Bayes. Het is zeer efficiënt, vooral als het gaat om tekstuele gegevens zoals: sentimentanalyse, spamdetectie en tekstclassificatie.
Dit algoritme wordt “Naïef” genoemd vanwege de aanname dat alle datasetvariabelen onafhankelijk zijn, wat niet altijd het geval is.
Voordat we verder gaan met uitleggen hoe Naive Bayes werkt, moeten we ervoor zorgen dat we het volgende begrijpen:
Voorwaardelijke waarschijnlijkheid
Het naïeve Bayes-algoritme is gebaseerd op de stelling van Bayes, die is gebaseerd op voorwaardelijke waarschijnlijkheid: het is de waarschijnlijkheid dat gebeurtenis A plaatsvindt, gegeven het feit dat gebeurtenis B al heeft plaatsgevonden.
Voorbeeld:
Laten we twee potten hebben met gekleurde ballen:
-
Pot 1 heeft 3 blauwe ballen, 2 rode ballen en 4 groene ballen.
-
Pot 2 heeft 1 blauwe bal, 4 rode ballen en 3 groene ballen.
We willen de waarschijnlijkheid berekenen dat we willekeurig een blauwe bal uit een van de potten selecteren
Het is niets anders dan de som van de kansen om een blauwe bal uit Jar1 of Jar2 te selecteren.
Nu willen we de waarschijnlijkheid berekenen dat we een blauwe bal selecteren, gegeven het feit dat we Jar1 hebben geselecteerd:
Ten slotte willen we de waarschijnlijkheid berekenen dat we Jar1 selecteren, gegeven het feit dat we een blauwe bal hebben getrokken. Hier gebruiken we de stelling van Bayes die als volgt wordt weergegeven:
Naïeve Bayes-classificatie
In de Naive Bayes-classificator willen we de klasse vinden die de voorwaardelijke waarschijnlijkheid maximaliseert, gegeven de invoervector X; Naïeve Bayes kan dus als volgt worden geformuleerd:
Met behulp van de stelling van Bayes wordt de functie:
In deze formulering is het gemakkelijk om P(Ci) te berekenen, wat niets anders is dan de waarschijnlijkheid van de klasse Ci, en het is gemakkelijk om P(x), wat de waarschijnlijkheid is dat de gebeurtenis x plaatsvindt, te berekenen.
Wat moeilijk te berekenen is, is P(x|Ci); de waarschijnlijkheid van de gebeurtenis x gegeven de klasse Ci. Om dit verder te vereenvoudigen, moeten we aannemen dat alle invoervariabelen onafhankelijk zijn; dus kunnen we schrijven:
En het is eigenlijk vanwege deze veronderstelling dat we deze classificator ‘naïef’ noemen, omdat we de onafhankelijkheid van de invoervariabelen niet altijd kunnen garanderen. De Naïeve Bayes-classificator wordt:
In feite kunnen we deze formulering verder vereenvoudigen door P(x) te elimineren, omdat deze voor alle klassen hetzelfde is:
Laten we nu eens naar een voorbeeld kijken:
| Weer | Tijd | Dag van de week | Diner |
| ------- | -------- | --------------- | ------ |
| Wissen | Avond | Weekend | Koks |
| Bewolkt | Nacht | Weekdag | Bestellingen |
| Regenachtig | Nacht | Weekdag | Bestellingen |
| Regenachtig | Middag | Weekdag | Bestellingen |
| Bewolkt | Middag | Weekend | Koks |
| Wissen | Nacht | Weekend | Koks |
| Besneeuwd | Avond | Weekend | Bestellingen |
| Wissen | Nacht | Weekdag | Koks |
| Wissen | Middernacht | Weekend | Bestellingen |
Hier hebben we een kleine dataset die drie invoervariabelen bevat: Weer, Tijd en Dag van de week, en één doelvariabele: “Diner” die aangeeft of iemand kookt of zijn avondeten bestelt. We willen graag de klasse van de invoer x={Clear, Evening, Weekend} vinden:
We moeten de voorwaardelijke waarschijnlijkheid berekenen voor de klasse “Koks” en de klasse “Bestellingen” gegeven de invoer x={Helder, Avond, Weekend}. De voorspelde klasse is degene met de hoogste voorwaardelijke waarschijnlijkheid.
We beginnen met het berekenen van de voorwaardelijke waarschijnlijkheid van de klasse “Koken”:
Nu berekenen we elke voorwaardelijke waarschijnlijkheid afzonderlijk:
De waarschijnlijkheid van weer=”Helder” gegeven het feit dat de klasse “Kookt” is, is het aantal regels met weer “Helder” en klasse “Kookt” ten opzichte van het totale aantal regels met klasse “Kookt”
Hetzelfde geldt voor de andere voorwaardelijke kansen:
Voor de waarschijnlijkheid P(Cooks) is dit het aantal regels met klasse “Cooks” over het totale aantal regels:
Nu berekenen we het product van deze kansen:
Dat was voor de klasse “Koken”, nu moeten we hetzelfde doen voor de klasse “Bestellingen”:
We berekenen de individuele kansen:
En uiteindelijk berekenen we het product van de kansen:
Ten slotte nemen we de klasse met de hoogste waarschijnlijkheid, namelijk de klasse “Koken”:
Voordelen en beperkingen van dit algoritme
Voordelen:
-
Het is een zeer snelle classificator.
-
Het is eenvoudig te implementeren.
-
Er is geen trainingsfase, maar het zijn slechts gevolgtrekkingen.
-
Er zijn niet veel gegevens nodig om conclusies te kunnen trekken.
Beperkingen:
- Naïef Bayes gaat ervan uit dat de invoervariabelen onafhankelijk zijn, wat niet altijd waar is.
- Het naïeve Bayes lijdt aan het nulfrequentieprobleem: het is wanneer het een nulwaarschijnlijkheid aan een invoervariabele toekent. Hierdoor wordt alle voorwaardelijke waarschijnlijkheid P(C|x) op nul gezet. Een truc om dit te voorkomen is door een minimale frequentie van 1 (in plaats van 0) voor alle variabelen te gebruiken.
Oefening
Hier is het dataframe van dezelfde dataset die we in het voorbeeld hebben gezien.
Jouw taak is om Naive Bayes zelf te implementeren met behulp van Python:
import pandas as pd
dataset = pd.DataFrame()
dataset['Weather'] = ['Clear', 'Cloudy', 'Rainy', 'Rainy', 'Cloudy', 'Clear', 'Snowy', 'Clear', 'Clear']
dataset['Time'] = ['Evening', 'Night', 'Night', 'Midday', 'Midday', 'Night', 'Evening', 'Night', 'Midnight']
dataset['Day'] = ['Weekend', 'Weekday', 'Weekday', 'Weekday', 'Weekend', 'Weekend', 'Weekend', 'Weekday', 'Weekend']
dataset['Class'] = ['Cooks', 'Orders', 'Orders', 'Orders', 'Cooks', 'Cooks', 'Orders', 'Cooks', 'Orders']
def naive_bayes(weather, time, day):
# res_dict = {class1: probability of class 1, class1: probability of class 1
return res_dict
Oplossing
def naive_bayes(x_weather, x_time, x_day):
TARGET = 'Dinner' # The name of the target variable
CLASSES = list(dataset['Dinner'].unique()) # The classes of the target variable
len_dataset = len(dataset) # The length of the dataset
res_dict = {} # res_dict = {class1:probability1, ..., class_n:probability_n}
# for each class of the target classes, we calculate the it's conditional probability
for class_name in CLASSES:
# the number of lines that belong to the class "class_name"
len_c = len(dataset[ (dataset[TARGET] == class_name) ])
# the number of lines that belong to the class "class_name" and have weather="x_weather"
n_weather = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Weather'] == x_weather) ])
# the number of lines that belong to the class "class_name" and have time="x_time"
n_time = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Time'] == x_time) ])
# the number of lines that belong to the class "class_name" and have day="x_day"
n_day = len(dataset[ (dataset[TARGET] == class_name) & (dataset['Day'] == x_day) ])
# We calculate the conditional probability:
# P(class|x) = P(weather|class) x P(time|class) x P(day|class) x P(class)
p = (n_weather / len_c) * (n_time / len_c) * (n_day / len_c) * (len_c / len_dataset) res_dict[class_name] = p
return res_dict