Gaussin naiivin Bayes-luokittimen päätösalue. Kuva tekijältä.
Mielestäni tämä on klassikko jokaisen datatieteen uran alussa: Naiivi Bayes -luokitin. Tai minun pitäisi pikemminkin sanoa perhe naiiveista Bayes-luokittelijoista, koska niitä on monia makuja. Esimerkiksi on olemassa moninominen naiivi Bayes, Bernoullin naiivi Bayes ja myös Gaussin naiivi Bayes, joista jokainen eroaa vain yhdessä pienessä yksityiskohdassa, kuten tulemme selvittämään. Naiivit Bayes-algoritmit ovat suunnittelultaan melko yksinkertaisia, mutta osoittautuivat hyödyllisiksi monissa monimutkaisissa reaalimaailman tilanteissa.
Tässä artikkelissa voit oppia
- kuinka naiivit Bayes-luokittelut toimivat,
- miksi on järkevää määritellä ne sellaisina kuin ne ovat ja
- kuinka ne otetaan käyttöön Pythonissa NumPyn avulla.
Löydät koodin osoitteesta minun Github.
Saattaa hieman auttaa, kun tutustun Bayesin tilastoihin Lempeä johdanto Bayesilaiseen päättelyyn tottua Bayesin kaavaan. Koska toteutamme luokittelijan scikit-oppimismukaisella tavalla, kannattaa myös tutustua artikkeliini Rakenna oma mukautettu scikit-learn Regression. Scikit-learnin lisäkustannukset ovat kuitenkin melko pienet ja sinun pitäisi pystyä seuraamaan mukana joka tapauksessa.
Aloitamme naiivin Bayes-luokituksen hämmästyttävän yksinkertaisen teorian tutkimisen ja siirrymme sitten toteutukseen.
Mistä olemme todella kiinnostuneita luokittelussa? Mitä me oikeastaan teemme, mikä on panos ja tulos? Vastaus on yksinkertainen:
Millä todennäköisyydellä x kuuluu johonkin luokkaan c, kun on annettu datapiste x?
Siinä kaikki, mitä haluamme vastata Kaikki luokittelu. Voit mallintaa tämän lauseen suoraan ehdollisena todennäköisyytenä: p(c|x).
Esimerkiksi jos niitä on
- 3-luokat c₁, c₂, c₃ja
- x koostuu 2 ominaisuudesta xXNUMX, x₂,
luokittelun tulos voisi olla jotain tällaista p(c₁|xXNUMX, x₂)=0.3, p(c₂|xXNUMX, x₂)=0.5 ja p(c₃|xXNUMX, x₂)=0.2. Jos välitämme tulosteena yhdestä etiketistä, valitsisimme suurimman todennäköisyyden, ts c₂ 50 % todennäköisyydellä täällä.
Naiivi Bayes-luokitin yrittää laskea nämä todennäköisyydet suoraan.
Naiivi Bayes
Ok, annettu datapiste x, haluamme laskea p(c|x) kaikille luokille c ja tulosta sitten c suurimmalla todennäköisyydellä. Kaavoissa näet tämän usein näin
Kuva tekijältä.
Huomautus: max p(c|x) palauttaa suurimman todennäköisyyden, kun taas argmax p(c|x) palauttaa c tällä suurimmalla todennäköisyydellä.
Mutta ennen kuin voimme optimoida p(c|x), meidän on kyettävä laskemaan se. Tätä varten käytämme Bayesin lause:
Bayesin lause. Kuva tekijältä.
Tämä on Bayesin osa naiivista Bayesistä. Mutta nyt meillä on seuraava ongelma: Mitä ovat p(x|c) Ja p(c)?
Tästä naiivin Bayes-luokittelijan koulutuksessa on kyse.
Treeni
Kaiken havainnollistamiseksi käytämme lelutietosarjaa kaksi todellista ominaisuutta xXNUMX, x₂ja kolme luokkaa c₁, c₂, c₃ seuraavassa.
Data, visualisoituna. Kuva tekijältä.
Voit luoda tämän tarkan tietojoukon kautta
from sklearn.datasets import make_blobs X, y = make_blobs(n_samples=20, centers=[(0,0), (5,5), (-5, 5)], random_state=0)
Aloitetaan luokan todennäköisyys p(c), todennäköisyys, että jokin luokka c havaitaan merkityssä tietojoukossa. Yksinkertaisin tapa arvioida tämä on vain laskea luokkien suhteelliset taajuudet ja käyttää niitä todennäköisyyksinä. Voimme käyttää tietojoukkoamme nähdäksemme, mitä tämä tarkoittaa tarkalleen.
Luokassa on 7 pistettä 20 pisteestä c₁ (sininen) tietojoukossa, siksi sanomme p(c₁)=7/20. Meillä on 7 pistettä luokasta c₂ (punainen) myös, joten asetamme p(c₂)=7/20. Viimeinen luokka c₃ (keltainen) on siis vain 6 pistettä p(c₃)=6/20.
Tämä yksinkertainen luokan todennäköisyyksien laskenta muistuttaa maksimitodennäköisyyden lähestymistapaa. Voit kuitenkin käyttää myös toista aikaisempi jakelu, jos haluat. Jos esimerkiksi tiedät, että tämä tietojoukko ei edusta todellista populaatiota, koska luokka c₃ pitäisi näkyä 50 %:ssa tapauksista, määrität sitten p(c₁)=0.25, p(c₂)=0.25 ja p(c₃)=0.5. Mikä tahansa auttaa sinua parantamaan testisarjan suorituskykyä.
Nyt käännymme todennäköisyys p(x|c)=p(xXNUMX, x₂|c). Yksi tapa laskea tämä todennäköisyys on suodattaa tietojoukko näytteille, joissa on etiketti c ja yritä sitten löytää jakauma (esim. 2-ulotteinen Gaussin), joka kaappaa piirteet xXNUMX, x₂.
Valitettavasti meillä ei yleensä ole tarpeeksi näytteitä luokkaa kohden tehdäksemme oikean arvion todennäköisyydestä.
Voidaksemme rakentaa kestävämmän mallin teemme naiivi oletus että ominaisuudet xXNUMX, x₂ olemme stokastisesti riippumaton, annettu c. Tämä on vain hieno tapa tehdä matematiikasta helpompaa kautta
Kuva tekijältä
jokaiselle luokalle c. Tässä on naiivi osa naiiveista Bayesistä tulee, koska tämä yhtälö ei päde yleisesti. Silti naiivi Bayes tuottaa silloinkin hyviä, joskus erinomaisia tuloksia käytännössä. Erityisesti NLP-ongelmissa, joissa on sanapussiominaisuuksia, moninomi-naiivi Bayes loistaa.
Yllä annetut argumentit ovat samat kaikille naiiveille Bayes-luokittelijoille, joita voit löytää. Nyt se riippuu vain mallista p(xXNUMX|cXNUMX), p(xXNUMX|cXNUMX), p(xXNUMX|cXNUMX), p(xXNUMX|c₂), p(xXNUMX|cXNUMX) ja p(x₂|cXNUMX).
Jos ominaisuudet ovat vain 0 ja 1, voit käyttää a Bernoullin jakauma. Jos ne ovat kokonaislukuja, a Multinomiaalinen jakelu. Meillä on kuitenkin todellisia ominaisuusarvoja ja päätämme a Gaussin jakauma, josta nimi Gaussin naiivi Bayes. Otamme seuraavan muodon
Kuva tekijältä.
jossa μᵢ,ⱼ on keskiarvo ja σᵢ,ⱼ on keskihajonta, joka meidän on arvioitava tiedoista. Tämä tarkoittaa, että saamme yhden keskiarvon jokaiselle ominaisuudelle i yhdistettynä luokkaan cⱼ, meidän tapauksessamme 2*3=6 tarkoittaa. Sama pätee standardipoikkeamiin. Tämä vaatii esimerkkiä.
Yritetään arvioida μ₂,₁ ja σ₂,₁. Koska j=1, olemme kiinnostuneita vain luokasta c₁, säilytetään vain tällä tarralla varustetut näytteet. Seuraavat näytteet ovat jäljellä:
# samples with label = c_1 array([[ 0.14404357, 1.45427351], [ 0.97873798, 2.2408932 ], [ 1.86755799, -0.97727788], [ 1.76405235, 0.40015721], [ 0.76103773, 0.12167502], [-0.10321885, 0.4105985 ], [ 0.95008842, -0.15135721]])
Nyt sen takia i=2 meidän on otettava huomioon vain toinen sarake. μ₂,₁ on keskiarvo ja σ₂,₁ tämän sarakkeen keskihajonta, ts μ₂,₁ = 0.49985176 ja σ₂,₁ = 0.9789976.
Nämä luvut ovat järkeviä, jos katsot sirontadiagrammia uudelleen ylhäältä. Ominaisuudet x₂ luokan näytteistä c₁ ovat noin 0.5, kuten kuvasta näkyy.
Laskemme tämän nyt viidelle muulle yhdistelmälle ja olemme valmiita!
Pythonissa voit tehdä sen seuraavasti:
from sklearn.datasets import make_blobs
import numpy as np # Create the data. The classes are c_1=0, c_2=1 and c_3=2.
X, y = make_blobs( n_samples=20, centers=[(0, 0), (5, 5), (-5, 5)], random_state=0
) # The class probabilities.
# np.bincounts counts the occurence of each label.
prior = np.bincount(y) / len(y) # np.where(y==i) returns all indices where the y==i.
# This is the filtering step.
means = np.array([X[np.where(y == i)].mean(axis=0) for i in range(3)])
stds = np.array([X[np.where(y == i)].std(axis=0) for i in range(3)])
Me vastaanotamme
# priors
array([0.35, 0.35, 0.3 ])
# means array([[ 0.90889988, 0.49985176], [ 5.4111385 , 4.6491892 ], [-4.7841679 , 5.15385848]])
# stds
array([[0.6853714 , 0.9789976 ], [1.40218915, 0.67078568], [0.88192625, 1.12879666]])
Tämä on tulos Gaussin naiivin Bayes-luokittajan koulutuksesta.
Ennusteiden tekeminen
Täydellinen ennustuskaava on
Kuva tekijältä.
Oletetaan uusi datapiste x*=(-2, 5) tulee sisään.
Kuva tekijältä.
Lasketaan, mihin luokkaan se kuuluu p(c|x*) kaikille luokille. Kuvasta sen pitäisi kuulua luokkaan c₃ = 2, mutta katsotaanpa. Jätetään huomioimatta nimittäjä p(x) sekunnin ajan. Seuraavaa silmukkaa käyttäen laskettiin nimittäjät kohteelle j = 1, 2, 3.
x_new = np.array([-2, 5]) for j in range(3): print( f"Probability for class {j}: {(1/np.sqrt(2*np.pi*stds[j]**2)*np.exp(-0.5*((x_new-means[j])/stds[j])**2)).prod()*p[j]:.12f}" )
Me vastaanotamme
Probability for class 0: 0.000000000263
Probability for class 1: 0.000000044359
Probability for class 2: 0.000325643718
Tietysti nämä todennäköisyydet (meidän ei pitäisi kutsua niitä sillä tavalla) älä laske yhteen, koska jätimme huomioimatta nimittäjän. Tämä ei kuitenkaan ole ongelma, koska voimme vain ottaa nämä normalisoimattomat todennäköisyydet ja jakaa ne niiden summalla, jolloin ne laskevat yhteen. Joten jakamalla nämä kolme arvoa niiden summalla noin 0.00032569, saamme
Kuva tekijältä.
Selkeä voittaja, kuten odotimme. Nyt toteutetaan se!
Tämä toteutus ei ole selvästikään tehokas, ei numeerisesti vakaa, se palvelee vain koulutustarkoitusta. Olemme keskustelleet useimmista asioista, joten sen pitäisi olla nyt helppo seurata. Voit jättää huomioimatta kaikki check
toimintoja tai lue artikkelini Rakenna oma mukautettu scikit-learn jos olet kiinnostunut siitä, mitä he tarkalleen tekevät.
Huomaa vain, että toteutin a predict_proba
menetelmä ensin todennäköisyyksien laskemiseksi. Menetelmä predict
vain kutsuu tätä menetelmää ja palauttaa indeksin (=luokka) suurimmalla todennäköisyydellä käyttämällä argmax-funktiota (se on taas!). Tunti odottaa luokkia 0- k-1, missä k on luokkien lukumäärä.
import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn.utils.validation import check_X_y, check_array, check_is_fitted class GaussianNaiveBayesClassifier(BaseEstimator, ClassifierMixin): def fit(self, X, y): X, y = check_X_y(X, y) self.priors_ = np.bincount(y) / len(y) self.n_classes_ = np.max(y) + 1 self.means_ = np.array( [X[np.where(y == i)].mean(axis=0) for i in range(self.n_classes_)] ) self.stds_ = np.array( [X[np.where(y == i)].std(axis=0) for i in range(self.n_classes_)] ) return self def predict_proba(self, X): check_is_fitted(self) X = check_array(X) res = [] for i in range(len(X)): probas = [] for j in range(self.n_classes_): probas.append( ( 1 / np.sqrt(2 * np.pi * self.stds_[j] ** 2) * np.exp(-0.5 * ((X[i] - self.means_[j]) / self.stds_[j]) ** 2) ).prod() * self.priors_[j] ) probas = np.array(probas) res.append(probas / probas.sum()) return np.array(res) def predict(self, X): check_is_fitted(self) X = check_array(X) res = self.predict_proba(X) return res.argmax(axis=1)
Toteutuksen testaus
Vaikka koodi on melko lyhyt, se on silti liian pitkä ollaksemme täysin varmoja siitä, ettemme ole tehneet virheitä. Joten tarkistakaamme, kuinka se pärjää scikit-learn GaussianNB-luokitin.
my_gauss = GaussianNaiveBayesClassifier()
my_gauss.fit(X, y)
my_gauss.predict_proba([[-2, 5], [0,0], [6, -0.3]])
lähdöt
array([[8.06313823e-07, 1.36201957e-04, 9.99862992e-01], [1.00000000e+00, 4.23258691e-14, 1.92051255e-11], [4.30879705e-01, 5.69120295e-01, 9.66618838e-27]])
Ennusteet käyttäen predict
menetelmä ovat
# my_gauss.predict([[-2, 5], [0,0], [6, -0.3]])
array([2, 0, 1])
Nyt käytetään scikit-learniä. Heitä jotain koodia
from sklearn.naive_bayes import GaussianNB gnb = GaussianNB()
gnb.fit(X, y)
gnb.predict_proba([[-2, 5], [0,0], [6, -0.3]])
saannot
array([[8.06314158e-07, 1.36201959e-04, 9.99862992e-01], [1.00000000e+00, 4.23259111e-14, 1.92051343e-11], [4.30879698e-01, 5.69120302e-01, 9.66619630e-27]])
Numerot näyttävät tavallaan samanlaisilta kuin luokittimemme numerot, mutta ne ovat hieman poikkeavia viimeisistä näytetyistä numeroista. Teimmekö jotain väärin? Ei. Scikit-learn-versio vain käyttää toista hyperparametria var_smoothing=1e-09
. Jos asetamme tämän nolla-, saamme tarkalleen numeromme. Täydellinen!
Tutustu luokittimemme päätösalueisiin. Merkkasin myös kolme pistettä, joita käytimme testauksessa. Tällä yhdellä pisteellä lähellä rajaa on vain 56.9 % mahdollisuus kuulua punaiseen luokkaan, kuten voit nähdä predict_proba
ulostulot. Kaksi muuta pistettä luokitellaan paljon korkeammalla varmuudella.
Päätösalueet 3 uudella pisteellä. Kuva tekijältä.
Tässä artikkelissa olemme oppineet, kuinka Gaussin naiivi Bayes-luokitin toimii, ja antanut intuition siitä, miksi se on suunniteltu sellaiseksi – se on suora lähestymistapa kiinnostavan todennäköisyyden mallintamiseen. Vertaa tätä logistiseen regressioon: siellä todennäköisyys mallinnetaan lineaarisella funktiolla, jonka päällä on sigmoidifunktio. Se on silti helppo malli, mutta se ei tunnu niin luonnolliselta kuin naiivi Bayes-luokittelu.
Jatkoimme laskemalla muutamia esimerkkejä ja keräämällä hyödyllisiä koodinpätkiä matkan varrella. Lopuksi olemme toteuttaneet täydellisen Gaussin naiivin Bayes-luokituksen tavalla, joka toimii hyvin scikit-learnin kanssa. Tämä tarkoittaa, että voit käyttää sitä esimerkiksi putkissa tai ruudukkohaussa.
Lopuksi teimme pienen mielenterveyden tarkistuksen tuomalla scikit-learnsin oman Gaussin naiivin Bayes-luokituksen ja testaamalla, tuottavatko sekä meidän että scikit-learnin luokitin saman tuloksen. Tämä testi onnistui.
Tri Robert Kübler on tietotutkija Publicis Mediassa ja kirjoittaja Towards Data Science -palvelussa.
Alkuperäinen. Postitettu luvalla.
- SEO-pohjainen sisällön ja PR-jakelu. Vahvista jo tänään.
- Platoblockchain. Web3 Metaverse Intelligence. Tietoa laajennettu. Pääsy tästä.
- Lähde: https://www.kdnuggets.com/2023/03/gaussian-naive-bayes-explained.html?utm_source=rss&utm_medium=rss&utm_campaign=gaussian-naive-bayes-explained
- :On
- $ YLÖS
- 1
- 7
- 8
- 9
- a
- pystyy
- Meistä
- edellä
- todella
- vastaan
- algoritmit
- Kaikki
- ja
- Toinen
- vastaus
- näyttää
- sovellettu
- lähestymistapa
- OVAT
- perustelut
- noin
- artikkeli
- AS
- At
- kirjoittaja
- pohja
- Bayes
- BE
- koska
- ennen
- Alku
- Bitti
- sininen
- reunus
- rakentaa
- by
- laskea
- laskettaessa
- soittaa
- Puhelut
- CAN
- kaappaa
- joka
- Ura
- tapaus
- tapauksissa
- mahdollisuus
- tarkastaa
- Valita
- luokka
- luokat
- klassinen
- luokittelu
- luokiteltu
- selkeä
- lähellä
- koodi
- Kerääminen
- Sarake
- yhdistelmät
- Tulla
- verrata
- täydellinen
- täysin
- monimutkainen
- Laskea
- luottamus
- Harkita
- jatkui
- voisi
- kytketty
- kurssi
- luoda
- asiakassuhde
- tiedot
- tietojenkäsittely
- tietojen tutkija
- aineistot
- päättää
- päätös
- riippuu
- Malli
- suunniteltu
- yksityiskohta
- poikkeama
- DID
- eri
- numeroa
- ohjata
- suoraan
- keskusteltiin
- jakelu
- tekee
- Dont
- e
- kukin
- helpompaa
- koulutus-
- tehokas
- tarpeeksi
- erityisesti
- arvio
- Jopa
- Joka
- kaikki
- täsmälleen
- esimerkki
- Esimerkit
- odotettu
- selitti
- Tutkiminen
- Ominaisuus
- Ominaisuudet
- harvat
- suodattaa
- suodatus
- Vihdoin
- Löytää
- Etunimi
- seurata
- jälkeen
- varten
- kaava
- alkaen
- toiminto
- tehtävät
- general
- lempeä
- saada
- tietty
- Goes
- hyvä
- ruudukko
- Olla
- auttaa
- auttaa
- tätä
- korkeampi
- suurin
- pitää
- Miten
- Kuitenkin
- HTML
- HTTPS
- i
- kuva
- toteuttaa
- täytäntöönpano
- täytäntöön
- tuoda
- tuovan
- parantaminen
- in
- indeksi
- Indeksit
- panos
- korko
- kiinnostunut
- esittely
- intuitio
- IT
- KDnuggets
- Pitää
- laji
- Tietää
- Merkki
- Sukunimi
- oppinut
- pitää
- vähän
- Pitkät
- katso
- tehdä
- TEE
- Tekeminen
- monet
- merkitty
- matematiikka
- maksimi
- välineet
- Media
- vain
- menetelmä
- ehkä
- virheitä
- malli
- lisää
- eniten
- nimi
- Luonnollinen
- Uusi
- NLP
- numero
- numerot
- numpy
- of
- on
- ONE
- Muut
- ulostulo
- erinomainen
- oma
- osa
- suorituskyky
- lupa
- kuva
- kappaletta
- Platon
- Platonin tietotieto
- PlatonData
- Kohta
- pistettä
- väestö
- harjoitusta.
- ennustus
- Ennusteet
- pohjamaali
- Aikaisempi
- todennäköisyys
- Ongelma
- ongelmia
- asianmukainen
- osoittautui
- tarkoitus
- Python
- pikemminkin
- Lue
- todellinen
- todellinen maailma
- punainen
- alue
- alueet
- regressio
- jäädä
- edustaja
- Muistuttaa
- johtua
- tulokset
- palata
- Tuotto
- ROBERT
- luja
- sama
- tiede
- Tiedemies
- scikit opittava
- Haku
- Toinen
- SELF
- tunne
- palvelee
- setti
- Lyhyt
- shouldnt
- samankaltainen
- Yksinkertainen
- koska
- single
- tilanteita
- pieni
- So
- jonkin verran
- jotain
- vakaa
- standardi
- Alkaa
- Lausunto
- Vaihe
- Yhä
- onnistunut
- ottaa
- testi
- Testaus
- että
- -
- heidän
- Niitä
- siksi
- Nämä
- asiat
- kolmella
- Throwing
- että
- liian
- ylin
- kohti
- lelu
- koulutus
- totta
- VUORO
- us
- käyttää
- yleensä
- validointi
- arvot
- versio
- Tapa..
- HYVIN
- Mitä
- Mikä on
- joka
- vaikka
- wikipedia
- tulee
- with
- Referenssit
- toimii
- kannattava
- olisi
- Väärä
- X
- tuotto
- saannot
- Sinun
- zephyrnet