Czym jest intuicyjne Wyjaśnienie techniki maksymalizacji oczekiwań? [zamknięte]

Maksymalizacja oczekiwań, jeśli rodzaj probabilistycznej metody klasyfikacji danych. Proszę mnie poprawić, jeśli się mylę, jeśli nie jest to klasyfikator.

Jakie jest intuicyjne wyjaśnienie tej techniki EM? Co to jest oczekiwanie i co jest maksymalizowane?

Author: Alex Riley, 2012-08-04

8 answers

uwaga: kod stojący za tą odpowiedzią można znaleźć tutaj .


Załóżmy, że mamy dane pobrane z dwóch różnych grup, czerwonej i niebieskiej:

Tutaj wpisz opis obrazka

Tutaj możemy zobaczyć, który punkt danych należy do Grupy Czerwonej lub niebieskiej. Ułatwia to znalezienie parametrów, które charakteryzują każdą grupę. Na przykład średnia z Grupy Czerwonej wynosi około 3, średnia z grupy niebieskiej wynosi około 7 (i możemy znaleźć dokładne środki, jeśli wanted).

Jest to, ogólnie rzecz biorąc, znane jako maksymalne oszacowanie prawdopodobieństwa . Biorąc pod uwagę niektóre dane, obliczamy wartość parametru (lub parametrów), który najlepiej wyjaśnia te dane.

Teraz wyobraź sobie, że nie możemy zobaczyć, która wartość została pobrana z jakiej grupy. Dla nas wszystko wygląda na fioletowe:

Tutaj wpisz opis obrazka

Tutaj mamy wiedzę, że istnieją dwie grupy wartości, ale nie wiemy, która grupa żadnej konkretnej wartości należy do.

Czy nadal możemy oszacować środki dla Grupy Czerwonej i niebieskiej, które najlepiej pasują do tych danych?

Tak, często możemy! maksymalizacja oczekiwań daje nam na to sposób. Bardzo ogólna idea algorytmu jest taka:
  1. zacznij od wstępnego oszacowania tego, co może być każdym parametrem.
  2. Oblicz prawdopodobieństwo , że każdy parametr tworzy punkt danych.
  3. Oblicz wagi dla każdego punktu danych wskazującego czy jest bardziej czerwony lub bardziej niebieski w oparciu o prawdopodobieństwo, że jest wytwarzany przez parametr. Połącz wagi z danymi ( ).
  4. Oblicz lepsze oszacowanie parametrów za pomocą danych dostosowanych do wagi (maksymalizacja ).
  5. powtórz kroki od 2 do 4, aż oszacowanie parametru zbiega się (proces przestaje wytwarzać inne oszacowanie).

Te kroki wymagają dalszych wyjaśnień, więc przejdę przez problem opisane powyżej.

Przykład: oszacowanie średniej i odchylenia standardowego

Użyję Pythona w tym przykładzie, ale kod powinien być dość łatwy do zrozumienia, jeśli nie jesteś zaznajomiony z tym językiem.

Załóżmy, że mamy dwie grupy, czerwoną i niebieską, z wartościami rozłożonymi jak na powyższym obrazku. W szczególności każda grupa zawiera wartość narysowaną z rozkładu normalnego o następujących parametrach:

import numpy as np
from scipy import stats

np.random.seed(110) # for reproducible results

# set parameters
red_mean = 3
red_std = 0.8

blue_mean = 7
blue_std = 2

# draw 20 samples from normal distributions with red/blue parameters
red = np.random.normal(red_mean, red_std, size=20)
blue = np.random.normal(blue_mean, blue_std, size=20)

both_colours = np.sort(np.concatenate((red, blue))) # for later use...

Oto zdjęcie tych czerwono-niebieskich grupy ponownie (aby uniknąć konieczności przewijania w górę):

Tutaj wpisz opis obrazka

Kiedy widzimy kolor każdego punktu (tj. do której grupy należy), bardzo łatwo jest oszacować średnie i odchylenie standardowe dla każdej grupy. Po prostu przekazujemy wartości czerwone i niebieskie do wbudowanych funkcji w NumPy. Na przykład:

>>> np.mean(red)
2.802
>>> np.std(red)
0.871
>>> np.mean(blue)
6.932
>>> np.std(blue)
2.195

Ale co jeśli nie możemy zobaczyć kolorów punktów? Oznacza to, że zamiast czerwonego lub niebieskiego każdy punkt został zabarwiony fioletowy.

Aby spróbować odzyskać średnie i standardowe parametry odchylenia dla grup czerwonych i niebieskich, możemy użyć maksymalizacji oczekiwań.

Nasz pierwszy krok (Krok 1 powyżej) to odgadnięcie wartości parametrów dla średniej i odchylenia standardowego każdej grupy. Nie musimy zgadywać inteligentnie; możemy wybrać dowolne liczby, które nam się podobają:

# estimates for the mean
red_mean_guess = 1.1
blue_mean_guess = 9

# estimates for the standard deviation
red_std_guess = 2
blue_std_guess = 1.7

Te szacunki parametrów wytwarzają krzywe dzwonka, które wyglądają tak:

Tutaj wpisz opis obrazka

Są złe szacunki. Oba środki (pionowe kropkowane linie) wyglądają daleko od jakiegokolwiek "środka" dla sensownych grup punktów, na przykład. Chcemy poprawić te szacunki.

Kolejnym krokiem ( Krok 2) jest obliczenie prawdopodobieństwa pojawienia się każdego punktu danych pod bieżącymi domysłami parametrów:

likelihood_of_red = stats.norm(red_mean_guess, red_std_guess).pdf(both_colours)
likelihood_of_blue = stats.norm(blue_mean_guess, blue_std_guess).pdf(both_colours)

Tutaj po prostu umieściliśmy każdy punkt danych w funkcji gęstości prawdopodobieństwa dla rozkładu normalnego, używając naszych obecnych domysłów na średnią i standard odchylenie dla Czerwonego i niebieskiego. To mówi nam, na przykład, że z naszych obecnych domysłów punkt danych na 1.761 jest znacznie bardziej prawdopodobne, aby być czerwony (0.189) niż niebieski (0.00003).

Dla każdego punktu danych, możemy przekształcić te dwie wartości prawdopodobieństwa w wagi ( Krok 3 ) tak, aby sumowały się do 1 w następujący sposób:

likelihood_total = likelihood_of_red + likelihood_of_blue

red_weight = likelihood_of_red / likelihood_total
blue_weight = likelihood_of_blue / likelihood_total

Z naszymi aktualnymi szacunkami i naszymi nowo obliczonymi wagami, możemy teraz obliczyć nowe szacunki dla średniego i standardowego odchylenia czerwonego i grupy niebieskie ( Krok 4 ).

Dwa razy obliczamy średnią i odchylenie standardowe używając wszystkich punktów danych, ale z różnymi wagami: raz dla czerwonych i raz dla niebieskich.

Kluczowa intuicja polega na tym, że im większa waga koloru w punkcie danych, tym bardziej punkt danych wpływa na kolejne szacunki dla parametrów tego koloru. Ma to wpływ na "ciągnięcie" parametrów we właściwym kierunku.

def estimate_mean(data, weight):
    """
    For each data point, multiply the point by the probability it
    was drawn from the colour's distribution (its "weight").

    Divide by the total weight: essentially, we're finding where 
    the weight is centred among our data points.
    """
    return np.sum(data * weight) / np.sum(weight)

def estimate_std(data, weight, mean):
    """
    For each data point, multiply the point's squared difference
    from a mean value by the probability it was drawn from
    that distribution (its "weight").

    Divide by the total weight: essentially, we're finding where 
    the weight is centred among the values for the difference of
    each data point from the mean.

    This is the estimate of the variance, take the positive square
    root to find the standard deviation.
    """
    variance = np.sum(weight * (data - mean)**2) / np.sum(weight)
    return np.sqrt(variance)

# new estimates for standard deviation
blue_std_guess = estimate_std(both_colours, blue_weight, blue_mean_guess)
red_std_guess = estimate_std(both_colours, red_weight, red_mean_guess)

# new estimates for mean
red_mean_guess = estimate_mean(both_colours, red_weight)
blue_mean_guess = estimate_mean(both_colours, blue_weight)

We nowe szacunki parametrów. Aby je poprawić, możemy wrócić do kroku 2 i powtórzyć proces. Robimy to do czasu zbieżności szacunków lub po wykonaniu pewnej liczby iteracji (krok 5).

Dla naszych danych, pierwsze pięć iteracji tego procesu wygląda tak (Ostatnie iteracji mają silniejszy wygląd):

Tutaj wpisz opis obrazka

Widzimy, że środki są już zbieżne na niektórych wartościach, a kształty krzywych (regulowane przez odchylenie standardowe) stają się również bardziej stabilne.

Jeśli kontynuujemy 20 iteracji, kończymy z następującym:

Tutaj wpisz opis obrazka

Proces EM jest zbieżny do następujących wartości, które okazują się bardzo zbliżone do wartości rzeczywistych (gdzie możemy zobaczyć kolory-bez ukrytych zmiennych):

          | EM guess | Actual |  Delta
----------+----------+--------+-------
Red mean  |    2.910 |  2.802 |  0.108
Red std   |    0.854 |  0.871 | -0.017
Blue mean |    6.838 |  6.932 | -0.094
Blue std  |    2.227 |  2.195 |  0.032

W powyższym kodzie możesz zauważyć, że nowe oszacowanie odchylenia standardowego zostało obliczone przy użyciu poprzedniej iteracji oszacowanie średniej. Ostatecznie nie ma znaczenia, czy najpierw obliczymy nową wartość dla średniej, ponieważ znajdujemy tylko (ważoną) wariancję wartości wokół jakiegoś punktu centralnego. Nadal zobaczymy zbieżność szacunków parametrów.

 74
Author: Alex Riley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-20 17:38:31

EM jest algorytmem maksymalizacji funkcji prawdopodobieństwa, gdy niektóre zmienne w modelu są nieobserwowane (tj. gdy masz zmienne Ukryte).

Można zapytać, jeśli próbujemy zmaksymalizować funkcję, dlaczego nie użyjemy istniejącej maszyny do zmaksymalizowania funkcji. Cóż, jeśli spróbujesz to zmaksymalizować, biorąc pochodne i ustawiając je na zero, okaże się, że w wielu przypadkach warunki pierwszego rzędu nie mają rozwiązania. Jest kurczak z jajkiem problem w tym, aby rozwiązać parametry modelu, musisz znać rozkład nieobserwowanych danych; ale Dystrybucja nieobserwowanych danych jest funkcją parametrów modelu.

E-M próbuje obejść to, iteracyjnie zgadując rozkład nieobserwowanych danych, a następnie szacując parametry modelu, maksymalizując coś, co jest dolną granicą rzeczywistej funkcji prawdopodobieństwa i powtarzając do zbieżności:

Algorytm EM

Start z guess dla wartości parametrów modelu

E-krok: dla każdego punktu danych, który ma brakujące wartości, użyj równania modelu do rozwiązania rozkładu brakujących danych, biorąc pod uwagę bieżące odgadnięcie parametrów modelu i dane obserwowane (zauważ, że rozwiązujesz dla rozkładu dla każdej brakującej wartości, a nie dla wartości oczekiwanej). Teraz, gdy mamy rozkład dla każdej brakującej wartości, możemy obliczyć oczekiwanie funkcji prawdopodobieństwa z szacunek dla nieobserwowanych zmiennych. Jeśli nasze odgadnięcie parametru modelu było poprawne, to oczekiwane prawdopodobieństwo będzie rzeczywistym prawdopodobieństwem naszych obserwowanych danych; jeśli parametry nie były poprawne, będzie to po prostu dolna granica.

M-step: teraz, gdy mamy funkcję oczekiwanego prawdopodobieństwa bez nieobserwowanych zmiennych, zmaksymalizuj funkcję tak, jak w całkowicie obserwowanym przypadku, aby uzyskać nowe oszacowanie parametrów modelu.

Powtarzać aż do konwergencji.

 31
Author: Marc Shivers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-04 20:42:41

Oto prosty przepis na zrozumienie algorytmu maksymalizacji oczekiwań:

1- przeczytaj ten artykuł em tutorial paper autorstwa Do I Batzoglou.

2- możesz mieć znaki zapytania w głowie, spójrz na wyjaśnienia na tej stronie wymiany stosu matematyki .

3- spójrz na ten kod, który napisałem w Pythonie, który wyjaśnia przykład w artykule z samouczka EM z punktu 1:

Ostrzeżenie : Na kod może być niechlujny/nieoptymalny, ponieważ nie jestem programistą Pythona. Ale robi swoje.

import numpy as np
import math

#### E-M Coin Toss Example as given in the EM tutorial paper by Do and Batzoglou* #### 

def get_mn_log_likelihood(obs,probs):
    """ Return the (log)likelihood of obs, given the probs"""
    # Multinomial Distribution Log PMF
    # ln (pdf)      =             multinomial coeff            *   product of probabilities
    # ln[f(x|n, p)] = [ln(n!) - (ln(x1!)+ln(x2!)+...+ln(xk!))] + [x1*ln(p1)+x2*ln(p2)+...+xk*ln(pk)]     

    multinomial_coeff_denom= 0
    prod_probs = 0
    for x in range(0,len(obs)): # loop through state counts in each observation
        multinomial_coeff_denom = multinomial_coeff_denom + math.log(math.factorial(obs[x]))
        prod_probs = prod_probs + obs[x]*math.log(probs[x])

    multinomial_coeff = math.log(math.factorial(sum(obs))) -  multinomial_coeff_denom
    likelihood = multinomial_coeff + prod_probs
    return likelihood

# 1st:  Coin B, {HTTTHHTHTH}, 5H,5T
# 2nd:  Coin A, {HHHHTHHHHH}, 9H,1T
# 3rd:  Coin A, {HTHHHHHTHH}, 8H,2T
# 4th:  Coin B, {HTHTTTHHTT}, 4H,6T
# 5th:  Coin A, {THHHTHHHTH}, 7H,3T
# so, from MLE: pA(heads) = 0.80 and pB(heads)=0.45

# represent the experiments
head_counts = np.array([5,9,8,4,7])
tail_counts = 10-head_counts
experiments = zip(head_counts,tail_counts)

# initialise the pA(heads) and pB(heads)
pA_heads = np.zeros(100); pA_heads[0] = 0.60
pB_heads = np.zeros(100); pB_heads[0] = 0.50

# E-M begins!
delta = 0.001  
j = 0 # iteration counter
improvement = float('inf')
while (improvement>delta):
    expectation_A = np.zeros((5,2), dtype=float) 
    expectation_B = np.zeros((5,2), dtype=float)
    for i in range(0,len(experiments)):
        e = experiments[i] # i'th experiment
        ll_A = get_mn_log_likelihood(e,np.array([pA_heads[j],1-pA_heads[j]])) # loglikelihood of e given coin A
        ll_B = get_mn_log_likelihood(e,np.array([pB_heads[j],1-pB_heads[j]])) # loglikelihood of e given coin B

        weightA = math.exp(ll_A) / ( math.exp(ll_A) + math.exp(ll_B) ) # corresponding weight of A proportional to likelihood of A 
        weightB = math.exp(ll_B) / ( math.exp(ll_A) + math.exp(ll_B) ) # corresponding weight of B proportional to likelihood of B                            

        expectation_A[i] = np.dot(weightA, e) 
        expectation_B[i] = np.dot(weightB, e)

    pA_heads[j+1] = sum(expectation_A)[0] / sum(sum(expectation_A)); 
    pB_heads[j+1] = sum(expectation_B)[0] / sum(sum(expectation_B)); 

    improvement = max( abs(np.array([pA_heads[j+1],pB_heads[j+1]]) - np.array([pA_heads[j],pB_heads[j]]) ))
    j = j+1
 24
Author: Rhubarb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:19:18

Technicznie termin " EM " jest trochę niedopowiedziany, ale zakładam, że odnosisz się do techniki Gaussian Mixture Modeling cluster analysis, która jest instancją ogólnej zasady EM.

Właściwie, analiza klastra EM nie jest klasyfikatorem. Wiem, że niektórzy uważają klastry za "klasyfikację bez nadzoru", ale w rzeczywistości analiza klastrów jest czymś zupełnie innym.

Kluczowa różnica i wielkie nieporozumienie zawsze z analizy klastra jest to, że: w analaysis klastra, nie ma "poprawnego rozwiązania" . Jest to metoda wiedzy odkrycia , w rzeczywistości ma na celu znalezienie czegoś Nowego ! To sprawia, że ocena jest bardzo trudna. Często jest ona oceniana przy użyciu znanej klasyfikacji jako odniesienie, ale nie zawsze jest to właściwe: klasyfikacja, którą posiadasz, może lub nie odzwierciedlać tego, co znajduje się w danych.

Pozwól, że podam ci przykład: masz duży zestaw danych klientów, w tym dane dotyczące płci. Metoda, która dzieli ten zestaw danych na "męski" i "żeński" jest optymalna, jeśli porównasz go z istniejącymi klasami. W" przewidywania " sposób myślenia jest to dobre, jak dla nowych użytkowników można teraz przewidzieć ich płeć. W "odkrywaniu wiedzy" sposób myślenia jest naprawdę zły, ponieważ chciałeś odkryć jakąś nową strukturę w danych. Metoda, która np. podzieliłaby dane na osoby starsze i dzieci, jednak wynikałaby gorzej, jak to tylko możliwe zdobądź w odniesieniu do klasy męsko-żeńskiej. Byłby to jednak doskonały wynik grupowania (gdyby nie podano wieku).

A teraz wracamy do EM. Zasadniczo zakłada, że Twoje dane składają się z wielu wielowymiarowych rozkładów normalnych (zauważ, że jest to silne założenie Bardzo, w szczególności gdy ustalasz liczbę klastrów!). Następnie próbuje znaleźć lokalny model optymalny dla tego przez naprzemiennie ulepszając model i przypisanie obiektu do model .

Aby uzyskać najlepsze wyniki w kontekście klasyfikacji, Wybierz liczbę klastrów większych niż liczba klas, lub nawet zastosuj klastry tylko dopojedynczych klas (aby dowiedzieć się, czy istnieje jakaś struktura w klasie!).

Powiedz, że chcesz szkolić klasyfikatora, aby odróżnić "samochody", "rowery" i "ciężarówki". Przy założeniu, że dane składają się dokładnie z 3 rozkładów normalnych, nie ma większego zastosowania. Można jednak założyć, że jest więcej niż jeden rodzaj samochodów (oraz ciężarówek i rowerów). Zamiast więc szkolić klasyfikatora dla tych trzech klas, klastrujesz samochody, ciężarówki i rowery na 10 klastrów (a może 10 samochodów, 3 ciężarówki i 3 rowery, cokolwiek), a następnie szkolisz klasyfikatora, aby odróżnić te 30 klas, a następnie scalić wynik klasy z powrotem do oryginalnych klas. Można również odkryć, że istnieje jeden klaster, który jest szczególnie trudny do sklasyfikowania, na przykład Trikes. To trochę samochody, a trochę rowery. Lub Ciężarówki dostawcze, które są bardziej jak samochody ponadgabarytowe niż Ciężarówki.

 16
Author: Anony-Mousse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-04 21:45:11

Inne odpowiedzi będąc dobrym, postaram się przedstawić inną perspektywę i zająć się intuicyjną częścią pytania.

Algorytm EM (Expectation-Maximization) jest odmianą klasy algorytmów iteracyjnych wykorzystujących dualność

Fragment (podkreślenie):

W matematyce dualizm, ogólnie rzecz biorąc, tłumaczy pojęcia, twierdzeń lub struktur matematycznych do innych pojęć, twierdzeń lub struktur, w sposób indywidualny, często (ale nie zawsze) za pomocą operacji inwolucyjnej: jeśli dual Z A jest B, to dual Z B jest A. takie inwolucje czasami mają PUNKTY STAŁE , tak że podwójny of a Is A itself

Zazwyczaj a podwójny B obiektu A jest związany z a w pewien sposób, który zachowuje pewną symetrię lub zgodność . Na przykład AB = const

Przykłady algorytmów iteracyjnych, wykorzystujących dualność (w poprzednim znaczeniu) są:

  1. algorytm Euklidesowy dla największego wspólnego dzielnika i jego wariantów
  2. algorytm bazowy wektora grama-Schmidta i warianty
  3. średnia arytmetyczna-średnia geometryczna nierówności i jej warianty
  4. Algorytm maksymalizacji oczekiwań i jego warianty (Zobacz także tutaj, aby uzyskać widok geometryczny informacji )
  5. (.. inne podobne algorytmy..)

W podobny sposób, EM algorytm może być również postrzegany jako dwa podwójne kroki maksymalizacji :

..[EM] jest postrzegana jako maksymalizacja funkcji wspólnych parametrów i rozkład na nieobserwowane zmienne.. E-step maksymalizuje funkcja ta w odniesieniu do rozkładu nad nieobserwowanym zmienne; M-krok w odniesieniu do parametrów..

W algorytmie iteracyjnym wykorzystującym dualność istnieje jednoznaczne (lub niejawne) założenie punktu równowagi (lub stałego) zbieżność (dla EM jest to udowodnione za pomocą nierówności Jensena)

Więc zarys takich algorytmów jest:

  1. E-podobny krok: Znajdź najlepsze rozwiązanie x w odniesieniu do danej y trzymanej stałej.
  2. M-jak krok (podwójny): Znajdź najlepsze rozwiązanie y w odniesieniu do x (jak obliczono w poprzednim kroku) jest utrzymywana stała.
  3. kryterium zakończenia / stopnia zbieżności: powtórz kroki 1, 2 z zaktualizowane wartości x,y aż do osiągnięcia zbieżności (lub określonej liczby iteracji)

Zauważ, że gdy taki algorytm zbiega się do (globalnego) optimum, to znalazł konfigurację, która jest najlepsza w obu zmysłach (tj. zarówno w x domena/parametry i y domena / parametry). Jednak algorytm może po prostu znaleźć lokalne optimum, a nie globalne optimum.

Powiedziałbym jest to intuicyjny opis zarysu algorytmu

W przypadku argumentów statystycznych i zastosowań inne odpowiedzi dały dobre wyjaśnienia (sprawdź również odniesienia w tej odpowiedzi)

 2
Author: Nikos M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-03 21:20:44

Przyjęta odpowiedź odwołuje się do Chuong em Paper , który porządnie tłumaczy em. Istnieje również wideo na youtube , które wyjaśnia artykuł bardziej szczegółowo.

Podsumowując, oto scenariusz:

1st:  {H,T,T,T,H,H,T,H,T,H} 5 Heads, 5 Tails; Did coin A or B generate me?
2nd:  {H,H,H,H,T,H,H,H,H,H} 9 Heads, 1 Tails
3rd:  {H,T,H,H,H,H,H,T,H,H} 8 Heads, 2 Tails
4th:  {H,T,H,T,T,T,H,H,T,T} 4 Heads, 6 Tails
5th:  {T,H,H,H,T,H,H,H,T,H} 7 Heads, 3 Tails

Two possible coins, A & B are used to generate these distributions.
A & B have an unknown parameter: their bias towards heads.

We don't know the biases, but we can simply start with a guess: A=60% heads, B=50% heads.

W przypadku pierwszego pytania próbnego, intuicyjnie sądzimy, że b je wygenerował, ponieważ proporcja głów bardzo dobrze pasuje do stronniczości B... ale ta wartość była tylko domysłem, więc nie możemy być pewni.

Mając to na uwadze, lubię myśleć o rozwiązanie EM takie jak to:

  • każda próba rzutów "głosuje" na którą monetę lubi najbardziej
    • jest to oparte na tym, jak dobrze każda moneta pasuje do swojej dystrybucji
    • lub, z punktu widzenia monety, istnieje wysokie oczekiwanie na zobaczenie tej próby w stosunku do drugiej monety (na podstawielog likelihoods ).
  • w zależności od tego, jak bardzo każda próba lubi każdą monetę, może zaktualizować domyślanie parametru danej monety (bias).
    • im bardziej proces lubi monetę,tym bardziej aktualizuje stronniczość monety, aby odzwierciedlić jej własne!
    • zasadniczo błędy monety są aktualizowane przez połączenie tych ważonych aktualizacji we wszystkich próbach, proces zwany (maximazation {20]}), który odnosi się do próby uzyskania najlepszych domysłów dla błędów każdej monety, biorąc pod uwagę zestaw prób.
Może to być uproszczenie (lub nawet zasadniczo błędne na niektórych poziomach), ale mam nadzieję, że pomoże to na poziom intuicyjny!
 2
Author: lucidv01d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-30 02:29:29

EM jest używany do maksymalizacji prawdopodobieństwa modelu Q ze zmiennymi utajonymi Z.

To iteracyjna optymalizacja.

theta <- initial guess for hidden parameters
while not converged:
    #e-step
    Q(theta'|theta) = E[log L(theta|Z)]
    #m-step
    theta <- argmax_theta' Q(theta'|theta)

E-krok: biorąc pod uwagę bieżące oszacowanie Z Oblicz oczekiwaną funkcję loglikelihood

M-krok: znajdź theta, która maksymalizuje to Q

Przykład GMM:

E-step: szacowanie przydziałów etykiet dla każdego punktu danych, biorąc pod uwagę aktualną estymację parametru gmm

M-step: assigments

K-means jest również algorytmem EM i istnieje wiele wyjaśniających animacji na k-means.

 1
Author: SlimJim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-30 13:02:44

Używając tego samego artykułu Do I Batzoglou cytowanego w odpowiedzi Zhubarba, zaimplementowałem EM dla tego problemu wJava . Komentarze do jego odpowiedzi pokazują, że algorytm utkwi w lokalnym optimum, co występuje również w mojej implementacji, jeśli parametry thetaA i thetaB są takie same.

Poniżej znajduje się standardowe wyjście mojego kodu, pokazujące zbieżność parametrów.

thetaA = 0.71301, thetaB = 0.58134
thetaA = 0.74529, thetaB = 0.56926
thetaA = 0.76810, thetaB = 0.54954
thetaA = 0.78316, thetaB = 0.53462
thetaA = 0.79106, thetaB = 0.52628
thetaA = 0.79453, thetaB = 0.52239
thetaA = 0.79593, thetaB = 0.52073
thetaA = 0.79647, thetaB = 0.52005
thetaA = 0.79667, thetaB = 0.51977
thetaA = 0.79674, thetaB = 0.51966
thetaA = 0.79677, thetaB = 0.51961
thetaA = 0.79678, thetaB = 0.51960
thetaA = 0.79679, thetaB = 0.51959
Final result:
thetaA = 0.79678, thetaB = 0.51960

Poniżej moja Java implementacja EM do rozwiązania problemu w (Do I Batzoglou, 2008). Podstawową częścią implementacji jest pętla do uruchamiania EM aż do zbieżności parametrów.

private Parameters _parameters;

public Parameters run()
{
    while (true)
    {
        expectation();

        Parameters estimatedParameters = maximization();

        if (_parameters.converged(estimatedParameters)) {
            break;
        }

        _parameters = estimatedParameters;
    }

    return _parameters;
}

Poniżej znajduje się cały kod.

import java.util.*;

/*****************************************************************************
This class encapsulates the parameters of the problem. For this problem posed
in the article by (Do and Batzoglou, 2008), the parameters are thetaA and
thetaB, the probability of a coin coming up heads for the two coins A and B,
respectively.
*****************************************************************************/
class Parameters
{
    double _thetaA = 0.0; // Probability of heads for coin A.
    double _thetaB = 0.0; // Probability of heads for coin B.

    double _delta = 0.00001;

    public Parameters(double thetaA, double thetaB)
    {
        _thetaA = thetaA;
        _thetaB = thetaB;
    }

    /*************************************************************************
    Returns true if this parameter is close enough to another parameter
    (typically the estimated parameter coming from the maximization step).
    *************************************************************************/
    public boolean converged(Parameters other)
    {
        if (Math.abs(_thetaA - other._thetaA) < _delta &&
            Math.abs(_thetaB - other._thetaB) < _delta)
        {
            return true;
        }

        return false;
    }

    public double getThetaA()
    {
        return _thetaA;
    }

    public double getThetaB()
    {
        return _thetaB;
    }

    public String toString()
    {
        return String.format("thetaA = %.5f, thetaB = %.5f", _thetaA, _thetaB);
    }

}


/*****************************************************************************
This class encapsulates an observation, that is the number of heads
and tails in a trial. The observation can be either (1) one of the
experimental observations, or (2) an estimated observation resulting from
the expectation step.
*****************************************************************************/
class Observation
{
    double _numHeads = 0;
    double _numTails = 0;

    public Observation(String s)
    {
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);

            if (c == 'H')
            {
                _numHeads++;
            }
            else if (c == 'T')
            {
                _numTails++;
            }
            else
            {
                throw new RuntimeException("Unknown character: " + c);
            }
        }
    }

    public Observation(double numHeads, double numTails)
    {
        _numHeads = numHeads;
        _numTails = numTails;
    }

    public double getNumHeads()
    {
        return _numHeads;
    }

    public double getNumTails()
    {
        return _numTails;
    }

    public String toString()
    {
        return String.format("heads: %.1f, tails: %.1f", _numHeads, _numTails);
    }

}

/*****************************************************************************
This class runs expectation-maximization for the problem posed by the article
from (Do and Batzoglou, 2008).
*****************************************************************************/
public class EM
{
    // Current estimated parameters.
    private Parameters _parameters;

    // Observations from the trials. These observations are set once.
    private final List<Observation> _observations;

    // Estimated observations per coin. These observations are the output
    // of the expectation step.
    private List<Observation> _expectedObservationsForCoinA;
    private List<Observation> _expectedObservationsForCoinB;

    private static java.io.PrintStream o = System.out;

    /*************************************************************************
    Principal constructor.
    @param observations The observations from the trial.
    @param parameters The initial guessed parameters.
    *************************************************************************/
    public EM(List<Observation> observations, Parameters parameters)
    {
        _observations = observations;
        _parameters = parameters;
    }

    /*************************************************************************
    Run EM until parameters converge.
    *************************************************************************/
    public Parameters run()
    {

        while (true)
        {
            expectation();

            Parameters estimatedParameters = maximization();

            o.printf("%s\n", estimatedParameters);

            if (_parameters.converged(estimatedParameters)) {
                break;
            }

            _parameters = estimatedParameters;
        }

        return _parameters;

    }

    /*************************************************************************
    Given the observations and current estimated parameters, compute new
    estimated completions (distribution over the classes) and observations.
    *************************************************************************/
    private void expectation()
    {

        _expectedObservationsForCoinA = new ArrayList<Observation>();
        _expectedObservationsForCoinB = new ArrayList<Observation>();

        for (Observation observation : _observations)
        {
            int numHeads = (int)observation.getNumHeads();
            int numTails = (int)observation.getNumTails();

            double probabilityOfObservationForCoinA=
                binomialProbability(10, numHeads, _parameters.getThetaA());

            double probabilityOfObservationForCoinB=
                binomialProbability(10, numHeads, _parameters.getThetaB());

            double normalizer = probabilityOfObservationForCoinA +
                                probabilityOfObservationForCoinB;

            // Compute the completions for coin A and B (i.e. the probability
            // distribution of the two classes, summed to 1.0).

            double completionCoinA = probabilityOfObservationForCoinA /
                                     normalizer;
            double completionCoinB = probabilityOfObservationForCoinB /
                                     normalizer;

            // Compute new expected observations for the two coins.

            Observation expectedObservationForCoinA =
                new Observation(numHeads * completionCoinA,
                                numTails * completionCoinA);

            Observation expectedObservationForCoinB =
                new Observation(numHeads * completionCoinB,
                                numTails * completionCoinB);

            _expectedObservationsForCoinA.add(expectedObservationForCoinA);
            _expectedObservationsForCoinB.add(expectedObservationForCoinB);
        }
    }

    /*************************************************************************
    Given new estimated observations, compute new estimated parameters.
    *************************************************************************/
    private Parameters maximization()
    {

        double sumCoinAHeads = 0.0;
        double sumCoinATails = 0.0;
        double sumCoinBHeads = 0.0;
        double sumCoinBTails = 0.0;

        for (Observation observation : _expectedObservationsForCoinA)
        {
            sumCoinAHeads += observation.getNumHeads();
            sumCoinATails += observation.getNumTails();
        }

        for (Observation observation : _expectedObservationsForCoinB)
        {
            sumCoinBHeads += observation.getNumHeads();
            sumCoinBTails += observation.getNumTails();
        }

        return new Parameters(sumCoinAHeads / (sumCoinAHeads + sumCoinATails),
                              sumCoinBHeads / (sumCoinBHeads + sumCoinBTails));

        //o.printf("parameters: %s\n", _parameters);

    }

    /*************************************************************************
    Since the coin-toss experiment posed in this article is a Bernoulli trial,
    use a binomial probability Pr(X=k; n,p) = (n choose k) * p^k * (1-p)^(n-k).
    *************************************************************************/
    private static double binomialProbability(int n, int k, double p)
    {
        double q = 1.0 - p;
        return nChooseK(n, k) * Math.pow(p, k) * Math.pow(q, n-k);
    }

    private static long nChooseK(int n, int k)
    {
        long numerator = 1;

        for (int i = 0; i < k; i++)
        {
            numerator = numerator * n;
            n--;
        }

        long denominator = factorial(k);

        return (long)(numerator / denominator);
    }

    private static long factorial(int n)
    {
        long result = 1;
        for (; n >0; n--)
        {
            result = result * n;
        }

        return result;
    }

    /*************************************************************************
    Entry point into the program.
    *************************************************************************/
    public static void main(String argv[])
    {
        // Create the observations and initial parameter guess
        // from the (Do and Batzoglou, 2008) article.

        List<Observation> observations = new ArrayList<Observation>();
        observations.add(new Observation("HTTTHHTHTH"));
        observations.add(new Observation("HHHHTHHHHH"));
        observations.add(new Observation("HTHHHHHTHH"));
        observations.add(new Observation("HTHTTTHHTT"));
        observations.add(new Observation("THHHTHHHTH"));

        Parameters initialParameters = new Parameters(0.6, 0.5);

        EM em = new EM(observations, initialParameters);

        Parameters finalParameters = em.run();

        o.printf("Final result:\n%s\n", finalParameters);
    }
}
 1
Author: stackoverflowuser2010,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 00:13:48