Bord:
Intro
Naive Bayes er en maskinlæringsalgoritme, der er baseret på Bayes-sætningen. Det er meget effektivt, især når det drejer sig om tekstdata som: Sentimentanalyse, Spam-detektion og tekstklassificering.
Denne algoritme kaldes "Naiv" på grund af den antagelse, at alle datasætvariabler er uafhængige, hvilket ikke altid er tilfældet.
Før vi går videre med at forklare, hvordan Naive bayes fungerer, så lad os sikre os, at vi forstår følgende:
Betinget sandsynlighed
Naiv Bayes-algoritme er baseret på Bayes-sætningen, som er baseret på betinget sandsynlighed: det er sandsynligheden for forekomsten af en begivenhed A givet, at en begivenhed B allerede har fundet sted.
Eksempel:
Lad os have to krukker, der indeholder farvede kugler:
-
Krukke 1 har 3 blå kugler, 2 røde kugler og 4 grønne kugler.
-
Krukke 2 har 1 blå kugle, 4 røde kugler og 3 grønne kugler.
Vi vil beregne sandsynligheden for tilfældigt at vælge en blå kugle fra en af glassene
Det er intet andet end summen af sandsynligheden for at vælge en blå kugle fra Jar1 eller Jar2.
Nu vil vi beregne sandsynligheden for at vælge en blå kugle, da vi valgte Jar1:
Til sidst vil vi beregne sandsynligheden for at vælge Jar1, da vi tegnede en blå kugle. Her bruger vi Bayes-sætningen, der er angivet som følgende:
Naiv Bayes-klassifikation
I Naive Bayes classifier ønsker vi at finde den klasse, der maksimerer den betingede sandsynlighed givet inputvektoren X; Naive Bayes kan således formuleres som følger:
Ved brug af Bayes-sætningen bliver funktionen:
I denne formulering er det let at beregne P(Ci), som ikke er andet end sandsynligheden for klassen Ci, og det er let at beregne P(x), som er sandsynligheden for, at hændelsen x indtræffer.
Det der er svært at beregne er P(x|Ci); sandsynligheden for hændelsen x givet klassen Ci. For yderligere at forenkle dette, er vi nødt til at antage, at alle inputvariabler er uafhængige; så kan vi skrive:
Og det er faktisk på grund af denne antagelse, at vi kalder denne klassifikator "Naiv", fordi vi ikke altid kan garantere uafhængigheden af inputvariablerne. Den naive Bayes klassificering bliver:
Faktisk kan vi yderligere forenkle denne formulering ved at eliminere P(x), fordi den er den samme for alle klasser:
Lad os nu tage et kig på et eksempel:
| Vejret | Tid | Ugedag | Aftensmad |
| ------- | -------- | --------------- | ------ |
| Ryd | Aften | Weekend | Kokker |
| Overskyet | Nat | Ugedag | Ordrer |
| Regnvejr | Nat | Ugedag | Ordrer |
| Regnvejr | Middag | Ugedag | Ordrer |
| Overskyet | Middag | Weekend | Kokker |
| Ryd | Nat | Weekend | Kokker |
| Snedækket | Aften | Weekend | Ordrer |
| Ryd | Nat | Ugedag | Kokker |
| Ryd | Midnat | Weekend | Ordrer |
Her har vi et lille datasæt, der indeholder 3 inputvariabler: Vejr, Tid og Ugedag, og en Målvariabel: "Aftensmad", der angiver, om en person laver mad eller bestiller sin aftensmad. Vi vil gerne finde klassen for input x={Clear, Evening, Weekend}:
Vi skal beregne den betingede sandsynlighed for klassen "Kokke" og klassen "Ordre" givet input x={Klar, Aften, Weekend}. Den forudsagte klasse er den, der har den højeste betingede sandsynlighed.
Vi starter med at beregne den betingede sandsynlighed for klassen "Kokke":
Nu beregner vi hver betinget sandsynlighed for sig:
Sandsynligheden for vejr = "Klar", givet at klassen er "Kokke" er antallet af linjer med vejret "Klar" og klassen "Kokke" over det samlede antal linjer med klassen "Kokke"
Det samme gælder for de andre betingede sandsynligheder:
For sandsynligheden P(Kokke) er det antallet af linjer med klassen "Kokke" over det samlede antal linjer:
Nu beregner vi produktet af disse sandsynligheder:
Det var for klassen "Kokke", nu skal vi gøre det samme for klassen "Bestillinger":
Vi beregner de individuelle sandsynligheder:
Og til sidst beregner vi produktet af sandsynligheder:
Til sidst tager vi klassen med størst sandsynlighed, som er klassen "Kokke":
Fordele og begrænsninger ved denne algoritme
Fordele:
-
Det er en meget hurtig klassificering.
-
Det er nemt at implementere.
-
Der er ingen træningsfase, men det er kun slutninger.
-
Det kræver ikke en masse data for at drage konklusioner.
Begrænsninger:
- Naiv Bayes antager, at inputvariablerne er uafhængige, hvilket ikke altid er sandt.
- Naive Bayes lider af nulfrekvensproblemet: det er, når den tildeler nul sandsynlighed til en inputvariabel. Dette vil nulstille al den betingede sandsynlighed P(C|x). Et trick for at undgå dette er at bruge en minimal frekvens på 1 (i stedet for 0) til alle variabler.
Øvelse
Her er datarammen for det samme datasæt, som vi har set i eksemplet.
Din opgave er selv at implementere Naive Bayes ved hjælp af 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
Løsning
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