详解GMM高斯混合模型EM模型

一般讲到GMM就会讲到EM。
我不过多的介绍EM算法。这里只是举一些例子来看看真实的GMM怎么用EM算的。

一、GMM的作用

记住GMM的作用,就是聚类!


二、GMM有hard和soft两种

hard-GMM和soft-GMM是为了对标k-means和soft k-means。在中文互联网上搜索到的GMM,其实基本都是soft-GMM。
所以这里我先介绍一下hard-GMM。


三、hard-GMM

在这里插入图片描述

1)已知初始化簇, B 1 = { x 1 , x 2 } , B 2 = { x 3 , x 4 , x 5 , x 6 } B1 = \{x_1, x_2\}, B2 = \{x_3,x_4,x_5,x_6\} B1={x1,x2},B2={x3,x4,x5,x6}.

初始化两个簇权重分别为 w 1 = 2 / 6 = 1 / 3 , w 2 = 4 / 6 = 2 / 3 w_1 = 2/6 = 1/3, w_2 = 4/6 = 2/3 w1=2/6=1/3,w2=4/6=2/3.

由此可知,两个簇的高斯分布参数为:
μ 1 = ( 0 + 0.5 ) / 2 = 0.25 \mu_1 = (0+0.5)/2 = 0.25 μ1=(0+0.5)/2=0.25
μ 2 = ( 1 + 2 + 3 + 4 ) / 4 = 2.5 \mu_2 = (1+2+3+4)/4 = 2.5 μ2=(1+2+3+4)/4=2.5.
σ 1 2 = 0.2 5 2 \sigma_1 ^ 2 = 0.25^2 σ12=0.252,
σ 2 2 = 1.25 \sigma_2^2 = 1.25 σ22=1.25

概率密度
P ^ ( x ) \hat{P}(x) P^(x)
= w 1 N ( x ; μ 1 , σ 1 2 ) + w 2 N ( x ; μ 2 , σ 2 2 ) = w_1N(x;\mu_1, \sigma_1^2)+w_2N(x;\mu_2, \sigma_2^2) =w1N(x;μ1,σ12)+w2N(x;μ2,σ22)
= 1 / 3 N ( x ; 0.25 , 0.2 5 2 ) + 2 / 3 N ( x ; 2.5 , 1.25 ) = 1/3N(x;0.25, 0.25^2)+2/3N(x;2.5, 1.25) =1/3N(x;0.25,0.252)+2/3N(x;2.5,1.25)

查表知:

P ^ ( x 1 ) = 0.342 \hat{P}(x_1) = 0.342 P^(x1)=0.342 P ^ ( x 2 ) = 0.371 \hat{P}(x_2) = 0.371 P^(x2)=0.371
P ^ ( x 3 ) = 0.103 \hat{P}(x3) = 0.103 P^(x3)=0.103 P ^ ( x 4 ) = 0.215 \hat{P}(x4) = 0.215 P^(x4)=0.215
P ^ ( x 5 ) = 0.215 \hat{P}(x5) = 0.215 P^(x5)=0.215 P ^ ( x 6 ) = 0.097 \hat{P}(x6) = 0.097 P^(x6)=0.097

E i n = − ∑ n = 1 6 l o g P ^ ( x n ) = 9.748 E_{in} = -\sum\limits_{n=1}^{6}log\hat{P}(x_n) = 9.748 Ein=n=16logP^(xn)=9.748

2)使用EM算法迭代直至收敛,需要写出每一步的聚类结果和模型参数

E-step:

计算归属度 λ i j \lambda_{ij} λij,表示数据点 i i i对簇 j j j的归属度。
λ i j = w j N ( x i ; μ j , σ j 2 ) \lambda_{ij} = w_jN(x_i; \mu_j, \sigma_j^2) λij=wjN(xi;μj,σj2)

(1)对数据点 x 1 x_1 x1来说,对簇1簇2的归属度分别为:
λ 11 \lambda_{11} λ11
= w 1 N ( x 1 ; μ 1 , σ 1 2 ) = w_1N(x_1; \mu_1, \sigma_1^2) =w1N(x1;μ1,σ12)
= 1 / 3 N ( 0 ; 0.25 , 0.2 5 2 ) = 1/3N(0;0.25, 0.25^2) =1/3N(0;0.25,0.252)
= 0.323 = 0.323 =0.323
λ 12 \lambda_{12} λ12
= w 2 N ( x 1 ; μ 2 , σ 2 2 ) = w_2N(x_1; \mu_2, \sigma_2^2) =w2N(x1;μ2,σ22)
= 2 / 3 N ( 0 ; 2.5 , 1.25 ) = 2/3N(0;2.5, 1.25) =2/3N(0;2.5,1.25)
= 0.019 = 0.019 =0.019

λ 11 > λ 12 \lambda_{11} > \lambda_{12} λ11>λ12
说明该步下,数据点1归属到簇1

(2)对数据点 x 3 x_3 x3来说,对簇1簇2的归属度分别为:
λ 31 \lambda_{31} λ31
= w 1 N ( x 3 ; μ 1 , σ 1 2 ) = w_1N(x_3; \mu_1, \sigma_1^2) =w1N(x3;μ1,σ12)
= 1 / 3 N ( 1 ; 0.25 , 0.2 5 2 ) = 1/3N(1;0.25, 0.25^2) =1/3N(1;0.25,0.252)
= 4 / ( 3 2 π ) ∗ e − 4.5 ) = 4/(3\sqrt{2\pi})*e^{-4.5)} =4/(32π )e4.5)
= 0.006 =0.006 =0.006
λ 32 \lambda_{32} λ32
= w 2 N ( x 3 ; μ 2 , σ 2 2 ) = w_2N(x_3; \mu_2, \sigma_2^2) =w2N(x3;μ2,σ22)
= 2 / 3 N ( 1 ; 2.5 , 1.25 ) = 2/3N(1;2.5, 1.25) =2/3N(1;2.5,1.25)
= ( 2 / 1.25 ) / ( 3 2 π ) ∗ e − 0.9 = (2/\sqrt{1.25})/(3\sqrt{2\pi})*e^{-0.9} =(2/1.25 )/(32π )e0.9
= 0.097 =0.097 =0.097
λ 31 < λ 32 \lambda_{31} < \lambda_{32} λ31<λ32
说明该步下,数据点3归属到簇2

(3)同理 x 2 x_2 x2归属到簇1, x 4 , x 5 , x 6 x_4,x_5,x_6 x4,x5,x6归属到簇2
所以最终我们还是得到 B 1 = { x 1 , x 2 } , B 2 = { x 3 , x 4 , x 5 , x 6 } B1 = \{x1, x2\}, B2 = \{x3,x4,x5,x6\} B1={x1,x2},B2={x3,x4,x5,x6}. 也就是说已经收敛,解答完毕

但如果还没有收敛怎么办?
假设得到了 B 1 = { x 1 , x 2 , x 3 } , B 2 = { x 4 , x 5 , x 6 } B1 = \{x_1, x_2, x_3\}, B2 = \{x_4,x_5,x_6\} B1={x1,x2,x3},B2={x4,x5,x6}
那就再通过M步更新高斯模型参数

M-step

两个簇权重分别为 w 1 = 2 / 6 = 1 / 3 , w 2 = 4 / 6 = 2 / 3 w_1 = 2/6 = 1/3, w_2 = 4/6 = 2/3 w1=2/6=1/3,w2=4/6=2/3
两个簇的高斯分布为
μ 1 = ( 0 + 0.5 + 1 ) / 3 = 0.5 \mu_1 = (0+0.5+1)/3 = 0.5 μ1=(0+0.5+1)/3=0.5
μ 2 = ( 2 + 3 + 4 ) / 3 = 3 \mu_2 = (2+3+4)/3 = 3 μ2=(2+3+4)/3=3
σ 1 2 = 1 / 6 \sigma_1^2 = 1/6 σ12=1/6
σ 2 2 = 2 / 3 \sigma_2^2 =2/3 σ22=2/3

概率密度
P ^ ( x ) \hat{P}(x) P^(x)
= w 1 N ( x ; μ 1 , σ 1 2 ) + w 2 N ( x ; μ 2 , σ 2 2 ) = w_1N(x;\mu_1, \sigma_1^2)+w_2N(x;\mu_2, \sigma_2^2) =w1N(x;μ1,σ12)+w2N(x;μ2,σ22)
= 1 / 3 N ( x ; 0.5 , 1 / 6 ) + 2 / 3 N ( x ; 3 , 2 / 3 ) = 1/3N(x;0.5, 1/6)+2/3N(x;3, 2/3) =1/3N(x;0.5,1/6)+2/3N(x;3,2/3)

这样就可以计算新一轮的E-step,如此反复,直至数据点的归属簇不再变化


类比一下:hard-GMM中,E-step就像是k-means中的将各数据点归属到各个簇,M-step就像是k-means计算新的簇中心


四、soft-GMM

第1)问没有区别,第2)问开始重新写soft-GMM版本的

2)使用EM算法迭代直至收敛,需要写出每一步的聚类结果和模型参数

E-step:

计算归属度 λ i j \lambda_{ij} λij,表示数据点 i i i对簇 j j j的归属度。
λ i j = w j N ( x i ; μ j , σ j 2 ) \lambda_{ij} = w_jN(x_i; \mu_j, \sigma_j^2) λij=wjN(xi;μj,σj2)

(1)对数据点 x 1 x_1 x1来说,对簇1簇2的归属度分别为:
λ 11 \lambda_{11} λ11
= w 1 N ( x 1 ; μ 1 , σ 1 2 ) = w_1N(x_1; \mu_1, \sigma_1^2) =w1N(x1;μ1,σ12)
= 1 / 3 N ( 0 ; 0.25 , 0.2 5 2 ) = 1/3N(0;0.25, 0.25^2) =1/3N(0;0.25,0.252)
= 0.323 = 0.323 =0.323
λ 12 \lambda_{12} λ12
= w 2 N ( x 1 ; μ 2 , σ 2 2 ) = w_2N(x_1; \mu_2, \sigma_2^2) =w2N(x1;μ2,σ22)
= 2 / 3 N ( 0 ; 2.5 , 1.25 ) = 2/3N(0;2.5, 1.25) =2/3N(0;2.5,1.25)
= 0.019 = 0.019 =0.019

与hard-GMM不同的时,我们需要计算归一化后的归属度:
λ 11 ′ = λ 11 λ 11 + λ 12 = 0.943 \lambda_{11}' = \frac{\lambda_{11}}{\lambda_{11}+\lambda_{12}} = 0.943 λ11=λ11+λ12λ11=0.943
λ 12 ′ = λ 12 λ 11 + λ 12 = 0.057 \lambda_{12}' = \frac{\lambda_{12}}{\lambda_{11}+\lambda_{12}} = 0.057 λ12=λ11+λ12λ12=0.057
λ 11 = λ 11 ′ \lambda_{11} = \lambda_{11}' λ11=λ11
λ 12 = λ 12 ′ \lambda_{12} = \lambda_{12}' λ12=λ12

(2)对数据点 x 3 x_3 x3来说,对簇1簇2的归属度分别为:
λ 31 \lambda_{31} λ31
= w 1 N ( x 3 ; μ 1 , σ 1 2 ) = w_1N(x_3; \mu_1, \sigma_1^2) =w1N(x3;μ1,σ12)
= 1 / 3 N ( 1 ; 0.25 , 0.2 5 2 ) = 1/3N(1;0.25, 0.25^2) =1/3N(1;0.25,0.252)
= 4 / ( 3 2 π ) ∗ e − 4.5 ) = 4/(3\sqrt{2\pi})*e^{-4.5)} =4/(32π )e4.5)
= 0.006 =0.006 =0.006
λ 32 \lambda_{32} λ32
= w 2 N ( x 3 ; μ 2 , σ 2 2 ) = w_2N(x_3; \mu_2, \sigma_2^2) =w2N(x3;μ2,σ22)
= 2 / 3 N ( 1 ; 2.5 , 1.25 ) = 2/3N(1;2.5, 1.25) =2/3N(1;2.5,1.25)
= ( 2 / 1.25 ) / ( 3 2 π ) ∗ e − 0.9 = (2/\sqrt{1.25})/(3\sqrt{2\pi})*e^{-0.9} =(2/1.25 )/(32π )e0.9
= 0.097 =0.097 =0.097

计算归一化后的归属度:
λ 31 ′ = λ 31 λ 31 + λ 32 = 0.058 \lambda_{31}' = \frac{\lambda_{31}}{\lambda_{31}+\lambda_{32}} = 0.058 λ31=λ31+λ32λ31=0.058
λ 32 ′ = λ 32 λ 31 + λ 32 = 0.942 \lambda_{32}' = \frac{\lambda_{32}}{\lambda_{31}+\lambda_{32}} = 0.942 λ32=λ31+λ32λ32=0.942
λ 31 = λ 31 ′ \lambda_{31} = \lambda_{31}' λ31=λ31
λ 32 = λ 32 ′ \lambda_{32} = \lambda_{32}' λ32=λ32

(3)同理计算剩下的数据点的归属度
soft-GMM如何认为算法已经收敛了呢?
当两次归属度的值变化量 < tolerance即可,比如我们这里设定 tolerance=0.02

我们这里再通过M步更新高斯模型参数

M-step

两个簇权重分别为 w 1 = ∑ i = 1 6 λ i 1 = 0.312 , w 2 = ∑ i = 1 6 λ i 2 = 0.688 w_1 = \sum\limits_{i=1}^{6}\lambda_{i1} = 0.312, w_2 = \sum\limits_{i=1}^{6}\lambda_{i2} = 0.688 w1=i=16λi1=0.312,w2=i=16λi2=0.688
两个簇的高斯分布为
μ 1 = ∑ i = 1 6 λ i 1 x i ∑ i = 1 6 λ i 1 = ( λ 11 x 1 + λ 21 x 2 + . . . + λ 61 x 6 ) λ 11 + λ 21 + . . . + λ 61 = 0.263 \mu_1 = \frac{\sum\limits_{i=1}^{6}\lambda_{i1}x_i}{\sum\limits_{i=1}^{6}\lambda_{i1}} = \frac{(\lambda_{11}x_1 + \lambda_{21}x_2 + ... + \lambda_{61}x_6) }{\lambda_{11}+\lambda_{21}+...+\lambda_{61}}= 0.263 μ1=i=16λi1i=16λi1xi=λ11+λ21+...+λ61(λ11x1+λ21x2+...+λ61x6)=0.263

μ 2 = ∑ i = 1 6 λ i 2 x i ∑ i = 1 6 λ i 2 = 2.424 \mu_2 = \frac{\sum\limits_{i=1}^{6}\lambda_{i2}x_i}{\sum\limits_{i=1}^{6}\lambda_{i2}} =2.424 μ2=i=16λi2i=16λi2xi=2.424

σ 1 2 = ∑ i = 1 6 λ i 1 ( x i − μ 1 ) 2 ∑ i = 1 6 λ i 1 = 0.279 \sigma_1^2 = \frac{\sum\limits_{i=1}^{6}\lambda_{i1}(x_i-\mu_1)^2}{\sum\limits_{i=1}^{6}\lambda_{i1}} = 0.279 σ12=i=16λi1i=16λi1(xiμ1)2=0.279

σ 2 2 = ∑ i = 1 6 λ i 2 ( x i − μ 2 ) 2 ∑ i = 1 6 λ i 2 = 1.180 \sigma_2^2 = \frac{\sum\limits_{i=1}^{6}\lambda_{i2}(x_i-\mu_2)^2}{\sum\limits_{i=1}^{6}\lambda_{i2}} = 1.180 σ22=i=16λi2i=16λi2(xiμ2)2=1.180

概率密度
P ^ ( x ) \hat{P}(x) P^(x)
= w 1 N ( x ; μ 1 , σ 1 2 ) + w 2 N ( x ; μ 2 , σ 2 2 ) = w_1N(x;\mu_1, \sigma_1^2)+w_2N(x;\mu_2, \sigma_2^2) =w1N(x;μ1,σ12)+w2N(x;μ2,σ22)
= 0.312 N ( x ; 0.263 , 0.279 ) + 0.688 N ( x ; 2.424 , 1.180 ) = 0.312N(x;0.263, 0.279) + 0.688N(x;2.424, 1.180) =0.312N(x;0.263,0.279)+0.688N(x;2.424,1.180)

这样就可以计算新一轮的E-step,如此反复,直至收敛(参数是否收敛或对数似然函数收敛)
参数收敛比方说第19轮和第20轮迭代时:

iter μ 1 \mu_1 μ1 μ 2 \mu_2 μ2 σ 1 2 \sigma_1^2 σ12 σ 1 2 \sigma_1^2 σ12
190.4852.9230.4080.896
200.4852.9230.4080.895

此时指定的参数已经的变化量已经 < tolerance = 0.02,可以认为已经收敛。


类比一下:soft-GMM中,E-step就像是k-means中的将各数据点对各个簇的归属度,M-step就像是k-means计算新的簇中心


五、python复现代码

"""
import numpy as np
import timedef CreateData(mu1, sigma1, alpha1, mu2, sigma2, alpha2, length):"""生成数据集输入两个高斯分布的真实参数:param mu1::param sigma1::param alpha1::param mu2::param sigma2::param alpha2::param length::return:        通过两个高斯分布生成的数据集"""# 生成第一个分模型的数据First = np.random.normal(loc=mu1, scale=sigma1, size=int(length * alpha1))# 生成第二个分模型的数据Second = np.random.normal(loc=mu2, scale=sigma2, size=int(length * alpha2))# 混合两个数据ObservedData = np.concatenate((First, Second), axis=0)  # 行拼接,生成的还是一列# 打乱顺序(打不打乱其实对算法没有影响)np.random.shuffle(ObservedData)return ObservedDatadef Cal_Gaussian(Data, mu, sigma):"""根据高斯密度函数计算:param Data:数据集:param mu:  当前的高斯分布的参数:param sigma::return:    GaussianP:概率"""GaussianP = 1 / (sigma * np.sqrt(2 * np.pi)) \* np.exp(-1 * np.square(Data - mu) / (2 * np.square(sigma)))return GaussianPdef E_step(Data, mu1, sigma1, alpha1, mu2, sigma2, alpha2):"""E步:param Data:    使用的是ndarray格式:param mu1::param sigma1::param alpha1::param mu2::param sigma2::param alpha2::return:        Gamma1; Gamma2:响应度"""# 计算样本对每个高斯混合模型的响应度(归属度,gamma)# 因此得到的数列结果中,包含该分模型对每个样本的计算响应度公式的分子项print(f" Cal_Gaussian(Data, mu1, sigma1) = { Cal_Gaussian(Data, mu1, sigma1)}")Gamma1 = alpha1 * Cal_Gaussian(Data, mu1, sigma1)  # 是一个列表,保存了每个样本对高斯模型1的响应度print(f" Cal_Gaussian(Data, mu2, sigma2) = { Cal_Gaussian(Data, mu2, sigma2)}")Gamma2 = alpha2 * Cal_Gaussian(Data, mu2, sigma2)# 响应度归一化Gamma1 = Gamma1 / (Gamma1 + Gamma2)# Gamma2 = Gamma2 / (Gamma1 + Gamma2)   # 注意原来是这样写的,但是Gamma1已经在上一行变化了,不能再用来归一化Gamma2 = 1 - Gamma1return Gamma1, Gamma2def M_step(Data, mu1_old, mu2_old, Gamma1, Gamma2):"""M步:param Data::param mu1_old: 当前高斯分布的参数:param mu2_old::param Gamma1:  对高斯分布1的响应度:param Gamma2:  对高斯分布2的响应度:return:    新的高斯分布的参数"""# 计算新的参数mumu1_new = np.dot(Gamma1, Data) / np.sum(Gamma1)mu2_new = np.dot(Gamma2, Data) / np.sum(Gamma2)# 计算新的参数sigma# sigma1_new = np.sqrt(np.dot(Gamma1, np.square(Data - mu1_old)) / np.sum(Gamma1))sigma1_new = np.sqrt(np.dot(Gamma1, np.square(Data - mu1_new)) / np.sum(Gamma1))# sigma2_new = np.sqrt(np.dot(Gamma2, np.square(Data - mu2_old)) / np.sum(Gamma2))sigma2_new = np.sqrt(np.dot(Gamma2, np.square(Data - mu2_new)) / np.sum(Gamma2))# 计算新的参数alpham = len(Data)alpha1_new = np.sum(Gamma1) / malpha2_new = np.sum(Gamma2) / mreturn mu1_new, sigma1_new, alpha1_new, mu2_new, sigma2_new, alpha2_newdef EM(Data, mu1, sigma1, alpha1, mu2, sigma2, alpha2, itertime):"""EM算法:param Data::param mu1::param sigma1::param alpha1::param mu2::param sigma2::param alpha2::param itertime:    迭代次数:return:            模型中分模型的参数"""# 迭代for i in range(itertime):print("************************************************")print(f"\n\n第{i}次迭代")# 计算响应度,E步Gamma1, Gamma2 = E_step(Data, mu1, sigma1, alpha1, mu2, sigma2, alpha2)print(f"对1类的隶属度 = {Gamma1}, \n对2类的隶属度 = {Gamma2}")# 更新参数,M步mu1, sigma1, alpha1, mu2, sigma2, alpha2 \= M_step(Data, mu1, mu2, Gamma1, Gamma2)print(f"mu1={mu1}, sigma1={sigma1}, alpha1={alpha1},\n" f"mu2={mu2}, sigma2={sigma2}, alpha2={alpha2}")return mu1, sigma1, alpha1, mu2, sigma2, alpha2if __name__ == '__main__':# 生成数据Data = np.array([0,0.5,1,2,3,4])# 初始化数据init_mu1 = 0.25init_sigma1 = 0.25init_theta1, init_alpha1 = [init_mu1, init_sigma1], 1/3init_mu2 = 2.5init_sigma2 = np.sqrt(1.25)init_theta2, init_alpha2 = [init_mu2, init_sigma2], 2/3itertime = 20tol = 2e-3# 训练模型start = time.time()print("start training")model_mu1, model_sigma1, model_alpha1, model_mu2, model_sigma2, model_alpha2 = \EM(Data, init_mu1, init_sigma1, init_alpha1, init_mu2, init_sigma2, init_alpha2, itertime)print('end training')end = time.time()print('training time: ', end - start)# print('真实参数:mu1 ', mu1, 'sigma1 ', sigma1, 'alpha1 ', alpha1, 'mu2 ', mu2, 'sigma2 ', sigma2, 'alpha2 ', alpha2)print('模型参数:mu1 ', model_mu1, 'sigma1 ', model_sigma1, 'alpha1 ', model_alpha1, 'mu2 ', model_mu2, 'sigma2 ',model_sigma2, 'alpha2 ', model_alpha2)

参考:

[1]《Dempster A P . Maximum likelihood from incomplete data via the EM algorithm[J]. Journal of the Royal Statistical Society, 1977, 39.》
[2]《高斯混合模型(GMM)》
[3]《EM算法python复现 - 高斯混合模型》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/26561.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UML建模及starUML使用

1、UML关系 1.1 六种关系图例 在UML类图中&#xff0c;常见的有以下几种关系: 泛化&#xff08;Generalization&#xff09;, 实现&#xff08;Realization&#xff09;&#xff0c;关联&#xff08;Association)&#xff0c;聚合&#xff08;Aggregation&#xff09;&#x…

统一建模语言UML(四):领域模型和类图

统一建模语言UML&#xff08;四&#xff09;&#xff1a;领域模型和类图 领域模型 领域模型是对领域内概念类或现实世界中对象的可视化表示&#xff0c;也称为概念模型。是更为完整的业务模型的一个特例。从UML的表示法角度&#xff0c;领域模型被描述为一组没有定义操作的类图…

EA建模工具,介绍常用的UML图

[导读] 作为程序猿都最好掌握的一门语言&#xff0c;那就是UML&#xff08;Unified Modeling Language&#xff09;&#xff0c;统一建模语言(UML)是软件工程领域中一种通用的开发建模语言&#xff0c;旨在提供一种可视化系统设计的标准方法。是开发人员、系统设计人员交流的有…

UML建模语言中的活动图

实验目的 通过上机实验&#xff0c;掌握活动图的语法和规则&#xff0c;深入理解活动图的概念 实验环境 Window下安装StarUML 实验内容 介绍活动图的基本语法与规则&#xff08;可以用图形表述&#xff09;&#xff1a; 活动图是在流程图的基础上添加了大量软件工程术语的…

使用语雀绘制 Java 中六大 UML 类图

目录 下载语雀 泛化关系&#xff08;Generalization&#xff09; 实现关系&#xff08;Realization&#xff09; 关联关系&#xff08;Association&#xff09; 依赖关系&#xff08;Dependency&#xff09; 聚合关系&#xff08;Aggregation&#xff09; 组合关系&…

[精华] UML (统一建模语言) 各种图总结

UML&#xff08;Unified Modeling Language&#xff09;是一种统一建模语言&#xff0c;为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言。下面将对UML的九种图包图的基本概念进行介绍以及各个图的使用场景。 一、基本概念   如下图所示&#xff0c;UML…

迅速掌握统一建模语言UML图

统一建模语言 是非专利的第三代建模和规约语言。UML是一种开放的方法&#xff0c;用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践&#xff0c;这些最佳实践在对大规模&#xff0c;复杂系统进行建模方面&…

UML建模三个工具: StarUML ,Telelogic TAU 和 Rose

UML建模软件目前用的主要有3种&#xff1a; 商业版本&#xff1a;Telelogic TAU 和 Rational Rose 开源版本&#xff1a;StarUML Telelogic TAU与Rational Rose的功能很强&#xff0c;但是需要买License。 StarUML就是希望能提供和TAU/Rose一样功能的开源版本。 目前使用起来…

统一建模语言UML(5)活动图

与其他图的区别 活动图与传统的流程图十分相似&#xff0c;活动图与流程图的最主要的区别在于&#xff0c;活动图能够支持活动的并行行为。 交互图和活动图都是用来对系统动态方面进行建模&#xff0c;区别&#xff1a; 交互图的节点是对象&#xff0c;描述了对象之间通过消息…

一、设计模式 - UML (统一建模语言) - 类图

文章目录 前言UML 类图1. 类图的自身结构2. 关联关系2.1. 自关联2.2. 单向关联2.3. 双向关联 3. 聚合关系4. 组合关系5. 依赖关系6. 继承关系7. 实现关系 前言 统一建模语言&#xff08;Unified Modeling Language&#xff0c;UML&#xff09;是用来设计软件的可视化建模语言&a…

redux在react中的应用,使用antdDesign完成购物车

目录 一.redux的认识 二.什么时候使用redux 三.安装redux 四.redux的使用 1.创建store 2.创建reducer 3.创建action 4.在页面中引入store (1)在商品列表页引入store (2)在购物车页面引入store 五.运行效果图 一.redux的认识 redux 和react没有什么直接的关系&#x…

小黑跟老黑们夜骑车拍完了毕业照面试了两场的leetcode之旅:793. 阶乘函数后 K 个零

小黑代码 class Solution:def preimageSizeFZF(self, k: int) -> int:# 获取n的阶乘的0个数lru_cachedef get_zero(n):if not n:return 0return (n//5) get_zero(n//5)# 二分查找def bin_search(k):# 定义左右指针left 0right int(1e10)while left < right:mid (lef…

python基础 | Pandas基础

文章目录 &#x1f4da;基本数据结构&#x1f407;Series&#xff1a;存储一维&#x1f407;DataFrame:存储二维&#x1f407;Series和DataFrame的关系 &#x1f4da;常用基本函数&#x1f407;数据基本操作&#x1f955;列的查改增删&#x1f440;查看列&#x1f440;修改列&a…

Python面向对象二(第十二讲)

文章目录 知识点1.私有属性与私有方法1.私有属性2.私有方法 2.成员3.实例属性1.类属性(静态属性)2.属性总结 4.实例方法5.类方法6.静态方法7.封装介绍8.继承(重点)9.新式类与经典类练习 10.单继承1.super()练习 11.作业 知识点 私有属性与私有方法成员属性方法封装继承多态 1…

常用设计模式系列(十)—装饰者模式

第一节 前言 各位好&#xff0c;首先我要先恭喜下自己粉丝即将破百&#xff0c;也谢谢各位的捧场&#xff0c;不过也跟我自己的努力密不可分&#xff0c;我也要继续加油&#xff0c;输出更好的文章来回报大家&#xff0c;也希望大家多提建议&#xff0c;有问题我也会及时改进。…

摆摊计划1(万一以后找不到工作)

货源&#xff1a;阿里巴巴正规平台 卖炸串 硬件&#xff1a; 多功能烤肠机 购买链接&#xff1a;脆皮烤肠机燃煤气商用油炸锅商用摆摊热狗机肠机关东煮组合机批发 (1688.com) 成本&#xff1a;379.6元 食材&#xff1a; 淀粉肠&#xff08;100支试水&#xff09;&#xff…

TCP/IP协议

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 目录 TCP/IP协议应用层协议自定义应用层协议DNS 传输层协议端口号UDP协议UDP协议端格式 TCP协议TCP协议段格式TCP工作机制确认应答…

基于HTML+CSS+JavaScript制作美食文化网站 ——卡通创意的烧烤(5个页面) html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

&#x1f468;‍&#x1f393;静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计&#x1f469;‍&#x1f393;,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等&#xff0c;用的最多的还是DW&#xff0c;当然不同软件写出的…

c语言-喝饮料问题

/* 喝饮料问题&#xff1a; 1瓶饮料1元&#xff0c;2个空瓶可以换一瓶饮料&#xff0c;给20元&#xff0c;可以喝多少饮料 */#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int man 0, kong 0, sum 0;man 20; //一开始可以买的饮料数sum 0; /…

如何完美吃下二叉树?——二叉树练习题

文章目录 开胃前菜 基础概念选择题主菜 二叉树oj题1.单值二叉树题目思路1代码思路2代码递归展开图 2. 检查两颗树是否相同题目代码 3. 对称二叉树题目思路代码 4. 二叉树的前序遍历题目代码 5. 另一颗树的子树思路代码 6.二叉树遍历题目代码 7.二叉树的层序遍历准备环节代码实现…