1.演算法理論p(
x)=∑
kk=1
πkn(
x|μk
,εk)
n(x|μk
,εk)
=1(2
π)d|
εk|√
exp(
−12(
xi−μ
k)tε
−1k(
xi−μ
k))
∑kk=1πk
=1
用極大似然法處理問題:
輸入: (i = 1~n)
最小化: e(
πk,μ
k,εk
)=−∑
ni=1
log[
p(xi
)]=
−∑ni=1l
og(∑
kk=1
1(2π
)d|ε
k|√e
xp(−
12(x
i−μk
)tε−
1k(x
i−μk
)))
這是乙個非凸問題,只能求區域性極值,一般採用em演算法。
步驟如下:
1.隨機化πk
,μk,
εk2.e步:計算γn
,k=π
kn(x
n|μk
,εk)
∑kk=
1n(x
n|μk
,εk)
上式表示:第n個樣本落在第k個高斯的概率
3.m步: nk
=∑kk
=1γn
,k表示n個樣本中有多少屬於第k個高斯
開始更新: πn
ewk=
nkn
μnew
k=1n
k∑nn
=1γn
,kxn
εnewk=
1nk∑
nn=1
γn,k
(xn−
μnew
k)(x
n−μn
ewk)
t 4.回到2直至收斂
python實現
**基於
在此基礎上進行理解。
# 計算高斯函式
def gaussian(data,mean,cov):
dim = np.shape(cov)[0] # 計算維度
covdet = np.linalg
.det(cov) # 計算|cov|
covinv = np.linalg
.inv(cov) # 計算cov的逆
if covdet==0: # 以防行列式為0
covdet = np.linalg
.det(cov+np.eye(dim)*0.01)
covinv = np.linalg
.inv(cov+np.eye(dim)*0.01)
m = data - mean
z = -0.5 * np.dot(np.dot(m, covinv),m) # 計算exp()裡的值
return 1.0/(np.power(np.power(2*np.pi,dim)*abs(covdet),0.5))*np.exp(z) # 返回概率密度值
# 用於判斷初始聚類簇中的means是否距離離得比較近
defisdistance
(means,criterion=0.03):
k=len(means)
for i in range(k):
for j in range(i+1,k):
if criterion>np.linalg.norm(means[i]-means[j]):
return
false
return
true
# 獲取最初的聚類中心
defgetinitialmeans
(data,k,criterion):
dim = data.shape[1] # 資料的維度
means = [ for k in range(k)] # 儲存均值
minmax=
for i in range(dim):
minmax=np.array(minmax)
while
true:
for i in range(k):
means[i]=
for j in range(dim):
means[i]=np.array(means[i])
if isdistance(means,criterion):
break
return means
# k均值演算法,估計大約幾個樣本屬於乙個gmm
defkmeans
(data,k):
n = data.shape[0] # 樣本數量
dim = data.shape[1] # 樣本維度
means = getinitialmeans(data,k,15)
means_old = [np.zeros(dim) for k in range(k)]
# 收斂條件
while np.sum([np.linalg.norm(means_old[k] - means[k]) for k in range(k)]) > 0.01:
means_old = cp.deepcopy(means)
numlog = [0] * k # 儲存屬於某類的個數
sumlog = [np.zeros(dim) for k in range(k)]
# e步
for i in range(n):
dislog = [np.linalg.norm(data[i]-means[k]) for k in range(k)]
tok = dislog.index(np.min(dislog))
numlog[tok]+=1
# 屬於該類的樣本數量加1
sumlog[tok]+=data[i] # 儲存屬於該類的樣本取值
# m步
for k in range(k):
means[k]=1.0 / numlog[k] * sumlog[k]
return means
defgmm
(data,k):
n = data.shape[0]
dim = data.shape[1]
means= kmeans(data,k)
convs=[0]*k
# 初始方差等於整體data的方差
for i in range(k):
convs[i]=np.cov(data.t)
pis = [1.0/k] * k
gammas = [np.zeros(k) for i in range(n)]
loglikelyhood = 0
oldloglikelyhood = 1
while np.abs(loglikelyhood - oldloglikelyhood) > 0.0001:
oldloglikelyhood = loglikelyhood
# e步
for i in range(n):
res = [pis[k] * gaussian(data[i],means[k],convs[k]) for k in range(k)]
sumres = np.sum(res)
for k in range(k): # gamma表示第n個樣本屬於第k個混合高斯的概率
gammas[i][k] = res[k] / sumres
# m步
for k in range(k):
nk = np.sum([gammas[n][k] for n in range(n)]) # n[k] 表示n個樣本中有多少屬於第k個高斯
pis[k] = 1.0 * nk/n
means[k] = (1.0/nk)*np.sum([gammas[n][k] * data[n] for n in range(n)],axis=0)
xdiffs = data - means[k]
convs[k] = (1.0/ nk)*np.sum([gammas[n][k]* xdiffs[n].reshape(dim,1) * xdiffs[n] for n in range(n)],axis=0)
# 計算最大似然函式
loglikelyhood = np.sum(
[np.log(np.sum([pis[k] * gaussian(data[n], means[k], convs[k]) for k in range(k)])) for n in range(n)])
print (means)
print (loglikelyhood)
混合高斯模型(GMM)與EM演算法
有乙個資料集d d d 中的每個資料點是這樣產生的,先從k個類別中選擇乙個類別,然後從該類別對應的資料產生分布中產生資料點。若k選1的對應的分布是multinoulli分布,每個類別對應的資料產生分布是不同的高斯分布,估計資料點x對應的分布。這個問題對應的模型就是乙個混合高斯模型,具體的資料產生過程...
機器學習 高斯混合模型GMM和EM演算法
高斯混合模型就是用高斯 概率密度函式 正態分佈 曲線 精確地量化事物,它是乙個將事物分解為若干的基於高斯概率密度函式 正態分佈曲線 形成的模型。高斯混合模型 gmm 顧名思義,就是資料可以看作是從數個單高斯分布 gsm 中生成出來的。雖然我們可以用不同的分布來隨意地構造 xx mixture mod...
GMM高斯混合模型
在一般的分類問題中,通常的套路都是提取特徵,將特徵輸入分類器訓練,得到最終的模型。但是在具體操作時,一開始提出的特徵和輸入分類器訓練的特徵是不一樣的。比如假設有n張 100 100 100 100 的影象,分別提取它們的hog特徵x rp q x rp q,p p為特徵的維數,q q 為這幅影象中h...