机器学习-聚类(混合高斯算法)

本文介绍了混合高斯模型的基本概念,包括协方差、协方差矩阵等,并详细推导了高斯混合模型的参数估计过程。通过EM算法实现模型训练,并提供了Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,介绍

学习混合高斯,先要了解几个概念:

1,协方差:

协方差是对两个随机变量联合分布线性相关程度的一种度量。两个随机变量越线性相关,协方差越大,完全线性无关,协方差为零。

根据数学期望的性质:

                                                               

推导协方差为:

                                                                

2,协方差矩阵:

对多维随机变量X=[X1,X2,X3,...,Xn],我们往往需要计算各维度两两之间的协方差,这样各协方差组成了一个n×n的矩阵,称为协方差矩阵:

                                                       

百度百科给出的实例:

                                             

3,服从高斯分布的概率密度函数:

                                                   

可以看出高斯分布由均值向量μ和协方差矩阵∑这两个参数确定,故将概率密度函数记为:p(x|μ,∑) 
可定义高斯混合分布为:

                                                                     

给定一组数据,假设该数据由多个高斯分布产生,现在我们要估计这些高斯分布的参数,以及每个样本属于每个高斯分布的概率,那么根据样本推测出元GMM的概率分布就可以了。具体求解借助EM算法可得。

二,公式推导

假设有K个样本,服从C个高斯分布,随机抽取一个样本X得到:

                                                         (1)

其中,为协方差矩阵,是聚类的中心(向量均值)

根据上式,可以写出关于样本值(第i个样本)的概率密度函数:

                                                               (2)

再根据贝叶斯定理:

                                                         

该分布由c个混合成分组成,每个混合对应一个高斯分布,P(Cj)为对应的“混合系数”,且=1。

我们定义m个观测样本的对数似然函数:

                                                    

为了得到最大对数似然函数,需要对分别对求偏导并令其为0:

(1)求:

将公式(2)代入,并且除去第K个分量其余可以看做常数,得到:

                                                    

                                                   

由于,只有第K个样本与有关,其他的都可以视为常数,上式变为:

                                                                           

再利用对数复合函数求导得到:

                                                 

 

利用贝叶斯公式,整理获得:

                                           (3)

接着,求解,

                                          

求偏导:

                                

                               (4)

令偏导为0,公式(4)代入公式(3),又知不为0,可得:

                                                     

                                                   

(2)求

类似与求

                                              

                                                

利用矩阵求导的性质:

                                                                   

                              

                                                  

再继续求解得:

                           

我们假设K的位置再行i和列j上,那么可知,∑除了在位置(i,j)上为1以外,其他的都为零,上式结果为:

                                                                         

代入上式,获得:

                                                                    

(3)求k个分量的比例的问题

在(1)和(2)中,我们已经获取了,我们要求K个分量最佳比例值,相当于优化:

                                                      

我们利用拉格朗日定理求解:

                                              

                                               

综上所述得到:

                                                                          

将其代入第K个分量,获得:

                                                                        

我们总结下算法流程:

第一步,初始化模型参数;

第二步,计算高斯混合分布

                                                                

第三步,计算Ck的后验分布:

                                                               

第四步,计算新的均值向量、协方差矩阵、混合系数

                                                             

                                                            

                                                          

第五步,如果不满足条件,跳转到第二步继续计算。

第六步,满足条件,确定均值向量中心,获得分类模型

二,代码实现

数据:

0.697   0.46
0.774  0.376
0.634  0.264
0.608  0.318
0.556  0.215
0.403  0.237
0.481  0.149
0.437  0.211
0.666  0.091
0.243  0.267
0.245  0.057
0.343  0.099
0.639  0.161
0.657  0.198
0.36   0.37
0.593  0.042
0.719  0.103
0.359  0.188
0.339  0.241
0.282  0.257
0.748  0.232
0.714  0.346
0.483  0.312
0.478  0.437
0.525  0.369
0.751  0.489
0.532  0.472
0.473  0.376
0.725  0.445
0.446  0.459
import numpy as np
import matplotlib.pyplot as plt

# 预处理数据
def loadDataSet(filename):
    dataSet = []
    fr = open(filename)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = list(map(float, curLine))
        dataSet.append(fltLine)
    return dataSet

# 高斯分布的概率密度函数
def prob(x, mu, sigma):
    n = np.shape(x)[1]
    expOn = float(-0.5 * (x - mu) * (sigma.I) * ((x - mu).T))
    divBy = pow(2 * np.pi, n / 2) * pow(np.linalg.det(sigma), 0.5)  # np.linalg.det 计算矩阵的行列式
    return pow(np.e, expOn) / divBy

# EM算法
def EM(dataMat, maxIter=50,c=3):
    m, n = np.shape(dataMat)
    # 第一步,初始化参数
    alpha = [1 / 3, 1 / 3, 1 / 3]   # 初始化参数 alpha1=alpha2=alpha3=1/3
    mu = [dataMat[5, :], dataMat[21, :], dataMat[26, :]] # 初始化聚类中心 mu1=x6,mu2=x22,mu3=x27
    sigma = [np.mat([[0.1, 0], [0, 0.1]]) for x in range(3)]    # 初始化协方差矩阵
    gamma = np.mat(np.zeros((m, c)))
    for i in range(maxIter):
        for j in range(m):
            sumAlphaMulP = 0
            for k in range(c):
                gamma[j, k] = alpha[k] * prob(dataMat[j, :], mu[k], sigma[k]) # 计算混合成分生成的后验概率
                sumAlphaMulP += gamma[j, k]    # 第二步,计算高斯混合分布
            for k in range(c):
                gamma[j, k] /= sumAlphaMulP   # 第三步,计算后验分布
        sumGamma = np.sum(gamma, axis=0)

        for k in range(c):
            mu[k] = np.mat(np.zeros((1, n)))
            sigma[k] = np.mat(np.zeros((n, n)))
            for j in range(m):
                mu[k] += gamma[j, k] * dataMat[j, :]
            mu[k] /= sumGamma[0, k] #  第四步,计算均值向量
            for j in range(m):
                sigma[k] += gamma[j, k] * (dataMat[j, :] - mu[k]).T *(dataMat[j, :] - mu[k])
            sigma[k] /= sumGamma[0, k]  #  第四步,计算协方差矩阵
            alpha[k] = sumGamma[0, k] / m   # 第四步,计算混合系数
    return gamma


# init centroids with random samples
def initCentroids(dataMat, k):
    numSamples, dim = dataMat.shape
    centroids = np.zeros((k, dim))
    for i in range(k):
        index = int(np.random.uniform(0, numSamples))
        centroids[i, :] = dataMat[index, :]
    return centroids


def gaussianCluster(dataMat):
    m, n = np.shape(dataMat)
    centroids = initCentroids(dataMat, m)
    clusterAssign = np.mat(np.zeros((m, 2)))
    gamma = EM(dataMat)
    for i in range(m):
        clusterAssign[i, :] = np.argmax(gamma[i, :]), np.amax(gamma[i, :])
    for j in range(m):
        pointsInCluster = dataMat[np.nonzero(clusterAssign[:, 0].A == j)[0]]
        centroids[j, :] = np.mean(pointsInCluster, axis=0)  # 第五步,确定各均值中心,获得分类模型
    return centroids, clusterAssign


def showCluster(dataMat, k, centroids, clusterAssment):
    numSamples, dim = dataMat.shape
    if dim != 2:
        print("Sorry! I can not draw because the dimension of your data is not 2!")
        return 1

    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
    if k > len(mark):
        print("Sorry! Your k is too large!")
        return 1

    for i in range(numSamples):
        markIndex = int(clusterAssment[i, 0])
        plt.plot(dataMat[i, 0], dataMat[i, 1], mark[markIndex])

    mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']

    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=12)

    plt.show()

if __name__=="__main__":
    dataMat = np.mat(loadDataSet('watermelon4.0.txt'))
    centroids, clusterAssign = gaussianCluster(dataMat)
    print(clusterAssign)
    showCluster(dataMat, 3, centroids, clusterAssign)
### 高斯混合模型 (Gaussian Mixture Model, GMM) 的概念 高斯混合模型是一种基于概率的无监督学习方法,它假设数据是从多个正态分布中生成的。具体来说,GMM 可以被看作由 \(K\) 个单高斯模型组合而成的模型[^3]。这些子模型被称为隐变量(Hidden Variable),因为实际的数据并不显式地属于某个特定的高斯分布。 #### 数学表示 GMM 的数学形式可以用以下公式描述: \[ p(x|\theta) = \sum_{k=1}^{K} \pi_k \cdot N(x | \mu_k, \Sigma_k) \] 其中: - \(N(x | \mu_k, \Sigma_k)\) 表示第 \(k\)高斯分量的概率密度函数; - \(\pi_k\) 是权重系数,满足 \(\sum_{k=1}^K \pi_k = 1\) 和 \(\pi_k > 0\)- \(\mu_k\) 和 \(\Sigma_k\) 分别代表第 \(k\)高斯分量的均值向量和协方差矩阵。 这种结构使得 GMM 能够灵活建模复杂的数据分布。 --- ### 应用场景 GMM 广泛应用于各种领域,以下是几个典型的应用案例: #### 数据聚类 在无标签的情况下,GMM 可以用来对数据进行软聚类。相比于传统的硬划分聚类算法(如 K-Means),GMM 提供了一种更柔性的解决方案,允许样本部分隶属于多个簇[^1]。 #### 图像分割 图像中的像素通常具有复杂的分布特性,而 GMM 可以很好地捕捉这些特征并将其划分为不同区域。例如,在医学影像分析中,GMM 常用于脑部 MRI 扫描的灰质/白质分离任务。 #### 时间序列建模 当与隐马尔科夫模型(HMM)结合时,GMM 成为了强大的工具来处理时间序列数据。这种方法广泛应用于语音识别领域,作为声学模型的核心组成部分之一[^2]。 --- ### 实现方式 Python 中最常用的库 `scikit-learn` 提供了简单易用的接口来训练 GMM 模型。下面是一个简单的代码示例展示如何利用该库完成基本的任务。 ```python from sklearn.mixture import GaussianMixture import numpy as np # 构造模拟数据集 data = np.random.randn(500, 2) # 初始化 GMM 模型对象 gmm_model = GaussianMixture(n_components=3, covariance_type='full', random_state=42) # 训练模型 gmm_model.fit(data) # 输出各组分参数估计结果 print("Means:\n", gmm_model.means_) print("Covariances:\n", gmm_model.covariances_) # 对新样本预测其所属类别及其隶属度 new_sample = [[0.5, 0.5]] prediction = gmm_model.predict(new_sample) probabilities = gmm_model.predict_proba(new_sample) print(f"Predicted cluster: {prediction}") print(f"Cluster membership probabilities: {probabilities}") ``` 上述脚本展示了如何定义、拟合以及评估一个三成分的 GMM 模型,并进一步解释了它的内部工作原理。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值