นี่คือตัวอย่างของการคาดหวังสูงสุด (EM) ที่ใช้ในการประเมินค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน รหัสอยู่ใน Python แต่ควรง่ายต่อการติดตามแม้ว่าคุณจะไม่คุ้นเคยกับภาษา
แรงจูงใจสำหรับ EM
จุดสีแดงและสีน้ำเงินที่แสดงด้านล่างนั้นมาจากการแจกแจงแบบปกติสองแบบที่ต่างกันโดยแต่ละค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน:
ในการคำนวณการประมาณค่าที่เหมาะสมของพารามิเตอร์ "จริง" และค่าเบี่ยงเบนมาตรฐานสำหรับการแจกแจงสีแดงเราสามารถดูจุดสีแดงและบันทึกตำแหน่งของแต่ละคนได้อย่างง่ายดายจากนั้นใช้สูตรที่คุ้นเคย (และคล้ายกันสำหรับกลุ่มสีน้ำเงิน) .
ตอนนี้ให้พิจารณากรณีที่เรารู้ว่ามีจุดสองกลุ่ม แต่เราไม่สามารถเห็นได้ว่าจุดใดเป็นของกลุ่มใด กล่าวอีกนัยหนึ่งสีถูกซ่อนอยู่:
ไม่ชัดเจนเลยว่าจะแบ่งคะแนนออกเป็นสองกลุ่มอย่างไร ขณะนี้เราไม่สามารถดูตำแหน่งและคำนวณการประมาณค่าพารามิเตอร์ของการแจกแจงสีแดงหรือการกระจายสีฟ้าได้
นี่คือสิ่งที่ EM สามารถนำมาใช้เพื่อแก้ไขปัญหา
ใช้ EM เพื่อประมาณค่าพารามิเตอร์
นี่คือรหัสที่ใช้ในการสร้างคะแนนที่แสดงด้านบน คุณสามารถดูค่าเฉลี่ยจริงและส่วนเบี่ยงเบนมาตรฐานของการแจกแจงปกติที่ได้คะแนนมา ตัวแปรred
และblue
ดำรงตำแหน่งของแต่ละจุดในกลุ่มสีแดงและสีน้ำเงินตามลำดับ:
import numpy as np
from scipy import stats
np.random.seed(110) # for reproducible random 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)))
ถ้าเราสามารถมองเห็นสีของแต่ละจุดที่เราจะพยายามกู้คืนวิธีการและค่าเบี่ยงเบนมาตรฐานโดยใช้ฟังก์ชั่นห้องสมุด:
>>> np.mean(red)
2.802
>>> np.std(red)
0.871
>>> np.mean(blue)
6.932
>>> np.std(blue)
2.195
แต่เนื่องจากสีถูกซ่อนไว้จากเราเราจะเริ่มกระบวนการ EM ...
อันดับแรกเราแค่เดาค่าสำหรับพารามิเตอร์ของแต่ละกลุ่ม ( ขั้นตอนที่ 1 ) การเดาเหล่านี้ไม่จำเป็นต้องดี:
# 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
การคาดเดาที่ไม่ดีพอสมควร - วิธีการดูเหมือนพวกเขาอยู่ไกลจาก "จุดกึ่งกลาง" ของกลุ่มคะแนนใด ๆ
เพื่อดำเนินการกับ EM และปรับปรุงการคาดเดาเหล่านี้เราคำนวณความน่าจะเป็นของแต่ละจุดข้อมูล (โดยไม่คำนึงถึงสีที่เป็นความลับ) ที่ปรากฏภายใต้การเดาเหล่านี้สำหรับค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐาน ( ขั้นตอนที่ 2 )
ตัวแปรboth_colours
เก็บจุดข้อมูลแต่ละจุด ฟังก์ชันstats.norm
คำนวณความน่าจะเป็นของจุดภายใต้การแจกแจงแบบปกติด้วยพารามิเตอร์ที่กำหนด:
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)
ตัวอย่างเช่นสิ่งนี้บอกเราว่าเมื่อเราเดาจุดข้อมูลที่ 1.761 มีแนวโน้มที่จะเป็นสีแดง (0.189) มากกว่าสีน้ำเงิน (0.00003)
เราสามารถเปลี่ยนค่าความน่าจะเป็นทั้งสองนี้ให้เป็นน้ำหนัก ( ขั้นตอนที่ 3 ) เพื่อให้ค่ารวมเป็น 1 ดังนี้:
likelihood_total = likelihood_of_red + likelihood_of_blue
red_weight = likelihood_of_red / likelihood_total
blue_weight = likelihood_of_blue / likelihood_total
ด้วยประมาณการปัจจุบันของเราและน้ำหนักที่คำนวณใหม่ของเราตอนนี้เราสามารถคำนวณใหม่อาจจะดีกว่าประมาณการสำหรับพารามิเตอร์ ( ขั้นตอนที่ 4 ) เราต้องการฟังก์ชันสำหรับค่าเฉลี่ยและฟังก์ชันสำหรับส่วนเบี่ยงเบนมาตรฐาน:
def estimate_mean(data, weight):
return np.sum(data * weight) / np.sum(weight)
def estimate_std(data, weight, mean):
variance = np.sum(weight * (data - mean)**2) / np.sum(weight)
return np.sqrt(variance)
สิ่งเหล่านี้มีลักษณะคล้ายกับฟังก์ชันปกติของค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานของข้อมูล ความแตกต่างคือการใช้weight
พารามิเตอร์ที่กำหนดน้ำหนักให้กับแต่ละจุดข้อมูล
น้ำหนักนี้เป็นกุญแจสำคัญใน EM ยิ่งน้ำหนักของสีบนจุดข้อมูลมากขึ้นเท่าไหร่จุดข้อมูลก็ยิ่งมีผลต่อการประมาณค่าถัดไปสำหรับพารามิเตอร์ของสีนั้น ท้ายที่สุดสิ่งนี้มีผลในการดึงแต่ละพารามิเตอร์ในทิศทางที่ถูกต้อง
การคาดเดาใหม่คำนวณด้วยฟังก์ชั่นเหล่านี้:
# 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)
จากนั้นกระบวนการ EM จะถูกทำซ้ำด้วยการคาดเดาใหม่จากขั้นตอนที่ 2 เป็นต้นไป เราสามารถทำซ้ำขั้นตอนสำหรับการวนซ้ำตามจำนวนที่กำหนด (พูด 20) หรือจนกว่าเราจะเห็นพารามิเตอร์มาบรรจบกัน
หลังจากการทำซ้ำห้าครั้งเราจะเห็นการคาดเดาที่ไม่ดีเริ่มต้นของเราเริ่มดีขึ้น:
หลังจากการวนซ้ำ 20 ครั้งกระบวนการ EM มีการรวมกันมากหรือน้อย:
สำหรับการเปรียบเทียบนี่คือผลลัพธ์ของกระบวนการ EM เมื่อเปรียบเทียบกับค่าที่คำนวณโดยที่ข้อมูลสีไม่ได้ถูกซ่อนอยู่:
| EM guess | Actual
----------+----------+--------
Red mean | 2.910 | 2.802
Red std | 0.854 | 0.871
Blue mean | 6.838 | 6.932
Blue std | 2.227 | 2.195
หมายเหตุ: คำตอบนี้ดัดแปลงมาจากคำตอบของฉันในกองมากเกินที่นี่