Giải thích trực quan về kỹ thuật Tối đa hóa kỳ vọng là gì? [đóng cửa]


109

Tối đa hóa kỳ vọng (EM) là một loại phương pháp xác suất để phân loại dữ liệu. Vui lòng sửa cho tôi nếu tôi sai nếu nó không phải là bộ phân loại.

Giải thích trực quan về kỹ thuật EM này là gì? Cái gì expectationở đây và cái gì đang tồn tại maximized?


12
Thuật toán tối đa hóa kỳ vọng là gì? , Nature Biotechnology 26 , 897–899 (2008) có một bức tranh đẹp minh họa cách hoạt động của thuật toán.
chl

@chl Trong phần b của bức tranh đẹp , làm cách nào họ nhận được các giá trị của phân phối xác suất trên Z (tức là 0,45xA, 0,55xB, v.v.)?
Noob Saibot

3
Bạn có thể xem câu hỏi này math.stackexchange.com/questions/25111/…
v4r

3
Đã cập nhật liên kết đến hình ảnh mà @chl đã đề cập.
n1k31t4

Câu trả lời:


119

Lưu ý: mã đằng sau câu trả lời này có thể được tìm thấy ở đây .


Giả sử chúng ta có một số dữ liệu được lấy mẫu từ hai nhóm khác nhau, màu đỏ và xanh lam:

nhập mô tả hình ảnh ở đây

Tại đây, chúng ta có thể xem điểm dữ liệu nào thuộc nhóm màu đỏ hoặc xanh lam. Điều này giúp bạn dễ dàng tìm thấy các thông số đặc trưng cho từng nhóm. Ví dụ: giá trị trung bình của nhóm màu đỏ là khoảng 3, giá trị trung bình của nhóm màu xanh là khoảng 7 (và chúng tôi có thể tìm thấy phương tiện chính xác nếu chúng tôi muốn).

Nói chung, đây được gọi là ước tính khả năng xảy ra tối đa . Với một số dữ liệu, chúng tôi tính toán giá trị của một tham số (hoặc các tham số) giải thích tốt nhất cho dữ liệu đó.

Bây giờ hãy tưởng tượng rằng chúng ta không thể thấy giá trị nào được lấy mẫu từ nhóm nào. Mọi thứ đều có màu tím đối với chúng tôi:

nhập mô tả hình ảnh ở đây

Ở đây, chúng tôi biết rằng có hai nhóm giá trị, nhưng chúng tôi không biết nhóm nào có giá trị cụ thể thuộc về nhóm nào.

Chúng ta vẫn có thể ước tính phương tiện cho nhóm màu đỏ và nhóm màu xanh lam phù hợp nhất với dữ liệu này chứ?

Có, thường thì chúng ta có thể! Tối đa hóa kỳ vọng cung cấp cho chúng tôi một cách để thực hiện điều đó. Ý tưởng chung đằng sau thuật toán là:

  1. Bắt đầu với ước tính ban đầu về giá trị của từng thông số.
  2. Tính khả năng mỗi tham số tạo ra điểm dữ liệu.
  3. Tính toán trọng số cho mỗi điểm dữ liệu cho biết nó có nhiều màu đỏ hơn hay nhiều màu xanh hơn dựa trên khả năng nó được tạo ra bởi một tham số. Kết hợp trọng số với dữ liệu ( kỳ vọng ).
  4. Tính toán ước tính tốt hơn cho các thông số bằng cách sử dụng dữ liệu đã điều chỉnh trọng lượng ( tối đa hóa ).
  5. Lặp lại các bước từ 2 đến 4 cho đến khi ước tính tham số hội tụ (quá trình ngừng tạo ra ước tính khác).

Các bước này cần giải thích thêm, vì vậy tôi sẽ xem xét vấn đề được mô tả ở trên.

Ví dụ: ước tính giá trị trung bình và độ lệch chuẩn

Tôi sẽ sử dụng Python trong ví dụ này, nhưng mã phải khá dễ hiểu nếu bạn không quen với ngôn ngữ này.

Giả sử chúng ta có hai nhóm, màu đỏ và màu xanh lam, với các giá trị được phân phối như trong hình trên. Cụ thể, mỗi nhóm chứa một giá trị được rút ra từ phân phối chuẩn với các tham số sau:

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...

Đây là hình ảnh của các nhóm màu đỏ và xanh lam này một lần nữa (để giúp bạn không phải cuộn lên):

nhập mô tả hình ảnh ở đây

Khi chúng ta có thể nhìn thấy màu sắc của từng điểm (tức là nó thuộc nhóm nào), rất dễ dàng để ước tính giá trị trung bình và độ lệch chuẩn cho mỗi nhóm. Chúng tôi chỉ chuyển các giá trị màu đỏ và xanh lam cho các hàm nội trang trong NumPy. Ví dụ:

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

Nhưng nếu chúng ta không thể nhìn thấy màu sắc của các điểm thì sao? Đó là, thay vì màu đỏ hoặc xanh lam, mọi điểm đã được tô màu tím.

Để thử và khôi phục các tham số trung bình và độ lệch chuẩn cho các nhóm màu đỏ và xanh lam, chúng ta có thể sử dụng Tối đa hóa kỳ vọng.

Bước đầu tiên của chúng tôi ( bước 1 ở trên) là đoán các giá trị tham số cho độ lệch chuẩn và trung bình của mỗi nhóm. Chúng ta không cần phải đoán một cách thông minh; chúng tôi có thể chọn bất kỳ số nào chúng tôi thích:

# 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

Các ước tính tham số này tạo ra các đường cong hình chuông trông như sau:

nhập mô tả hình ảnh ở đây

Đây là những ước tính không tốt. Ví dụ, cả hai đều có nghĩa là (các đường chấm dọc) nhìn xa bất kỳ loại "giữa" nào đối với các nhóm điểm hợp lý. Chúng tôi muốn cải thiện những ước tính này.

Bước tiếp theo ( bước 2 ) là tính toán khả năng mỗi điểm dữ liệu xuất hiện trong các dự đoán tham số hiện tại:

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)

Ở đây, chúng tôi chỉ cần đặt từng điểm dữ liệu vào hàm mật độ xác suất cho phân phối chuẩn bằng cách sử dụng các phỏng đoán hiện tại của chúng tôi ở mức trung bình và độ lệch chuẩn cho màu đỏ và xanh lam. Ví dụ, điều này cho chúng ta biết rằng với những dự đoán hiện tại của chúng ta, điểm dữ liệu tại 1.761 có nhiều khả năng có màu đỏ (0,189) hơn là màu xanh lam (0,00003).

Đối với mỗi điểm dữ liệu, chúng tôi có thể chuyển hai giá trị khả năng này thành trọng số ( bước 3 ) để chúng tổng hợp thành 1 như sau:

likelihood_total = likelihood_of_red + likelihood_of_blue

red_weight = likelihood_of_red / likelihood_total
blue_weight = likelihood_of_blue / likelihood_total

Với ước tính hiện tại và trọng số mới được tính toán của chúng tôi, giờ đây chúng tôi có thể tính toán các ước tính mới cho giá trị trung bình và độ lệch chuẩn của nhóm màu đỏ và xanh lam ( bước 4 ).

Chúng tôi tính toán hai lần giá trị trung bình và độ lệch chuẩn bằng cách sử dụng tất cả các điểm dữ liệu, nhưng với các trọng số khác nhau: một lần cho trọng số màu đỏ và một lần cho trọng số màu xanh.

Điểm mấu chốt của trực giác là trọng lượng của một màu trên một điểm dữ liệu càng lớn, thì điểm dữ liệu đó càng ảnh hưởng đến các ước tính tiếp theo cho các tham số của màu đó. Điều này có tác dụng “kéo” các thông số đi đúng hướng.

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)

Chúng tôi có ước tính mới cho các thông số. Để cải thiện chúng một lần nữa, chúng ta có thể quay lại bước 2 và lặp lại quy trình. Chúng tôi thực hiện điều này cho đến khi các ước tính hội tụ hoặc sau khi một số lần lặp đã được thực hiện ( bước 5 ).

Đối với dữ liệu của chúng tôi, năm lần lặp đầu tiên của quá trình này trông như thế này (các lần lặp gần đây có hình thức mạnh mẽ hơn):

nhập mô tả hình ảnh ở đây

Chúng tôi thấy rằng các phương tiện đã hội tụ trên một số giá trị và hình dạng của các đường cong (bị chi phối bởi độ lệch chuẩn) cũng đang trở nên ổn định hơn.

Nếu chúng ta tiếp tục trong 20 lần lặp, chúng ta kết thúc với những điều sau:

nhập mô tả hình ảnh ở đây

Quá trình EM đã hội tụ các giá trị sau, hóa ra rất gần với giá trị thực (nơi chúng ta có thể nhìn thấy màu sắc - không có biến ẩn):

          | 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

Trong đoạn mã trên, bạn có thể nhận thấy rằng ước tính mới cho độ lệch chuẩn được tính bằng cách sử dụng ước tính trung bình của lần lặp trước. Cuối cùng sẽ không thành vấn đề nếu chúng ta tính giá trị mới cho giá trị trung bình trước vì chúng ta chỉ đang tìm phương sai (có trọng số) của các giá trị xung quanh một số điểm trung tâm. Chúng tôi vẫn sẽ thấy các ước tính cho các tham số hội tụ.


điều gì sẽ xảy ra nếu chúng ta thậm chí không biết số lượng phân phối bình thường mà từ đó nó đến từ đâu? Ở đây bạn đã lấy một ví dụ về phân phối k = 2, liệu chúng ta có thể ước lượng k, và k tập tham số không?
stackit

1
@stackit: Tôi không chắc có một cách chung đơn giản để tính giá trị có khả năng xảy ra nhất của k như một phần của quy trình EM trong trường hợp này. Vấn đề chính là chúng ta cần bắt đầu EM với các ước tính cho từng tham số chúng ta muốn tìm và điều đó đòi hỏi chúng ta cần biết / ước tính k trước khi bắt đầu. Tuy nhiên, có thể ước tính tỷ lệ điểm thuộc về một nhóm thông qua EM ở đây. Có thể nếu chúng ta đánh giá quá cao k, tỷ lệ của tất cả trừ hai nhóm sẽ giảm xuống gần bằng không. Tôi chưa thử nghiệm điều này, vì vậy tôi không biết nó sẽ hoạt động tốt như thế nào trong thực tế.
Alex Riley

1
@AlexRiley Bạn có thể nói thêm một chút về các công thức tính toán ước tính độ lệch chuẩn và giá trị trung bình mới không?
Lemon

2
@AlexRiley Cảm ơn vì lời giải thích. Tại sao các ước tính độ lệch chuẩn mới được tính bằng cách sử dụng phỏng đoán cũ của giá trị trung bình? Điều gì sẽ xảy ra nếu các ước tính mới của giá trị trung bình được tìm thấy trước tiên?
GoodDeeds

1
@Lemon GoodDeeds Kaushal - xin lỗi vì tôi đã trả lời muộn cho câu hỏi của bạn. Tôi đã cố gắng chỉnh sửa câu trả lời để giải quyết những điểm bạn đã nêu ra. Tôi cũng đã làm cho tất cả mã được sử dụng trong câu trả lời này có thể truy cập được trong một cuốn sổ ở đây (trong đó cũng bao gồm các giải thích chi tiết hơn về một số điểm tôi đã chạm vào).
Alex Riley,

36

EM là một thuật toán để tối đa hóa một hàm khả năng khi một số biến trong mô hình của bạn không được quan sát (tức là khi bạn có các biến tiềm ẩn).

Bạn có thể hỏi khá rằng, nếu chúng ta chỉ đang cố gắng tối đa hóa một chức năng, tại sao chúng ta không sử dụng máy móc hiện có để tối đa hóa một chức năng. Chà, nếu bạn cố gắng tối đa hóa điều này bằng cách lấy các đạo hàm và đặt chúng bằng 0, bạn sẽ thấy rằng trong nhiều trường hợp, các điều kiện bậc nhất không có lời giải. Có một vấn đề về con gà và quả trứng trong đó để giải quyết các thông số mô hình của bạn, bạn cần biết sự phân phối dữ liệu chưa được quan sát của mình; nhưng việc phân phối dữ liệu không được quan sát của bạn là một chức năng của các thông số mô hình của bạn.

EM cố gắng giải quyết vấn đề này bằng cách đoán lặp đi lặp lại một phân phối cho dữ liệu không được quan sát, sau đó ước tính các thông số mô hình bằng cách tối đa hóa thứ gì đó là giới hạn thấp hơn trên hàm khả năng thực tế và lặp lại cho đến khi hội tụ:

Thuật toán EM

Bắt đầu với việc đoán các giá trị của thông số mô hình của bạn

Bước E: Đối với mỗi điểm dữ liệu có các giá trị bị thiếu, hãy sử dụng phương trình mô hình của bạn để giải quyết phân phối dữ liệu bị thiếu dựa trên dự đoán hiện tại của bạn về các thông số mô hình và cung cấp dữ liệu quan sát được (lưu ý rằng bạn đang giải quyết phân phối cho mỗi điểm bị thiếu giá trị, không phải cho giá trị mong đợi). Bây giờ chúng ta có một phân phối cho mỗi giá trị bị thiếu, chúng ta có thể tính kỳ vọng của hàm khả năng liên quan đến các biến không được quan sát. Nếu phỏng đoán của chúng tôi cho tham số mô hình là chính xác, khả năng dự kiến ​​này sẽ là khả năng thực tế của dữ liệu quan sát của chúng tôi; nếu các tham số không đúng, nó sẽ chỉ là một giới hạn dưới.

M-step: Bây giờ chúng ta đã có một hàm khả năng dự kiến ​​mà không có biến không được quan sát trong đó, hãy tối đa hóa hàm như bạn làm trong trường hợp được quan sát đầy đủ, để có được ước tính mới về các tham số mô hình của bạn.

Lặp lại cho đến khi hội tụ.


5
Tôi không hiểu E-step của bạn. Một phần của vấn đề là khi tôi đang học những thứ này, tôi không thể tìm thấy những người sử dụng cùng một thuật ngữ. Vậy bạn hiểu phương trình mô hình là gì? Tôi không biết ý bạn là gì khi giải cho một phân phối xác suất?
user678392

27

Dưới đây là một công thức đơn giản để hiểu thuật toán Tối đa hóa kỳ vọng:

1- Đọc bài hướng dẫn EM này của Do và Batzoglou.

2- Bạn có thể có những dấu chấm hỏi trong đầu, hãy xem giải thích trên trang trao đổi chồng toán học này .

3- Xem mã này mà tôi đã viết bằng Python giải thích ví dụ trong bài báo hướng dẫn EM của mục 1:

Cảnh báo: Mã có thể lộn xộn / không tối ưu, vì tôi không phải là nhà phát triển Python. Nhưng nó thực hiện công việc.

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

Tôi thấy rằng chương trình của bạn sẽ cho kết quả cả A và B là 0.66, tôi cũng thực hiện nó bằng cách sử dụng scala, cũng thấy rằng kết quả là 0.66, bạn có thể giúp kiểm tra điều đó được không?
zjffdu

Sử dụng bảng tính, tôi chỉ tìm thấy kết quả 0,66 của bạn nếu các dự đoán ban đầu của tôi bằng nhau. Nếu không, tôi có thể tạo lại đầu ra của hướng dẫn.
ngâm mình vào

@zjffdu, EM chạy bao nhiêu lần lặp lại trước khi trả về cho bạn 0,66? Nếu bạn khởi tạo với các giá trị bằng nhau, nó có thể bị kẹt ở mức tối đa cục bộ và bạn sẽ thấy rằng số lần lặp là cực kỳ thấp (vì không có cải thiện).
Zhubarb

Bạn cũng có thể xem slide này của Andrew Ng và ghi chú khóa học của Harvard
Minh Phan

16

Về mặt kỹ thuật, thuật ngữ "EM" hơi không được xác định rõ ràng, nhưng tôi cho rằng bạn tham khảo kỹ thuật phân tích cụm Mô hình hỗn hợp Gaussian, đó là một ví dụ của nguyên tắc EM chung.

Trên thực tế, phân tích cụm EM không phải là một bộ phân loại . Tôi biết rằng một số người coi phân cụm là "phân loại không được giám sát", nhưng thực sự phân tích cụm là một cái gì đó hoàn toàn khác.

Sự khác biệt chính và sự phân loại gây hiểu lầm lớn mà mọi người luôn mắc phải với phân tích cụm là: trong phân tích theo cụm, không có "giải pháp đúng" . Nó là một phương pháp khám phá kiến thức, nó thực sự có nghĩa là để tìm một cái gì đó mới ! Điều này làm cho việc đánh giá rất phức tạp. Nó thường được đánh giá bằng cách sử dụng một phân loại đã biết làm tham chiếu, nhưng điều đó không phải lúc nào cũng phù hợp: phân loại bạn có có thể phản ánh hoặc không phản ánh những gì có trong dữ liệu.

Để tôi cho bạn một ví dụ: bạn có một tập dữ liệu lớn về khách hàng, bao gồm cả dữ liệu giới tính. Phương pháp phân chia tập dữ liệu này thành "nam" và "nữ" là tối ưu khi bạn so sánh nó với các lớp hiện có. Theo cách nghĩ "dự đoán" thì điều này là tốt, vì đối với người dùng mới, giờ đây bạn có thể dự đoán giới tính của họ. Theo cách nghĩ "khám phá kiến ​​thức", điều này thực sự tệ, bởi vì bạn muốn khám phá một số cấu trúc mới trong dữ liệu. Tuy nhiên, một phương pháp có thể chia nhỏ dữ liệu thành người già và trẻ em sẽ cho điểm càng tệ hơn đối với tầng lớp nam / nữ. Tuy nhiên, đó sẽ là một kết quả phân nhóm tuyệt vời (nếu tuổi không được đưa ra).

Bây giờ trở lại EM. Về cơ bản, nó giả định rằng dữ liệu của bạn bao gồm nhiều phân phối chuẩn đa biến (lưu ý rằng đây là một giả định rất mạnh, đặc biệt là khi bạn cố định số lượng cụm!). Sau đó, nó cố gắng tìm ra một mô hình tối ưu cục bộ cho việc này bằng cách cải tiến xen kẽ mô hình và việc gán đối tượng cho mô hình .

Để có kết quả tốt nhất trong bối cảnh phân loại, hãy chọn số lượng cụm lớn hơn số lớp hoặc thậm chí chỉ áp dụng phân nhóm cho các lớp đơn lẻ (để tìm hiểu xem có cấu trúc nào đó trong lớp hay không!).

Giả sử bạn muốn đào tạo một bộ phân loại để phân biệt "ô tô", "xe đạp" và "xe tải". Có rất ít công dụng trong việc giả định dữ liệu bao gồm chính xác 3 phân phối bình thường. Tuy nhiên, bạn có thể cho rằng có nhiều hơn một loại ô tô (và xe tải và xe đạp). Vì vậy, thay vì đào tạo một bộ phân loại cho ba lớp này, bạn tập hợp ô tô, xe tải và xe đạp thành 10 cụm mỗi nhóm (hoặc có thể 10 ô tô, 3 xe tải và 3 xe đạp, bất cứ điều gì), sau đó đào tạo một bộ phân loại để phân biệt 30 lớp này, và sau đó hợp nhất kết quả lớp trở lại các lớp ban đầu. Bạn cũng có thể phát hiện ra rằng có một cụm đặc biệt khó phân loại, chẳng hạn như Trikes. Chúng là một chiếc ô tô và một chút xe đạp. Hoặc xe tải giao hàng, giống xe quá khổ hơn là xe tải.


EM không được chỉ định như thế nào?
sam boosalis

Có nhiều hơn một phiên bản của nó. Về mặt kỹ thuật, bạn cũng có thể gọi kiểu Lloyd k-có nghĩa là "EM". Bạn cần xác định mô hình bạn sử dụng.
Có QUIT - Anony-Mousse

2

Các câu trả lời khác tốt, tôi sẽ cố gắng cung cấp một góc nhìn khác và giải quyết phần trực quan của câu hỏi.

Thuật toán EM (Kỳ vọng-Tối đa hóa) là một biến thể của một lớp thuật toán lặp sử dụng đối ngẫu

Trích (nhấn mạnh của tôi):

Trong toán học, đối ngẫu, nói chung, chuyển các khái niệm, định lý hoặc cấu trúc toán học thành các khái niệm, định lý hoặc cấu trúc khác, theo kiểu một đối một, thường (nhưng không phải luôn luôn) bằng một phép toán bất biến: nếu đối ngẫu của A là B thì đối ngẫu của B là A. Các nghịch biến như vậy đôi khi có điểm cố định , sao cho đối ngẫu của A là chính A

Thông thường một B kép của một đối tượng A có liên quan đến A theo một cách nào đó để bảo toàn một số đối xứng hoặc tương thích . Ví dụ AB = const

Ví dụ về các thuật toán lặp, sử dụng đối ngẫu (theo nghĩa trước đây) là:

  1. Thuật toán Euclide cho Số chia chung lớn nhất và các biến thể của nó
  2. Thuật toán cơ sở vectơ Gram – Schmidt và các biến thể
  3. Trung bình số học - Bất đẳng thức trung bình hình học và các biến thể của nó
  4. Thuật toán Kỳ vọng-Tối đa hóa và các biến thể của nó (xem thêm tại đây để biết thông tin-hình học )
  5. (.. các thuật toán tương tự khác ..)

Theo cách tương tự, thuật toán EM cũng có thể được coi là hai bước tối đa hóa kép :

.. [EM] được coi là tối đa hóa một hàm kết hợp của các tham số và phân phối trên các biến không được quan sát .. E-step tối đa hóa hàm này đối với phân phối trên các biến không được quan sát; bước M đối với các tham số ..

Trong một thuật toán lặp lại sử dụng đối ngẫu, có giả định rõ ràng (hoặc ngầm định) về điểm hội tụ cân bằng (hoặc cố định) (đối với EM, điều này được chứng minh bằng cách sử dụng bất đẳng thức Jensen)

Vì vậy, phác thảo của các thuật toán như vậy là:

  1. Bước tương tự: Tìm nghiệm x tốt nhất để y không đổi.
  2. Bước giống M (kép): Tìm nghiệm tốt nhất y đối với x (như đã tính ở bước trước) được giữ không đổi.
  3. Tiêu chí của bước Kết thúc / Hội tụ: Lặp lại các bước 1, 2 với các giá trị được cập nhật của x , y cho đến khi đạt đến hội tụ (hoặc đạt đến số lần lặp được chỉ định)

Lưu ý rằng khi một thuật toán như vậy hội tụ đến mức tối ưu (toàn cục), nó đã tìm thấy một cấu hình tốt nhất theo cả hai nghĩa (tức là trong cả miền / tham số x và miền / tham số y ). Tuy nhiên, thuật toán chỉ có thể tìm thấy giá trị tối ưu cục bộ chứ không phải giá trị tối ưu toàn cục .

tôi muốn nói đây là mô tả trực quan về phác thảo của thuật toán

Đối với các lập luận và ứng dụng thống kê, các câu trả lời khác đã đưa ra lời giải thích tốt (xem thêm phần tham khảo trong câu trả lời này)


2

Câu trả lời được chấp nhận có tham chiếu đến Chương EM Paper , một tài liệu thực hiện tốt công việc giải thích EM. Ngoài ra còn có một video youtube giải thích bài báo chi tiết hơn.

Tóm lại, đây là kịch bản:

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.

Trong trường hợp câu hỏi của thử nghiệm đầu tiên, theo trực giác, chúng tôi nghĩ rằng B tạo ra nó vì tỷ lệ số đầu rất phù hợp với thiên vị của B ... nhưng giá trị đó chỉ là phỏng đoán, vì vậy chúng tôi không thể chắc chắn.

Với ý nghĩ đó, tôi muốn nghĩ ra giải pháp EM như thế này:

  • Mỗi lần thử lật đều được 'bỏ phiếu' xem đồng xu nào nó thích nhất
    • Điều này dựa trên mức độ phù hợp của mỗi đồng xu với phân phối của nó
    • HOẶC, từ quan điểm của đồng tiền, có nhiều kỳ vọng sẽ thấy thử nghiệm này so với đồng tiền khác (dựa trên khả năng nhật ký ).
  • Tùy thuộc vào mức độ mỗi lần thử nghiệm thích mỗi đồng xu, nó có thể cập nhật đoán thông số của đồng xu đó (bias).
    • Bản dùng thử càng thích đồng xu, thì bản cập nhật xu hướng của đồng xu càng nhiều để phản ánh xu hướng của chính nó!
    • Về cơ bản những thành kiến của đồng xu được cập nhật bằng cách kết hợp các bản cập nhật trọng trên tất cả các thử nghiệm, một quá trình được gọi là ( maximazation ), trong đó đề cập đến cố gắng để có được những dự đoán tốt nhất cho thiên vị của mỗi đồng tiền được đưa ra một loạt các thử nghiệm.

Đây có thể là sự đơn giản hóa quá mức (hoặc thậm chí sai về cơ bản ở một số cấp độ), nhưng tôi hy vọng điều này sẽ giúp ích ở mức độ trực quan!


1

EM được sử dụng để tối đa hóa khả năng xảy ra mô hình Q với các biến tiềm ẩn Z.

Đó là một sự tối ưu hóa lặp đi lặp lại.

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-step: ước tính hiện tại đã cho của Z tính toán hàm khả năng logli được mong đợi

m-step: tìm theta tối đa hóa Q này

Ví dụ về GMM:

e-step: ước tính các chỉ định nhãn cho mỗi điểm dữ liệu với ước tính tham số gmm hiện tại

m-step: tối đa hóa theta mới với các phép gán nhãn mới

K-means cũng là một thuật toán EM và có rất nhiều hình ảnh động giải thích trên K-means.


1

Sử dụng cùng một bài viết của Do và Batzoglou được trích dẫn trong câu trả lời của Zhubarb, tôi đã triển khai EM cho vấn đề đó trong Java . Các nhận xét cho câu trả lời của anh ấy cho thấy rằng thuật toán bị kẹt ở mức tối ưu cục bộ, điều này cũng xảy ra với việc triển khai của tôi nếu các tham số thetaA và thetaB giống nhau.

Dưới đây là đầu ra tiêu chuẩn của mã của tôi, cho thấy sự hội tụ của các tham số.

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

Dưới đây là cách triển khai EM của tôi trong Java để giải quyết vấn đề trong (Do và Batzoglou, 2008). Phần cốt lõi của việc thực hiện là vòng lặp để chạy EM cho đến khi các tham số hội tụ.

private Parameters _parameters;

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

        Parameters estimatedParameters = maximization();

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

        _parameters = estimatedParameters;
    }

    return _parameters;
}

Dưới đây là toàn bộ mã.

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);
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.