GMM 机器学习聚类算法

96
zenRRan
2017.03.24 21:17* 字数 162

高斯模型就是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型。

公式
WechatIMG8.jpeg
WechatIMG9.jpeg

笼统理解意思就是通过p通过PI,MU,SIGMA更新,而PI,MU,SIGMA也是由p更新,循环即可

实践中讲解。随机初始化n个点,进行聚类

导入库
import numpy as np   #矩阵运算
import random as rand   #产生随机数
import math    #数学运算
import matplotlib.pyplot as plt  #画图
参数初始化
p = []  #shape = 【随机点数 * 分类数】 p[i][j] 表示第i个点属于第j类的概率
X = []  #shape = 【随机点数 * 维数】 这里在二维平面,维数=2,X[i]表示第i个点 X[i][0] X[i][1] -> 横纵坐标 x,y  
N = 0   # 随机点的个数
random_x = [] # 一维 随机点的x坐标list
random_y = [] # 一维 随机点的y坐标list
MU = [] # shape = 【分类数 * 维数】  这里在二维平面,维数=2,MU[i]表示预测属于第i类的中心点 MU[i][0] MU[i][1] -> 横纵坐标 x,y  
SIGMA = [] # shape = 【分类数 * 3】 方差 SIGMA[i]=[MU[i][0], MU[i][1],cov] cov表示二维的概率的协方差
PI = [] # 一维 表示PI[i]表示p第i列的平均值
核心函数
def sum_p(k):  # 对p的k列求和
    sum = 1e-15
    for i in range(N):
        sum += p[i][k]
    return sum

def pai(k):   #更新参数PI
    return sum_p(k) / N

def mu(k): #更新MU
    sum = sum_p(k)
    sum_x = 1e-15
    sum_y = 1e-15
    for i in range(N):
        sum_x += (p[i][k] * x[i])
        sum_y += (p[i][k] * y[i])
    return sum_x/sum, sum_y/sum

def sigma(k):  #更新SIGMA
    sumx = 1e-15
    sumy = 1e-15
    cov  = 1e-15
    S = sum_p(k)
    for i in range(N):
        sumx += (p[i][k] * math.pow(x[i] - MU_X[k], 2))
        sumy += (p[i][k] * math.pow(y[i] - MU_Y[k], 2))
        cov  += (p[i][k] * (x[i] - MU_X[k]) * (y[i] - MU_Y[k]))
    return sumx/S, sumy/S, cov/S

def guass(x, y, k):  #高斯分布概率
    miux, miuy = MU_X[k], MU_Y[k]
    [sigmax, sigmay, cov] = SIGMA[k]
    covmatrix = np.matrix([[sigmax, cov], [cov, sigmay]])
    cov_inverse = np.linalg.pinv(covmatrix)
    cov_det = np.linalg.det(cov_inverse)
    if cov_det < 0:
        cov_det = 0
    e1 = 1 / (2 * math.pi) * np.sqrt(np.abs(cov_det))
    shift = np.matrix([[x - miux], [y - miuy]])
    er = -0.5 * (np.transpose(shift) * cov_inverse * shift)
    ex = math.exp(er)
    # print("guess=",e1 * ex)
    return e1 * ex

def P(i, k):   #更新P
    a = PI[k] * guass(x[i], y[i], k)
    b = 1e-15
    for kk in range(len(x1)):
        b += PI[kk] * guass(x[i], y[i], kk)
    return a/b

实验效果

1.jpeg
2.jpeg
3.jpeg
4.jpeg

具体代码看我的github

欢迎关注深度学习自然语言处理公众号

image
机器学习
Web note ad 1