Stůl:
Intro
Naive Bayes je klasifikační algoritmus strojového učení, který je založen na Bayesově teorému. Je velmi efektivní zejména při práci s textovými daty, jako jsou: Analýza sentimentu, Detekce spamu a klasifikace textu.
Tento algoritmus se nazývá „Naivní“ kvůli předpokladu, že všechny proměnné datové sady jsou nezávislé, což není vždy případ.
Než budeme pokračovat ve vysvětlování toho, jak Naive bayes funguje, ujistěte se, že rozumíme následujícímu:
Podmíněná pravděpodobnost
Naivní Bayesův algoritmus je založen na Bayesově teorému, který je založen na podmíněné pravděpodobnosti: je to pravděpodobnost výskytu události A za předpokladu, že událost B již nastala.
Příklad:
Mějme dvě sklenice, které obsahují barevné kuličky:
-
Jar 1 má 3 modré koule, 2 červené koule a 4 zelené koule.
-
Jar 2 má 1 modrou kouli, 4 červené koule a 3 zelené koule.
Chceme vypočítat pravděpodobnost náhodného výběru modré koule z jedné ze sklenic
Není to nic jiného než součet pravděpodobností výběru modré koule z Jar1 nebo Jar2.
Nyní chceme vypočítat pravděpodobnost výběru modré koule vzhledem k tomu, že jsme vybrali Jar1:
Nakonec chceme vypočítat pravděpodobnost výběru Jar1 za předpokladu, že jsme nakreslili modrou kouli. Zde používáme Bayesovu větu, která je uvedena takto:
Klasifikace Naive Bayes
V klasifikátoru Naive Bayes chceme najít třídu, která maximalizuje podmíněnou pravděpodobnost danou vstupním vektorem X; Naive Bayes lze tedy formulovat následovně:
S použitím Bayesovy věty se funkce stává:
V této formulaci je snadné vypočítat P(Ci), což není nic jiného než pravděpodobnost třídy Ci, a je snadné vypočítat P(x), což je pravděpodobnost výskytu jevu x.
Co je těžké spočítat, je P(x|Ci); pravděpodobnost události x dané třídy Ci. Abychom to dále zjednodušili, musíme předpokládat, že všechny vstupní proměnné jsou nezávislé; tedy můžeme napsat:
A právě kvůli tomuto předpokladu nazýváme tento klasifikátor „Naivní“, protože nemůžeme vždy zaručit nezávislost vstupních proměnných. Klasifikátor Naive Bayes se stává:
Ve skutečnosti můžeme tuto formulaci dále zjednodušit odstraněním P(x), protože je to stejné pro všechny třídy:
Nyní se podívejme na příklad:
| Počasí | Čas | Den v týdnu | Večeře |
| ------- | -------- | ---------------- | ------ |
| Jasno | Večer | Víkend | Kuchaři |
| Zataženo | Noc | všední den | Objednávky |
| Deštivý | Noc | všední den | Objednávky |
| Deštivý | poledne | všední den | Objednávky |
| Zataženo | poledne | Víkend | Kuchaři |
| Jasno | Noc | Víkend | Kuchaři |
| Zasněžené | Večer | Víkend | Objednávky |
| Jasno | Noc | všední den | Kuchaři |
| Jasno | Půlnoc | Víkend | Objednávky |
Zde máme malou datovou sadu, která obsahuje 3 vstupní proměnné: Počasí, Čas a Den v týdnu a jednu Cílovou proměnnou: „Večeře“, která udává, zda člověk vaří nebo si objedná večeři. Rádi bychom našli třídu vstupu x={Clear, Evening, Weekend}:
Potřebujeme vypočítat podmíněnou pravděpodobnost pro třídu „Kuchaři“ a třídu „Objednávky“ při zadání x={Jasno, Večer, Víkend}. Predikovaná třída je ta, která má nejvyšší podmíněnou pravděpodobnost.
Začneme výpočtem podmíněné pravděpodobnosti třídy „Kuchaři“:
Nyní vypočítáme každou podmíněnou pravděpodobnost samostatně:
Pravděpodobnost počasí = „Jasné“ za předpokladu, že třída je „Kuchaři“ je počet řádků s počasím „Jasné“ a třídou „Kuchaři“ nad celkovým počtem řádků s třídou „Kuchaři“
Totéž platí pro ostatní podmíněné pravděpodobnosti:
Nyní pro pravděpodobnost P(Cooks) je to počet řádků s třídou „Cooks“ nad celkovým počtem řádků:
Nyní vypočítáme součin těchto pravděpodobností:
To bylo pro třídu „Kuchaři“, nyní musíme udělat totéž pro třídu „Objednávky“:
Vypočítáme jednotlivé pravděpodobnosti:
A nakonec vypočítáme součin pravděpodobností:
Nakonec vezmeme třídu s nejvyšší pravděpodobností, kterou je třída „Kuchaři“:
Výhody a omezení tohoto algoritmu
Výhody:
-
Je to velmi rychlý klasifikátor.
-
Je snadné implementovat.
-
Neexistuje žádná tréninková fáze, ale je to pouze odvození.
-
K vyvození závěrů nepotřebuje mnoho dat.
Omezení:
- Naivní Bayes předpokládá, že vstupní proměnné jsou nezávislé, což není vždy pravda.
- Naivní Bayes trpí problémem s nulovou frekvencí: je to tehdy, když vstupní proměnné přiřazuje nulovou pravděpodobnost. Tím se vynuluje všechna podmíněná pravděpodobnost P(C|x). Jeden trik, jak se tomu vyhnout, je použít minimální frekvenci 1 (místo 0) pro všechny proměnné.
Cvičení
Zde je datový rámec stejné datové sady, kterou jsme viděli v příkladu.
Vaším úkolem je implementovat Naive Bayes sami pomocí pythonu:
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
Řešení
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