请使用上面身高数据,需要使用EM算法来估计高斯混合模型的参数,并使用这些参数来进行预测。

该代码实现了一个使用EM算法(Expectation-Maximization)对身高数据进行分析的程序。首先定义了高斯概率密度函数Gauss,然后是E步和M步函数,分别用于更新模型参数。程序读取身高数据,进行训练集和测试集划分,并初始化男生和女生的身高分布参数。通过迭代优化,最终得到男生和女生的身高比例、平均值和方差。在测试集上计算对数似然估计,并绘制训练集的混合高斯分布直方图。
摘要由CSDN通过智能技术生成
import math
import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import norm

    
#概率密度函数
def Gauss(X,mu,sigma):
    result = (1 / (np.sqrt(2 * math.pi) * sigma)) * np.exp(-0.5 * ((X - mu) / sigma) ** 2)
    return result
#E_step
def E_step(heights,a1,u1,o1,a2,u2,o2):
    gama1 = a1*Gauss(heights,u1,o1)
    gama2 = a2*Gauss(heights,u2,o2)
    sum = gama1 + gama2
    gama1 = gama1 / sum
    gama2 = gama2 / sum
    return(gama1,gama2)
#M_step
def M_step(u1,u2,gama1,gama2,heights):
    u1_new = np.dot(gama1,heights)/np.sum(gama1)
    u2_new = np.dot(gama2,heights)/np.sum(gama2)
    
    o1_new = math.sqrt(np.dot(gama1,(heights - u1)**2)/np.sum(gama1))
    o2_new = math.sqrt(np.dot(gama2,(heights - u2)**2)/np.sum(gama2))
    
    a1_new = np.sum(gama1)/len(gama1)
    a2_new = np.sum(gama2)/len(gama2)
    
    return u1_new,u2_new,o1_new,o2_new,a1_new,a2_new
if __name__ == '__main__':
    start = time.time()    
    #读入身高数据
    df= pd.read_csv('./height_data.csv', header=0, names=['height'])
    heights = [row['height'] for index, row in df.iterrows()]
    #划分训练集和测试集3:1  
    np.random.shuffle(heights)
    train_heights = heights[:1500]
    test_heights  = heights[1500:]
    #设定初始值    
    u1,u2,o1,o2,a1,a2 = 175,150,10,10,0.5,0.5
    print('---------------------------')
    print('初始设置参数为:')
    print('男生比例a1:%.6f\n男生均高u1:%.6f\n男生方差o1:%.6f\n女生比例a2:%.6f\n女生均高u2:%.6f\n女生方差o2:%.6f' %(a1,u1,o1,a2,u2,o2))
    #开始训练,循环500次
    iter = 500
    step = 0
    train_heights = np.array(train_heights)
    while (step < iter):
        step += 1
        gama1,gama2 = E_step(train_heights, a1, u1, o1, a2, u2, o2)
        u1,u2,o1,o2,a1,a2 = M_step(u1,u2,gama1,gama2,train_heights)
    #输出训练结果
    print('----------------------------')
    print('EM算法迭代得到参数为:')
    print('男生比例a1:%.6f\n男生均高u1:%.6f\n男生方差o1:%.6f\n女生比例a2:%.6f\n女生均高u2:%.6f\n女生方差o2:%.6f' %(a1,u1,o1,a2,u2,o2))
    #输出运行时间
    print('----------------------------')
    print('运行时间:', time.time() - start)    
    #测试集上对数似然估计
    p1 = a1 * np.exp(-0.5 * (test_heights - u1) ** 2 / o1 ** 2) / np.sqrt(2 * np.pi * o1 ** 2)
    p2 = a2 * np.exp(-0.5 * (test_heights - u2) ** 2 / o2 ** 2) / np.sqrt(2 * np.pi * o2 ** 2)
    log_likelihood = np.sum(np.log(p1 + p2))
    print('似然估计:', log_likelihood)
    #做出直方图
    print('----------------------------')
    print('     图片:训练集混合高斯分布直方图')
    x = np.linspace(min(train_heights), max(train_heights), 200)
    def y(x):
        y = a1 * norm.pdf(x, u1, o1) + a2 * norm.pdf(x, u2, o2)
        return y * len(train_heights)
    plt.hist(train_heights, bins=20, color="w", label="直方分布图", edgecolor='k')
    plt.xlabel('height/cm')
    plt.ylabel('Count')
    plt.plot(x, y(x), 'b', linewidth=2)
    plt.show() 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值