1.高斯混合模型概念
高斯混合模型是一種機率模型,它假設所有資料點都是從有限數量的高斯分佈的混合引數中生成的。實際上,可以將混合模型視為對 k-means聚類演算法的擴充套件,它包含了資料的協方差結構以及隱高斯模型中心的資訊。該方法使用了高斯分佈作為引數模型,並使用了期望最大(Expectation Maximization,簡稱EM)演算法進行訓練。
2.基本原理與相關知識
2。1 高斯分佈
高斯分佈(Gaussian distribution)經常被稱為正態分佈(normal distribution),是一種在自然界大量存在的、最為常見的分佈形式。
下圖是一張標準的高斯分佈曲線圖,兩頭低,中間高,左右對稱因其曲線呈鐘形,因此人們又經常稱之為鐘形曲線:
高斯分佈的機率密度函式公式如下:
公式中包含兩個引數,引數μ表示均值,引數σ表示標準差,均值對應正態分佈的中間位置,在本例中我們可以推測均值在180cm附近。標準差衡量了資料圍繞均值分散的程度。
注意:在實踐中,機率分佈要先進行歸一化,也就是說曲線下面的面積之和需要為1,這樣才能確保返回的機率密度在允許的取值範圍內。
2。 期望最大化演算法(EM)與高斯模型訓練
模型的EM訓練過程:
觀察取樣的機率值和模型機率值的接近程度,來判斷一個模型是否擬合良好。
調整模型以讓新模型更適配取樣的機率值。
反覆迭代這個過程很多次,直到兩個機率值非常接近時,我們停止更新並完成模型訓練。
模型生成的資料來決定似然值,即透過模型來計算資料的期望值。透過更新引數μ和σ來讓期望值最大化。這個過程可以不斷迭代直到兩次迭代中生成的引數變化非常小為止。該過程和k-means的演算法訓練過程很相似(k-means不斷更新類中心來讓結果最大化),只不過在這裡的高斯模型中,需要同時更新
兩個引數:分佈的均值和標準差
3. 高斯混合模型實際案例
雖然GMM經常用於聚類,但我們可以將獲得的聚類與資料集中的實際類別進行比較。我們用訓練集中的類的均值初始化高斯矩陣的均值,以使這種比較有效。
使用iris資料集上的各種GMM協方差型別,在訓練和測試資料上繪製預測標籤。將gmm與球形、對角線、滿協方差矩陣和繫結協方差矩陣按效能遞增順序進行比較。儘管人們期望完全協方差在一般情況下表現最好,但它容易在小資料集上過度擬合,並不能很好地推廣到測試資料上。
如下圖,訓練集以點表示,驗證集以叉表示。iris資料集是四維的。這裡只顯示了前兩個維度,因此有些點在其他維度上是分離的。
# Author: Ron Weiss , Gael Varoquaux# Modified by Thierry Guillemot # License: BSD 3 clauseimport matplotlib as mplimport matplotlib。pyplot as pltimport numpy as npfrom sklearn import datasetsfrom sklearn。mixture import GaussianMixturefrom sklearn。model_selection import StratifiedKFoldprint(__doc__)colors = [‘navy’, ‘turquoise’, ‘darkorange’]def make_ellipses(gmm, ax): for n, color in enumerate(colors): if gmm。covariance_type == ‘full’: covariances = gmm。covariances_[n][:2, :2] elif gmm。covariance_type == ‘tied’: covariances = gmm。covariances_[:2, :2] elif gmm。covariance_type == ‘diag’: covariances = np。diag(gmm。covariances_[n][:2]) elif gmm。covariance_type == ‘spherical’: covariances = np。eye(gmm。means_。shape[1]) * gmm。covariances_[n] v, w = np。linalg。eigh(covariances) u = w[0] / np。linalg。norm(w[0]) angle = np。arctan2(u[1], u[0]) angle = 180 * angle / np。pi # convert to degrees v = 2。 * np。sqrt(2。) * np。sqrt(v) ell = mpl。patches。Ellipse(gmm。means_[n, :2], v[0], v[1], 180 + angle, color=color) ell。set_clip_box(ax。bbox) ell。set_alpha(0。5) ax。add_artist(ell) ax。set_aspect(‘equal’, ‘datalim’)iris = datasets。load_iris()# Break up the dataset into non-overlapping training (75%) and testing# (25%) sets。skf = StratifiedKFold(n_splits=4)# Only take the first fold。train_index, test_index = next(iter(skf。split(iris。data, iris。target)))X_train = iris。data[train_index]y_train = iris。target[train_index]X_test = iris。data[test_index]y_test = iris。target[test_index]n_classes = len(np。unique(y_train))# Try GMMs using different types of covariances。estimators = {cov_type: GaussianMixture(n_components=n_classes, covariance_type=cov_type, max_iter=20, random_state=0) for cov_type in [‘spherical’, ‘diag’, ‘tied’, ‘full’]}n_estimators = len(estimators)plt。figure(figsize=(3 * n_estimators // 2, 6))plt。subplots_adjust(bottom=。01, top=0。95, hspace=。15, wspace=。05, left=。01, right=。99)for index, (name, estimator) in enumerate(estimators。items()): # Since we have class labels for the training data, we can # initialize the GMM parameters in a supervised manner。 estimator。means_init = np。array([X_train[y_train == i]。mean(axis=0) for i in range(n_classes)]) # Train the other parameters using the EM algorithm。 estimator。fit(X_train) h = plt。subplot(2, n_estimators // 2, index + 1) make_ellipses(estimator, h) for n, color in enumerate(colors): data = iris。data[iris。target == n] plt。scatter(data[:, 0], data[:, 1], s=0。8, color=color, label=iris。target_names[n]) # Plot the test data with crosses for n, color in enumerate(colors): data = X_test[y_test == n] plt。scatter(data[:, 0], data[:, 1], marker=‘x’, color=color) y_train_pred = estimator。predict(X_train) train_accuracy = np。mean(y_train_pred。ravel() == y_train。ravel()) * 100 plt。text(0。05, 0。9, ‘Train accuracy: %。1f’ % train_accuracy, transform=h。transAxes) y_test_pred = estimator。predict(X_test) test_accuracy = np。mean(y_test_pred。ravel() == y_test。ravel()) * 100 plt。text(0。05, 0。8, ‘Test accuracy: %。1f’ % test_accuracy, transform=h。transAxes) plt。xticks(()) plt。yticks(()) plt。title(name)plt。legend(scatterpoints=1, loc=‘lower right’, prop=dict(size=12))plt。show()
4. k-means和GMM的關係
在特定條件下,k-means和GMM方法可以互相用對方的思想來表達。在k-means中根據距離每個點最接近的類中心來標記該點的類別,這裡存在的假設是每個類簇的尺度接近且特徵的分佈不存在不均勻性。這也解釋了為什麼在使用k-means前對資料進行歸一會有效果。高斯混合模型則不會受到這個約束,因為它對每個類簇分別考察特徵的協方差模型。
K-means演算法可以被視為高斯混合模型(GMM)的一種特殊形式。
整體上看,高斯混合模型能提供更強的描述能力,因為聚類時資料點的從屬關係不僅與近鄰相關,還會依賴於類簇的形狀。n維高斯分佈的形狀由每個類簇的協方差來決定。在協方差矩陣上新增特定的約束條件後,可能會透過GMM和k-means得到相同的結果。
實踐中如果每個類簇的協方差矩陣繫結在一起(就是說它們完全相同),並且矩陣對角線上的協方差數值保持相同,其他數值則全部為0,這樣能夠生成具有相同尺寸且形狀為圓形類簇。在此條件下,每個點都始終屬於最近的中間點對應的類。
在k-means方法中使用EM來訓練高斯混合模型時對初始值的設定非常敏感。而對比k-means,GMM方法有更多的初始條件要設定。實踐中不僅初始類中心要指定,而且協方差矩陣和混合權重也要設定。可以執行k-means來生成類中心,並以此作為高斯混合模型的初始條件。由此可見並兩個演算法有相似的處理過程,主要區別在於模型的複雜度不同。
整體來看,所有無監督機器學習演算法都遵循一條簡單的模式:給定一系列資料,訓練出一個能描述這些資料規律的模型(並期望潛在過程能生成資料)。
訓練過程通常要反覆迭代,直到無法再最佳化引數獲得更貼合數據的模型為止。
(1)獲取更多優質內容及精彩資訊,可前往:https://www.cda.cn/?seo
(2)瞭解更多資料領域的優質課程: