Machine Learning Academy · Oppitunti

Bayesin teoreema selkokielellä

Käy läpi konkreettinen lääketieteellisen testin esimerkki ja rakenna intuitio ennakkotodennäköisyydestä, uskottavuudesta ja posterioritodennäköisyydestä ilman raskasta matematiikkaa.

Oppitunti 1/413 vaihetta

Bayesin teoreema selkokielellä on ilmainen Machine Learning Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Machine Learning Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Mikä on Bayesin teoreema?

Bayesin teoreema on matemaattinen sääntö, jonka avulla uskomuksia päivitetään uuden näytön perusteella. Se vastaa kysymykseen: Kun havaitsin X:n, kuinka todennäköinen hypoteesi H on? Kaava on: P(H|X) = P(X|H) * P(H) / P(X). Selkokielisesti: H:n jälkitodennäköisyys X:n perusteella on X:n havaitsemisen uskottavuus siinä tapauksessa, että H on tosi, kerrottuna H:n prioritodennäköisyydellä ja jaettuna X:n havaitsemisen kokonaistodennäköisyydellä. Bayesin teoreema on keskeinen koneoppimisessa, tilastotieteessä ja epävarmuuden vallitessa tehtävässä järkevässä päättelyssä.

# Bayes' theorem components:
# P(H|X)  = Posterior  -- What we want to know
#                         'Probability of H given we observed X'
# P(X|H)  = Likelihood -- How likely is X if H is true?
# P(H)    = Prior      -- Our belief in H before seeing X
# P(X)    = Evidence   -- Overall probability of observing X

# Rearranged:
# Posterior = (Likelihood * Prior) / Evidence

print('Posterior = (Likelihood * Prior) / Evidence')

Lääketieteellinen testiesimerkki

Muodostetaan intuitiota klassisen esimerkin avulla. Harvinainen sairaus koskee yhtä prosenttia väestöstä. Testi on 95-prosenttisesti tarkka: jos henkilöllä on sairaus, testitulos on positiivinen 95 prosentissa tapauksista; jos sairautta ei ole, testitulos on negatiivinen 95 prosentissa tapauksista (väärien positiivisten tulosten osuus on 5 %). Jos testitulos on positiivinen, mikä on todennäköisyys, että henkilöllä todella on sairaus? Useimpien intuitio vastaa 95 %, mutta Bayesin teoreema osoittaa, että todennäköisyys on paljon pienempi – koska sairaus on niin harvinainen, useimmat positiiviset tulokset ovat todellisuudessa vääriä positiivisia.

# Medical test: Bayes' theorem applied
P_disease    = 0.01   # Prior: 1% have the disease
P_no_disease = 0.99   # 99% are healthy

P_pos_given_disease    = 0.95  # True positive rate (sensitivity)
P_pos_given_no_disease = 0.05  # False positive rate

# P(positive) = total probability of a positive test
P_positive = (P_pos_given_disease * P_disease +
              P_pos_given_no_disease * P_no_disease)

# Bayes: P(disease | positive)
P_disease_given_pos = (P_pos_given_disease * P_disease) / P_positive

print(f'P(disease | positive test) = {P_disease_given_pos:.2%}')
# Only ~16%! Not 95% -- the low prior dominates

Prioritodennäköisyys, uskottavuus ja jälkitodennäköisyys

Bayesin teoreeman kolme keskeistä termiä ovat seuraavat: Prioritodennäköisyys P(H) on uskomus H:sta ennen näytön näkemistä – lääketieteellisessä esimerkissä sairauden 1 prosentin esiintyvyys. Uskottavuus P(X|H) kertoo, kuinka hyvin hypoteesi H selittää näytön X – tässä tapauksessa todellinen positiivinen tulos 95 prosentin todennäköisyydellä. Jälkitodennäköisyys P(H|X) on päivitetty uskomus sen jälkeen, kun näyttö on otettu huomioon. Yhden havainnon perusteella laskettu jälkitodennäköisyys toimii seuraavan havainnon prioritodennäköisyytenä – Bayesin teoreema kuvaa jatkuvaa oppimisprosessia, jossa uskomuksia päivitetään näytön kertyessä.

# Sequential Bayesian updating
# Start with 1% prior, observe 3 positive tests

prior = 0.01
P_pos_given_disease = 0.95
P_pos_given_no_disease = 0.05

for test_num in range(1, 4):
    likelihood_pos = P_pos_given_disease
    P_positive = likelihood_pos * prior + P_pos_given_no_disease * (1 - prior)
    posterior = (likelihood_pos * prior) / P_positive
    
    print(f'After test {test_num}: P(disease) = {posterior:.3%}')
    prior = posterior  # Posterior becomes new prior

# Three positive tests raise probability substantially

Bayesin teoreema luokittelussa

Koneoppimisen luokittelussa Bayesin teoreema antaa kunkin luokan todennäköisyyden havaittujen ominaisuuksien perusteella: P(class | features) ∝ P(features | class) * P(class). Ennustamme luokan, jolla on suurin jälkitodennäköisyys. P(class) arvioidaan luokkien esiintymistiheyksistä koulutusdatassa (prioritodennäköisyys). P(features | class) arvioidaan kunkin luokan sisäisestä ominaisuusjakaumasta (uskottavuus). Naive Bayes yksinkertaistaa uskottavuuden laskemista olettamalla, että ominaisuudet ovat luokkaan nähden toisistaan riippumattomia – ”naiivi” oletus toimii käytännössä usein yllättävän hyvin.

# Classification with Bayes' theorem
# Predict P(spam | email_features) vs P(ham | email_features)

# Prior (from training data)
P_spam = 0.3  # 30% of emails are spam
P_ham  = 0.7  # 70% are ham

# Likelihood: P(features | class) from training
# (simplified: single word 'offer' seen)
P_offer_given_spam = 0.6  # 'offer' appears in 60% of spam
P_offer_given_ham  = 0.1  # 'offer' appears in 10% of ham

# Unnormalised posteriors (ignore P(offer) -- same denominator)
posterior_spam = P_offer_given_spam * P_spam  # 0.18
posterior_ham  = P_offer_given_ham  * P_ham   # 0.07

print('Unnormalised: spam=', posterior_spam, 'ham=', posterior_ham)
print('Predicted class: spam' if posterior_spam > posterior_ham else 'ham')

Kokonaistodennäköisyyden laki

Bayesin teoreeman nimittäjä P(X) lasketaan usein kokonaistodennäköisyyden lain avulla: P(X) = sum over all classes c of P(X|c) * P(c). Tämä varmistaa, että kaikkien luokkien jälkitodennäköisyydet summautuvat yhteen. Lääketieteellisessä esimerkissä P(positive) = P(positive|disease)*P(disease) + P(positive|no disease)*P(no disease). Naive Bayes -luokittelussa P(X):n laskeminen yleensä ohitetaan, koska se on sama kaikille luokille – vertaamme vain normalisoimattomia jälkitodennäköisyyksiä löytääksemme todennäköisimmän luokan.

# Law of total probability: P(X) = sum_c P(X|c) * P(c)
classes  = ['spam', 'ham', 'newsletter']
priors   = [0.3,    0.5,   0.2]          # Must sum to 1.0
P_word_given_class = [0.5, 0.1, 0.3]     # Likelihood of 'free' in each class

# Total probability of seeing the word 'free'
P_free = sum(lik * pri for lik, pri in zip(P_word_given_class, priors))
print(f'P(free) = {P_free}')

# Posteriors (normalised)
for cls, pri, lik in zip(classes, priors, P_word_given_class):
    posterior = lik * pri / P_free
    print(f'P({cls} | free) = {posterior:.3f}')

Kaavasta algoritmiksi

Bayesin teoreema voidaan muuntaa suoraan luokittelualgoritmiksi. Kun käytettävissä on nimetty koulutusjoukko: Vaihe 1: arvioikaa kunkin luokan P(class) luokkien esiintymistiheyksien perusteella. Vaihe 2: arvioikaa jokaiselle ominaisuuden ja luokan yhdistelmälle P(feature | class). Vaihe 3: laskekaa uuden näytteen tapauksessa kullekin luokalle P(class | features) ∝ P(features | class) * P(class). Vaihe 4: ennustakaa luokka, jolla on suurin jälkitodennäköisyys. Naive Bayesin ”naiivi” approksimaatio yksinkertaistaa vaihetta 2: oletetaan, että P(features|class) = product of P(feature_i | class) for all features.

# Naive Bayes algorithm in pseudocode

# Training:
# For each class c:
#   prior[c] = count(class==c) / total_samples
#   For each feature f:
#     likelihood[c][f] = P(feature_f | class==c)  # from training data

# Prediction for new sample x:
# For each class c:
#   log_prob[c] = log(prior[c])
#   For each feature f:
#     log_prob[c] += log(likelihood[c][f=x_f])  # naive: assume independence
# return argmax(log_prob)  # class with highest log-posterior

print('Naive independence assumption: P(f1,f2,...|c) = P(f1|c)*P(f2|c)*...*P(fn|c)')

Miksi logaritmiset todennäköisyydet estävät alivuodon

Kun useita pieniä todennäköisyyksiä kerrotaan keskenään, tulos alivuotaa liukulukuaritmetiikassa nopeasti nollaksi – vaikka arvo on matemaattisesti erittäin pieni mutta nollasta poikkeava. Esimerkiksi 100 sanaa sisältävän dokumentin tapauksessa, kun kunkin sanan P(word|class)=0.01, saadaan 0.01^100 = 10^{-200}, mikä alittaa pienimmän float64-arvon. Logaritmiavaruudessa työskentely muuttaa kertolaskun yhteenlaskuksi: log(a*b) = log(a) + log(b). Koska vertaamme logaritmisia jälkitodennäköisyyksiä emmekä varsinaisia jälkitodennäköisyyksiä, argmax-päätös on sama. Naive Bayes -toteutukset toimivat aina logaritmiavaruudessa numeerisen vakauden varmistamiseksi.

import numpy as np

# Direct multiplication: underflows
probs = [0.1] * 100  # 100 features, each P=0.1
product = np.prod(probs)
print('Direct product:', product)  # 0.0 -- underflow!

# Log space: numerically stable
log_sum = np.sum(np.log(probs))
print('Log sum:', log_sum)         # -100 * log(10) -- valid

# Compare two classes
log_prob_A = np.sum(np.log([0.1] * 100))
log_prob_B = np.sum(np.log([0.2] * 100))
print('Class A log-prob:', log_prob_A)
print('Class B log-prob:', log_prob_B)
print('Predicted:', 'A' if log_prob_A > log_prob_B else 'B')

Bayes-optimaalinen luokitin: kultainen standardi

Bayes-optimaalinen luokitin on tietylle datajakaumalle teoreettisesti paras mahdollinen luokitin. Se ennustaa luokan, jolla on suurin todellinen jälkitodennäköisyys P(class|features). Mikään muu luokitin ei voi saavuttaa kyseisessä jakaumassa pienempää odotettua virhesuhdetta. Käytännössä Bayes-optimaalista luokitinta ei voida käyttää, koska todellisia jakaumia ei tunneta – voimme vain arvioida niitä rajallisesta datasta. Naive Bayes on Bayes-optimaalisen luokittimen approksimaatio riippumattomuusoletuksen vallitessa. Kun oletus pitää paikkansa, Naive Bayes on optimaalinen luokitin.

# The Bayes error rate is the irreducible error
# Even a perfect model cannot beat it on a given distribution

# Example: predicting coin flip from noisy signal
import numpy as np

np.random.seed(42)
# True label: 50/50 coin
y_true = np.random.choice([0, 1], size=1000)
# Signal: 70% correlated with true label
signal = np.where(np.random.rand(1000) < 0.7, y_true, 1-y_true)

# Optimal prediction: just use the signal
acc = (signal == y_true).mean()
print(f'Optimal classifier accuracy: {acc:.3f}')
print(f'Bayes error rate (irreducible): {1-0.70:.3f} = 30%')

Bayesin teoreeman tosielämän sovellukset

Bayesin teoreema ei ole vain oppikirjakaava – se ohjaa monia todellisia järjestelmiä. Sähköpostin roskapostisuodattimet laskevat P(spam | words) tunnettujen roskaposti- ja asiallisten viestien sanatiheyksien perusteella. Lääketieteelliset diagnoosijärjestelmät päivittävät sairauksien todennäköisyyksiä testitulosten saapuessa. Hakukoneet käyttävät bayesilaista järjestämistä yhdistääkseen kyselyn relevanssin ja asiakirjan suosion. Autonomiset ajoneuvot käyttävät bayesilaista suodatusta (Kalman-suodatin, partikkelisuodatin) sijaintinsa seuraamiseen kohinaisista anturimittauksista. A/B-testauksessa käytetään teollisuudessa yhä useammin bayesilaisia menetelmiä, jotka tuottavat todennäköisyyden sille, mikä vaihtoehto on paras, p-arvojen sijaan.

# Real-world Bayes: A/B test - which version is better?
# After 100 conversions from 1000 visitors for version A
# and 120 conversions from 1000 visitors for version B:

from scipy import stats

# Beta distribution as posterior for conversion rate
alpha_A, beta_A = 100 + 1, 900 + 1  # Beta(successes+1, failures+1)
alpha_B, beta_B = 120 + 1, 880 + 1

# Monte Carlo: P(B is better than A)
samples_A = stats.beta(alpha_A, beta_A).rvs(100000)
samples_B = stats.beta(alpha_B, beta_B).rvs(100000)

P_B_better = (samples_B > samples_A).mean()
print(f'P(B is better than A): {P_B_better:.3f}')

Riippumattomuusoletus: milloin se pätee?

Naive Bayesin ”naiivi” osa olettaa, että ominaisuudet ovat ehdollisesti riippumattomia luokan perusteella. Tekstidatassa tämä tarkoittaa, että kunkin sanan esiintymisen oletetaan olevan riippumatonta muista sanoista, kun luokka tunnetaan. Todellisuudessa esimerkiksi sanat ”credit” ja ”card” esiintyvät yhdessä – ne korreloivat keskenään. Empiiriset tutkimukset kuitenkin osoittavat, että Naive Bayes toimii hyvin riippumattomuusoletuksen rikkoutumisesta huolimatta, koska: (1) luokittelun järjestämiseen tarvitaan vain jälkitodennäköisyyksien oikea järjestys, ei tarkkoja todennäköisyyksiä; (2) monet ominaisuudet yhdistävät toisistaan riippumattomat signaalit tehokkaasti; (3) yksinkertaisuus estää ylisovittamista pienissä aineistoissa.

# When does naive independence work?
# Even with correlated features, naive bayes often ranks classes correctly

import numpy as np

# Two correlated features that both indicate spam
words = {'buy': 0, 'now': 1, 'click': 2, 'here': 3}

# Spam email often has all four; ham rarely does
# Independence assumption ignores that 'buy' and 'now' co-occur
# But the combined signal is still strong for detecting spam

P_word_spam = [0.7, 0.6, 0.5, 0.6]
P_word_ham  = [0.1, 0.1, 0.05, 0.1]

# For email with all 4 words
log_spam = np.sum(np.log(P_word_spam))
log_ham  = np.sum(np.log(P_word_ham))
print('Log P(features|spam):', log_spam.round(2))
print('Log P(features|ham): ', log_ham.round(2))
print('Predicted: SPAM' if log_spam > log_ham else 'HAM')

Bayes-tekijä: hypoteesien vertailu

Bayesin tekijä on kahden kilpailevan hypoteesin uskottavuuksien suhde: BF = P(evidence | H1) / P(evidence | H0). Toisin kuin p-arvot, jotka kertovat vain, hylätäänkö nollahypoteesi, Bayesin tekijä ilmaisee määrällisesti, kuinka paljon näyttö tukee toista hypoteesia toisen sijaan. BF > 10 on vahvaa näyttöä H1:n puolesta; BF < 0.1 on vahvaa näyttöä H0:n puolesta; arvot välillä 1/3–3 eivät anna ratkaisevaa näyttöä. Bayesin tekijöitä käytetään yhä enemmän tieteessä ja teollisuudessa A/B-testaukseen ja hypoteesien arviointiin, koska niissä aiempi tieto otetaan luontevasti huomioon ja näytön vahvuus esitetään tulkittavassa muodossa.

# Bayes Factor example: comparing two models
# H0: coin is fair (p=0.5)
# H1: coin is biased (p=0.7)
# Observed: 8 heads in 10 flips

from scipy.stats import binom

observed_heads = 8
n_flips = 10

# Likelihood under each hypothesis
L_H0 = binom.pmf(observed_heads, n_flips, p=0.5)
L_H1 = binom.pmf(observed_heads, n_flips, p=0.7)

BF = L_H1 / L_H0
print(f'P(8 heads | fair coin) = {L_H0:.4f}')
print(f'P(8 heads | p=0.7)    = {L_H1:.4f}')
print(f'Bayes Factor (H1/H0)  = {BF:.2f}')
print('BF > 3: moderate evidence for biased coin')

Pikatarkistus

Testaa, miten hyvin ymmärrät tämän oppitunnin Pythonin koneoppimista koskevat käsitteet.

Oppitunnin kertaus

Tässä oppitunnissa opit, että Bayesin lause päivittää ennakkokäsityksiä näytön avulla ja tuottaa jälkikäsityksiä, tutustuit kolmeen osaan (ennakkotodennäköisyys, uskottavuus ja jälkitodennäköisyys) sekä niiden vuorovaikutukseen ja opit, miksi pienet ennakkotodennäköisyydet voivat hallita tulosta jopa erittäin tarkkojen testien tapauksessa (kuten lääketieteellisessä diagnoosiesimerkissä). Seuraavaksi tutustumme Bag of Words -menetelmään sekä CountVectorizer- ja TfidfVectorizer-luokkiin, joilla teksti muunnetaan luvuiksi Naive Bayes -luokitusta varten.

Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Bayesin teoreema selkokielellä” ilmainen?

Kyllä – oppitunnin ”Bayesin teoreema selkokielellä” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Machine Learning Academy-kurssin, päivitä CoddyKit PROhon. Machine Learning Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Bayesin teoreema selkokielellä”?

Käy läpi konkreettinen lääketieteellisen testin esimerkki ja rakenna intuitio ennakkotodennäköisyydestä, uskottavuudesta ja posterioritodennäköisyydestä ilman raskasta matematiikkaa. Harjoittelet Machine Learning Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Machine Learning Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Machine Learning Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”Bayesin teoreema selkokielellä”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Machine Learning Academy-oppitunnilla?

Kyllä. Jokainen Machine Learning Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Bayesin teoreema selkokielellä
  2. Bag of Words: CountVectorizer ja TfidfVectorizer
  3. Multinomiaalisen Naive Bayes -luokittimen opettaminen
  4. Laplace-tasoitus ja nollatodennäköisyyden ongelma
← Takaisin: Machine Learning Academy