KMeans 是一種常見的非監督式學習演算法,適用於將資料點分群。在數字影像分群的案例中,我們將影像資料轉換成適合 KMeans 處理的格式,並利用 KMeans 找出分群中心,藉此將數字影像分類別。為提升分群準確性,我們使用 t-SNE 進行資料降維與預處理,有效改善 KMeans 在高維資料上的表現。除了分群,KMeans 也能應用於影像壓縮。透過 KMeans 將影像畫素分群,並以分群中心代表新的顏色,能有效減少顏色數量,達到壓縮影像的目的。GMM 則是一種更進階的資料分群模型,相較於 KMeans 假設分群為圓形,GMM 能處理更複雜的資料分佈,並提供每個資料點屬於各分群的機率。我們利用 GMM 進行手寫數字生成,透過學習數字的資料分佈,生成新的手寫數字樣本。此外,GMM 也能應用於密度估計,藉由多個高斯分佈的組合,更精確地描述資料的密度分佈。
使用KMeans演算法進行數字分群
在這個例子中,我們使用KMeans演算法來對數字影像進行分群。首先,我們需要將影像資料轉換為合適的格式。然後,我們可以使用KMeans演算法來找到數字分群的中心。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import accuracy_score, confusion_matrix
import seaborn as sns
from scipy.stats import mode
from sklearn.manifold import TSNE
# 載入數字影像資料
digits =...
# 對數字影像進行KMeans分群
kmeans = KMeans(n_clusters=10)
clusters = kmeans.fit_predict(digits.data)
# 取得分群中心
center = kmeans.cluster_centers_.reshape(10, 8, 8)
# 顯示分群中心
plt.figure(figsize=(10, 10))
for i in range(10):
plt.subplot(2, 5, i+1)
plt.imshow(center[i], interpolation='nearest', cmap=plt.cm.binary)
plt.xticks([])
plt.yticks([])
plt.show()
# 對分群結果進行標籤修正
labels = np.zeros_like(clusters)
for i in range(10):
mask = (clusters == i)
labels[mask] = mode(digits.target[mask])[0]
# 評估分群結果的準確性
accuracy = accuracy_score(digits.target, labels)
print(f"準確性:{accuracy:.3f}")
# 顯示混淆矩陣
mat = confusion_matrix(digits.target, labels)
plt.figure(figsize=(10, 10))
sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=False, cmap='Blues',
xticklabels=digits.target_names, yticklabels=digits.target_names)
plt.xlabel('真實標籤')
plt.ylabel('預測標籤')
plt.show()
# 使用t-SNE演算法進行資料預處理
tsne = TSNE(n_components=2, init='random')
digits_tsne = tsne.fit_transform(digits.data)
# 對預處理後的資料進行KMeans分群
kmeans_tsne = KMeans(n_clusters=10)
clusters_tsne = kmeans_tsne.fit_predict(digits_tsne)
# 對分群結果進行標籤修正
labels_tsne = np.zeros_like(clusters_tsne)
for i in range(10):
mask = (clusters_tsne == i)
labels_tsne[mask] = mode(digits.target[mask])[0]
# 評估分群結果的準確性
accuracy_tsne = accuracy_score(digits.target, labels_tsne)
print(f"準確性(t-SNE):{accuracy_tsne:.3f}")
# 顯示混淆矩陣
mat_tsne = confusion_matrix(digits.target, labels_tsne)
plt.figure(figsize=(10, 10))
sns.heatmap(mat_tsne.T, square=True, annot=True, fmt='d', cbar=False, cmap='Blues',
xticklabels=digits.target_names, yticklabels=digits.target_names)
plt.xlabel('真實標籤')
plt.ylabel('預測標籤')
plt.show()
內容解密:
- 我們使用KMeans演算法來對數字影像進行分群。
- 首先,我們需要將影像資料轉換為合適的格式。
- 然後,我們可以使用KMeans演算法來找到數字分群的中心。
- 我們對分群結果進行標籤修正,以確保分群結果的準確性。
- 我們評估分群結果的準確性,並顯示混淆矩陣。
- 我們使用t-SNE演算法進行資料預處理,以改善分群結果的準確性。
圖表翻譯:
- 圖47-9顯示了KMeans演算法學習到的分群中心。
- 圖47-10顯示了混淆矩陣,描述了真實標籤和預測標籤之間的關係。
- 圖47-11顯示了使用t-SNE演算法進行資料預處理後的混淆矩陣。
無監督學習的威力:使用 K-Means 進行資料分析
在這個例子中,我們將使用 K-Means 演算法來對資料進行聚類別,並且不使用標籤。這個過程可以從資料中提取出有用的資訊,甚至可以達到 94% 的分類別準確率。
from sklearn.manifold import TSNE
from sklearn.cluster import KMeans
from sklearn import metrics
import numpy as np
# 對資料進行降維
tsne = TSNE(n_components=2, learning_rate='auto', random_state=0)
digits_proj = tsne.fit_transform(digits.data)
# 進行 K-Means 聚類別
kmeans = KMeans(n_clusters=10, random_state=0)
clusters = kmeans.fit_predict(digits_proj)
# 對標籤進行重新排列
labels = np.zeros_like(clusters)
for i in range(10):
mask = (clusters == i)
labels[mask] = metrics.mode(digits.target[mask])[0]
# 計算準確率
accuracy = metrics.accuracy_score(digits.target, labels)
print("準確率:", accuracy)
圖表翻譯:
這個流程圖展示瞭如何使用 K-Means 進行資料分析的步驟,從降維到聚類別、重新排列標籤,最後計算準確率。
顏色壓縮:K-Means 的另一個應用
K-Means 也可以用於顏色壓縮,這是一種減少影像中顏色數量的技術。透過對影像中的畫素進行聚類別,可以減少影像中的顏色數量,從而達到壓縮的效果。
from sklearn.datasets import load_sample_image
import numpy as np
# 載入影像
china = load_sample_image("china.jpg")
# 對影像進行聚類別
kmeans = KMeans(n_clusters=64, random_state=0)
clusters = kmeans.fit_predict(china.reshape(-1, 3))
# 對影像進行重建
reconstructed_image = kmeans.cluster_centers_[clusters].reshape(china.shape)
內容解密:
這個程式碼展示瞭如何使用 K-Means 進行顏色壓縮的步驟,從載入影像到對影像進行聚類別,最後對影像進行重建。透過減少影像中的顏色數量,可以達到壓縮的效果。
圖表翻譯:
這個流程圖展示瞭如何使用 K-Means 進行顏色壓縮的步驟,從影像到聚類別、重建,最後達到壓縮的效果。
影像處理與視覺化
在影像處理中,我們經常遇到需要將影像轉換為資料陣列以進行分析和視覺化的需求。下面,我們將探討如何將一張影像轉換為三維陣列,並對其進行視覺化。
影像陣列轉換
首先,我們需要將影像轉換為資料陣列。這個過程涉及到將影像的每個畫素轉換為紅、綠、藍(RGB)值。這些值通常儲存為整數,範圍從0到255。
import numpy as np
import matplotlib.pyplot as plt
# 載入影像
img = plt.imread('china.jpg')
# 將影像轉換為三維陣列
data = img / 255.0 # 將RGB值縮放到0到1之間
# 將陣列重塑為[n_samples, n_features]
data = data.reshape(-1, 3)
print(data.shape)
資料視覺化
接下來,我們可以將這些資料點視覺化為三維空間中的點雲。為了效率起見,我們通常只選擇一部分資料點進行視覺化。
def plot_pixels(data, title, colors=None, N=10000):
if colors is None:
colors = data
# 選擇隨機子集
rng = np.random.default_rng(0)
i = rng.permutation(data.shape[0])[:N]
colors = colors[i]
R, G, B = data[i].T
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
ax[0].scatter(R, G, color=colors, marker='.')
ax[0].set(xlabel='Red', ylabel='Green', xlim=(0, 1), ylim=(0, 1))
ax[1].scatter(R, B, color=colors, marker='.')
ax[1].set(xlabel='Red', ylabel='Blue', xlim=(0, 1), ylim=(0, 1))
fig.suptitle(title, size=20)
plot_pixels(data, title='Input color space: 16 million possible colors')
圖表翻譯:
上述程式碼展示瞭如何將影像轉換為三維陣列,並對其進行視覺化。首先,影像被載入並轉換為RGB值陣列,然後這個陣列被重塑為[n_samples, n_features]的形式。接著,選擇了一部分隨機資料點,並使用matplotlib進行視覺化,分別在紅-綠和紅-藍平面上繪製散點圖。
使用K-means演算法進行影像壓縮
在這個例子中,我們將使用K-means演算法來壓縮一張影像。首先,我們需要匯入必要的函式庫,包括sklearn和matplotlib。
from sklearn.cluster import MiniBatchKMeans
import matplotlib.pyplot as plt
import numpy as np
接下來,我們將載入一張影像,並將其轉換為RGB色彩空間。
# 載入影像
china =...
# 將影像轉換為RGB色彩空間
data = china.reshape(-1, 3)
現在,我們可以使用MiniBatchKMeans演算法來壓縮影像。首先,我們需要建立一個MiniBatchKMeans物件,並設定其引數。
# 建立MiniBatchKMeans物件
kmeans = MiniBatchKMeans(16)
# 訓練模型
kmeans.fit(data)
# 預測新的色彩
new_colors = kmeans.cluster_centers_[kmeans.predict(data)]
最後,我們可以將新的色彩應用到原始影像上,並顯示結果。
# 將新的色彩應用到原始影像上
china_recolored = new_colors.reshape(china.shape)
# 顯示結果
fig, ax = plt.subplots(1, 2, figsize=(16, 6))
ax[0].imshow(china)
ax[0].set_title('原始影像', size=16)
ax[1].imshow(china_recolored)
ax[1].set_title('16色影像', size=16)
plt.show()
這個例子展示瞭如何使用K-means演算法來壓縮一張影像。透過將原始影像的色彩空間從16,000,000種色彩減少到16種色彩,我們可以達到約1百萬倍的壓縮比。
內容解密:
- 我們使用MiniBatchKMeans演算法來壓縮影像,因為它比標準的K-means演算法更快。
- 我們設定MiniBatchKMeans物件的引數為16,這意味著我們想要將原始影像的色彩空間減少到16種色彩。
- 我們使用
fit方法來訓練模型,並使用predict方法來預測新的色彩。 - 我們將新的色彩應用到原始影像上,並顯示結果。
圖表翻譯:
- 原始影像(左)和16色影像(右)的比較。
- 圖表顯示了使用K-means演算法壓縮影像的效果。雖然有些細節丟失了,但整體影像是仍然容易辨識的。
- 圖表也展示了壓縮比約為1百萬倍。
使用KMeans進行資料分群
在進行資料分群時,KMeans是一種常見的演算法。以下是使用KMeans進行資料分群的範例。
產生資料
首先,我們需要產生一些資料來進行分群。這裡我們使用make_blobs函式來產生400個樣本,分成4個叢集,每個叢集的標準差為0.60。
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
X, y_true = make_blobs(n_samples=400, centers=4, cluster_std=0.60, random_state=0)
X = X[:, ::-1] # flip axes for better plotting
進行KMeans分群
接下來,我們使用KMeans演算法來進行分群。這裡我們設定叢集數為4,隨機種子為0。
from sklearn.cluster import KMeans
kmeans = KMeans(4, random_state=0)
labels = kmeans.fit_predict(X)
繪製分群結果
最後,我們繪製分群結果。
plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')
plt.show()
KMeans模型的限制
雖然KMeans是一種常見的分群演算法,但它有一些限制。例如,它不能提供叢集分配的機率或不確定性。此外,KMeans模型假設每個叢集都是一個圓形(或高維度中的超球體),這可能不能準確反映真實資料的分佈。
模型的視覺化
為了更好地理解KMeans模型,我們可以視覺化它。以下是視覺化KMeans模型的範例。
from scipy.spatial.distance import cdist
def plot_kmeans(kmeans, X, n_clusters=4, rseed=0, ax=None):
labels = kmeans.fit_predict(X)
ax = ax or plt.gca()
ax.axis('equal')
ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2)
centers = kmeans.cluster_centers_
radii = [cdist(X[labels == i], [center]).max() for i, center in enumerate(centers)]
for c, r in zip(centers, radii):
ax.add_patch(plt.Circle(c, r, ec='black', fc='lightgray', zorder=1))
plot_kmeans(kmeans, X)
plt.show()
圖表翻譯:
上述程式碼會產生兩個圖表。第一個圖表顯示KMeans分群的結果,每個點的顏色代表它所屬的叢集。第二個圖表視覺化了KMeans模型,每個叢集用一個圓圈代表,圓圈的半徑代表了叢集的大小。這兩個圖表可以幫助我們更好地理解KMeans模型和它的限制。
使用KMeans進行資料分群
在進行資料分群時,KMeans是一種常見的演算法,但它有著一些限制。例如,KMeans假設所有的分群都是圓形的,如果資料中存在非圓形的分群,KMeans可能無法正確地進行分群。
KMeans的限制
以下是使用KMeans進行資料分群的限制:
- KMeans假設所有的分群都是圓形的,如果資料中存在非圓形的分群,KMeans可能無法正確地進行分群。
- KMeans不提供機率性的分群指派,這意味著每個資料點只會被指派到一個分群中,而不是提供一個機率分佈。
Gaussian Mixture Model(GMM)
為瞭解決KMeans的限制,我們可以使用Gaussian Mixture Model(GMM)進行資料分群。GMM是一種機率模型,它假設資料是由多個高斯分佈組成的。
GMM的優點
以下是使用GMM進行資料分群的優點:
- GMM可以處理非圓形的分群。
- GMM提供機率性的分群指派,這意味著每個資料點都會被指派到多個分群中,並且會提供一個機率分佈。
使用GMM進行資料分群
以下是使用GMM進行資料分群的步驟:
- 匯入必要的套件:```python from sklearn.mixture import GaussianMixture import numpy as np import matplotlib.pyplot as plt
2. 建立一個GMM物件:```python
gmm = GaussianMixture(n_components=4)
- 對資料進行fit:```python gmm.fit(X)
4. 預測分群標籤:```python
labels = gmm.predict(X)
- 繪製分群結果:```python plt.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap=‘viridis’)
6. 預測機率分佈:```python
probs = gmm.predict_proba(X)
圖表翻譯:
以下是圖表的翻譯:
- 圖48-2:KMeans對於圓形分群的結果。
- 圖48-3:KMeans對於非圓形分群的結果。
- 圖48-4:GMM對於資料的分群結果。
內容解密:
以下是內容的解密:
- KMeans是一種簡單且快速的演算法,但它有著一些限制。
- GMM是一種更為複雜的模型,它可以處理非圓形的分群,並且提供機率性的分群指派。
- 透過使用GMM,我們可以獲得更為準確的分群結果。
程式碼解說:
以下是程式碼的解說:
gmm = GaussianMixture(n_components=4): 建立一個GMM物件,設定分群數量為4。gmm.fit(X): 對資料進行fit。labels = gmm.predict(X): 預測分群標籤。probs = gmm.predict_proba(X): 預測機率分佈。
以下是
- 研究如何改進GMM以處理更為複雜的資料。
- 研究如何將GMM應用於其他領域,例如影像處理、自然語言處理等。
高斯混合模型(GMM)概覽
高斯混合模型(GMM)是一種常用的無監督學習演算法,用於分群分析。它與K-means演算法相似,但GMM更為靈活,因為它可以處理不同形狀和大小的分群。
GMM的工作原理
GMM使用期望-最大化(EM)演算法來找出最佳的分群結果。這個過程包括以下步驟:
- 初始化:選擇初始的分群中心和covariance矩陣。
- E-step:計算每個資料點屬於每個分群的機率。
- M-step:根據E-step中計算的機率,更新每個分群的中心和covariance矩陣。
視覺化GMM結果
為了更好地理解GMM的結果,我們可以使用matplotlib函式庫來視覺化分群結果。下面的程式碼展示瞭如何繪製GMM分群結果:
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
import numpy as np
# 載入資料
X = np.random.rand(100, 2)
# 建立GMM模型
gmm = GaussianMixture(n_components=3)
# 訓練模型
gmm.fit(X)
# 預測分群標籤
labels = gmm.predict(X)
# 繪製分群結果
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
plt.show()
自定義視覺化函式
為了更好地展示GMM分群結果,我們可以定義一個自定義的視覺化函式。這個函式可以繪製每個分群的邊界和形狀:
def plot_gmm(gmm, X, label=True, ax=None):
ax = ax or plt.gca()
labels = gmm.fit(X).predict(X)
if label:
ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis')
# 繪製每個分群的邊界和形狀
for i, (mean, cov) in enumerate(zip(gmm.means_, gmm.covariances_)):
# Convert covariance to principal axes
if cov.shape == (2, 2):
U, s, Vt = np.linalg.svd(cov)
angle = np.degrees(np.arctan2(U[1, 0], U[0, 0]))
width, height = 2 * np.sqrt(s)
else:
angle = 0
width, height = 2 * np.sqrt(cov)
# Draw the ellipse
for nsig in range(1, 4):
ax.add_patch(Ellipse(mean, nsig * width, nsig * height, angle))
應用GMM進行分群分析
GMM可以應用於各種分群分析任務,例如客戶分段、影像分割等。下面的程式碼展示瞭如何使用GMM進行客戶分段:
# 載入客戶資料
customer_data = np.random.rand(100, 2)
# 建立GMM模型
gmm = GaussianMixture(n_components=3)
# 訓練模型
gmm.fit(customer_data)
# 預測客戶分段標籤
labels = gmm.predict(customer_data)
# 繪製客戶分段結果
plt.scatter(customer_data[:, 0], customer_data[:, 1], c=labels, cmap='viridis')
plt.show()
這些範例展示瞭如何使用GMM進行分群分析和視覺化結果。GMM是一種強大的工具,可以幫助您發現資料中的隱藏模式和結構。
高斯混合模型(GMM)及其應用
高斯混合模型(Gaussian Mixture Model, GMM)是一種強大的機器學習演算法,常用於資料分群(clustering)和密度估計(density estimation)。在本文中,我們將探討GMM的基本概念、其應用以及如何使用Python實作GMM。
GMM的基本概念
GMM是一種機率模型,假設資料來自多個高斯分佈的混合。每個高斯分佈代表一個分群,模型會學習每個分群的引數,包括均值、協方差和權重。GMM的目標是找到最佳的模型引數,使得模型能夠最好地描述資料的分佈。
GMM的應用
GMM常用於以下應用:
- 資料分群:GMM可以用於將資料分成多個分群,每個分群代表一個高斯分佈。
- 密度估計:GMM可以用於估計資料的密度分佈。
- 異常偵測:GMM可以用於偵測資料中的異常值。
使用Python實作GMM
在Python中,可以使用scikit-learn函式庫實作GMM。以下是使用GMM進行資料分群的範例:
from sklearn.mixture import GaussianMixture
import numpy as np
import matplotlib.pyplot as plt
# 生成示範資料
np.random.seed(0)
mean1 = [0, 0]
cov1 = [[1, 0], [0, 1]]
data1 = np.random.multivariate_normal(mean1, cov1, 100)
mean2 = [5, 5]
cov2 = [[2, 0], [0, 2]]
data2 = np.random.multivariate_normal(mean2, cov2, 100)
X = np.vstack((data1, data2))
# 建立GMM模型
gmm = GaussianMixture(n_components=2, covariance_type='full', random_state=0)
# 訓練模型
gmm.fit(X)
# 預測分群
labels = gmm.predict(X)
# 繪製結果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.show()
在這個範例中,我們生成了兩個高斯分佈的資料,然後使用GMM模型將資料分成兩個分群。最後,我們繪製了分群的結果。
選擇協方差型別
在GMM中,協方差型別(covariance type)是個重要的超引數。協方差型別決定了每個高斯分佈的協方差矩陣的形狀。有三種協方差型別:
diag:對角線協方差矩陣,每個維度的協方差是獨立的。spherical:球面協方差矩陣,每個維度的協方差是相同的。full:完整協方差矩陣,每個維度的協方差可以是任意的。
選擇適合的協方差型別對於GMM的效能有很大的影響。一般來說,full協方差型別可以提供最好的效能,但也最耗費計算資源。
GMM作為密度估計
雖然GMM常用於資料分群,但其實GMM是一種密度估計演算法。GMM可以用於估計資料的密度分佈,並且可以用於生成新的資料。
以下是使用GMM進行密度估計的範例:
from sklearn.mixture import GaussianMixture
import numpy as np
import matplotlib.pyplot as plt
# 生成示範資料
np.random.seed(0)
mean1 = [0, 0]
cov1 = [[1, 0], [0, 1]]
data1 = np.random.multivariate_normal(mean1, cov1, 100)
mean2 = [5, 5]
cov2 = [[2, 0], [0, 2]]
data2 = np.random.multivariate_normal(mean2, cov2, 100)
X = np.vstack((data1, data2))
# 建立GMM模型
gmm = GaussianMixture(n_components=2, covariance_type='full', random_state=0)
# 訓練模型
gmm.fit(X)
# 估計密度
x = np.linspace(-5, 10, 100)
y = np.linspace(-5, 10, 100)
x, y = np.meshgrid(x, y)
pos = np.dstack((x, y))
density = gmm.score_samples(pos)
# 繪製結果
plt.contourf(x, y, density)
plt.show()
在這個範例中,我們使用GMM模型估計了資料的密度分佈,並且繪製了密度分佈的等高線圖。
使用高斯混合模型(GMM)進行資料分佈建模
在前面的章節中,我們探討瞭如何使用高斯混合模型(GMM)進行資料分佈建模。GMM是一種強大的工具,可以用來模擬複雜的資料分佈。以下是使用GMM進行資料分佈建模的步驟:
載入必要的套件
import numpy as np
import matplotlib.pyplot as plt
from sklearn.mixture import GaussianMixture
載入資料
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
建立GMM模型
gmm = GaussianMixture(n_components=3, covariance_type='full', random_state=0)
gmm.fit(X)
繪製GMM模型
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
plt.scatter(X_pca[:, 0], X_pca[:, 1])
plt.show()
使用GMM模型生成新資料
X_new, _ = gmm.sample(100)
plt.scatter(X_new[:, 0], X_new[:, 1])
plt.show()
內容解密:
在上面的程式碼中,我們首先載入必要的套件,包括NumPy、Matplotlib和Scikit-learn。然後,我們載入iris資料集,並建立一個GMM模型,設定n_components為3,表示我們想要將資料分成3個群組。接著,我們使用fit()方法訓練GMM模型。最後,我們使用sample()方法生成新資料,並繪製出來。
圖表翻譯:
上面的圖表顯示了使用GMM模型生成的新資料。由圖表可以看出,新資料的分佈與原始資料的分佈相似,表明GMM模型成功地學習了原始資料的分佈特性。
AIC和BIC的計算
n_components = np.arange(1, 11)
models = [GaussianMixture(n, covariance_type='full', random_state=0).fit(X) for n in n_components]
plt.plot(n_components, [m.bic(X) for m in models], label='BIC')
plt.plot(n_components, [m.aic(X) for m in models], label='AIC')
plt.legend(loc='best')
plt.xlabel('n_components')
plt.show()
內容解密:
在上面的程式碼中,我們計算了AIC和BIC的值,並繪製出來。AIC和BIC是兩種常用的模型選擇指標,可以用來評估模型的優劣。由圖表可以看出,AIC和BIC的值隨著n_components的增加而減少,表明模型的複雜度增加了。
圖表翻譯:
上面的圖表顯示了AIC和BIC的變化趨勢。由圖表可以看出,當n_components增加到一定程度時,AIC和BIC的值會停止減少,甚至開始增加,表明模型過度複雜了。因此,我們需要選擇一個合適的n_components值,使得模型既能夠準確地模擬資料,又不會過度複雜。
使用高斯混合模型(GMM)生成手寫數字
在這個例子中,我們將使用高斯混合模型(GMM)來生成手寫數字。首先,我們需要載入手寫數字資料集。
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
import numpy as np
from sklearn.decomposition import PCA
from sklearn.mixture import GaussianMixture
# 載入手寫數字資料集
digits = load_digits()
print(digits.data.shape)
接下來,我們將繪製前 50 個手寫數字,以便回憶我們正在處理的資料。
def plot_digits(data):
fig, ax = plt.subplots(5, 10, figsize=(8, 4), subplot_kw=dict(xticks=[], yticks=[]))
fig.subplots_adjust(hspace=0.05, wspace=0.05)
for i, axi in enumerate(ax.flat):
im = axi.imshow(data[i].reshape(8, 8), cmap='binary')
im.set_clim(0, 16)
plt.show()
plot_digits(digits.data)
由於高維度空間中的 GMM 收斂困難,我們將使用 PCA 對資料進行降維。這裡,我們要求 PCA 保留 99% 的變異數。
pca = PCA(0.99, whiten=True)
data = pca.fit_transform(digits.data)
print(data.shape)
現在,我們將使用 AIC 來確定 GMM 中的元件數量。
n_components = np.arange(50, 210, 10)
models = [GaussianMixture(n, covariance_type='full', random_state=0) for n in n_components]
aics = [model.fit(data).aic(data) for model in models]
plt.plot(n_components, aics)
plt.show()
根據 AIC 曲線,約 140 個元件最小化了 AIC。我們將使用這個模型,並快速地將其適應於資料以確認其收斂性。
gmm = GaussianMixture(140, covariance_type='full', random_state=0)
gmm.fit(data)
內容解密:
上述程式碼首先載入手寫數字資料集,然後繪製前 50 個數字。接下來,使用 PCA 對資料進行降維,以避免高維度空間中的收斂問題。然後,使用 AIC 來選擇 GMM 中的最佳元件數量,並使用該模型適應資料。
圖表翻譯:
上述程式碼生成了兩個圖表:手寫數字輸入圖和 AIC 曲線圖。手寫數字輸入圖顯示了前 50 個手寫數字的外觀,而 AIC 曲線圖則顯示了不同元件數量下的 AIC 值,幫助我們選擇最佳的 GMM 模型。
圖表翻譯:
上述流程圖描述了整個過程:載入資料集、繪製手寫數字、使用 PCA 進行降維、使用 AIC 選擇 GMM 元件數量以及適應 GMM 於資料。這個流程圖幫助我們瞭解如何使用 GMM 生成手寫數字。
使用Kernel密度估計進行資料分析
在前一章中,我們探討了高斯混合模型(Gaussian Mixture Model, GMM),它是一種結合了聚類別和密度估計的混合模型。密度估計是一種演算法,它接收一組D維資料,並生成這些資料所遵循的D維機率分佈的估計。GMM透過使用多個高斯分佈來近似資料分佈來實作這一點。另一方面,核密度估計(Kernel Density Estimation, KDE)是一種更為極端的方法,它使用每個資料點的一個高斯分佈,從而得到一個幾乎非引數化的密度估計器。
簡介
首先,我們需要匯入必要的函式庫,包括matplotlib和numpy,以便進行資料視覺化和計算。
import matplotlib.pyplot as plt
import numpy as np
動機:直方圖
對於一維資料,直方圖是一種簡單的密度估計器。它透過將資料分成離散的桶,計算每個桶中的點數量,並以直觀的方式進行視覺化。然而,直方圖有一個缺點,就是它對桶的大小和位置很敏感。
def make_data(N, f=0.3, rseed=1):
rand = np.random.RandomState(rseed)
x = rand.randn(N)
return x
核密度估計
KDE是一種更為靈活的方法,它使用每個資料點的一個高斯分佈來估計密度。這種方法可以自動適應資料的分佈形狀,不需要人工設定桶的大小和位置。
from scipy.stats import gaussian_kde
def kde_estimate(x):
kde = gaussian_kde(x)
return kde
視覺化
我們可以使用matplotlib來視覺化KDE估計的結果。
def plot_kde(x, kde):
x_eval = np.linspace(x.min(), x.max(), 1000)
y_eval = kde(x_eval)
plt.plot(x_eval, y_eval)
plt.show()
示例
讓我們建立一些資料,並使用KDE進行密度估計。
x = make_data(1000)
kde = kde_estimate(x)
plot_kde(x, kde)
這將生成一個圖表,展示了KDE估計的密度分佈。
使用直方圖進行資料視覺化
在資料科學中,直方圖是一種常見的資料視覺化工具,用於展示資料的分佈情況。Python 的 matplotlib 函式庫提供了 plt.hist 函式來建立直方圖。
建立標準直方圖
首先,我們可以使用 plt.hist 函式建立一個標準的直方圖。以下是範例程式碼:
import matplotlib.pyplot as plt
import numpy as np
def make_data(N):
# 產生隨機資料
x = np.random.normal(0, 1, N)
return x
x = make_data(1000)
hist = plt.hist(x, bins=30, density=True)
這段程式碼會產生一個包含 1000 個隨機資料點的資料集,並使用 plt.hist 函式建立一個直方圖。bins 引數指定了直方圖的 bin 數量,density 引數指定了是否要將直方圖 normalize 成密度函式。
直方圖的 Normalize
在上面的範例中,我們使用 density=True 引數將直方圖 normalize 成密度函式。這意味著直方圖的高度不再反映資料的計數,而是反映資料的密度。
density, bins, patches = hist
widths = bins[1:] - bins[:-1]
print((density * widths).sum()) # 輸出:1.0
這段程式碼計算了直方圖下方的面積,並印出結果。由於直方圖已經被 normalize 成密度函式,所以面積應該等於 1.0。
直方圖的 bin 大小和位置
使用直方圖作為密度估算器有一個問題,就是 bin 大小和位置的選擇可能會導致不同的特徵表現。例如,如果我們只使用 20 個資料點,bin 的選擇就可能導致完全不同的資料解釋。
x = make_data(20)
bins = np.linspace(-5, 10, 10)
這段程式碼產生了一個包含 20 個隨機資料點的資料集,並指定了 bin 的大小和位置。
多個子圖的視覺化
我們可以使用 plt.subplots 函式建立多個子圖,並在每個子圖中展示不同的資料視覺化。
fig, ax = plt.subplots(1, 2, figsize=(12, 4), sharex=True, sharey=True,
subplot_kw={'xlim':(-4, 9), 'ylim':(-0.02, 0.3)})
fig.subplots_adjust(wspace=0.05)
for i, offset in enumerate([0.0, 0.6]):
# 在每個子圖中繪製資料
pass
這段程式碼建立了兩個子圖,並指定了子圖的大小和位置。sharex 和 sharey 引數指定了子圖是否分享 x 軸和 y 軸。subplot_kw 引數指定了子圖的其他屬性。
內容解密:
在這個範例中,我們使用 plt.hist 函式建立了一個直方圖,並指定了 bin 的大小和位置。然後,我們計算了直方圖下方的面積,並印出結果。最後,我們建立了多個子圖,並在每個子圖中展示不同的資料視覺化。
圖表翻譯:
以下是直方圖的視覺化:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title KMeans與GMM演算法技術應用於影像處理與分群
package "影像處理流程" {
package "影像載入" {
component [讀取影像] as read
component [色彩空間轉換] as color
component [尺寸調整] as resize
}
package "影像處理" {
component [濾波器 Filter] as filter
component [邊緣檢測 Edge] as edge
component [形態學操作] as morph
component [特徵提取] as feature
}
package "深度學習" {
component [CNN 卷積網路] as cnn
component [物件偵測] as detect
component [影像分割] as segment
}
}
read --> color : BGR/RGB/Gray
color --> resize : 縮放
resize --> filter : 平滑/銳化
filter --> edge : Sobel/Canny
edge --> feature : SIFT/ORB
feature --> cnn : 特徵學習
cnn --> detect : YOLO/RCNN
cnn --> segment : U-Net/Mask RCNN
note right of cnn
卷積層提取特徵
池化層降維
全連接層分類
end note
@enduml這個流程圖展示了資料從資料集到直方圖,再到 normalize 成密度函式,最後計算面積的過程。
直方圖的侷限性與改進方法
直方圖是一種常用的資料視覺化工具,然而它也存在著一些侷限性。其中一個主要問題是直方圖的bin位置會影響對資料的解釋。如圖49-2所示,兩個不同的直方圖可以從同一組資料中生成,卻呈現出不同的分佈形態。這使得我們難以確定哪一個直方圖能夠準確地反映資料的真實分佈。
從資料視覺化與機器學習模型訓練的角度來看,本文深入探討了KMeans、高斯混合模型(GMM)以及核密度估計(KDE)等技術在資料分群、密度估計和影像壓縮等方面的應用。分析顯示,KMeans 演算法簡單高效,但其圓形分群的假設限制了其在複雜資料結構上的應用。GMM 則透過多個高斯分佈的混合,更精確地捕捉資料的非線性結構,並提供機率性的分群指派,彌補了 KMeans 的不足。此外,KDE 方法以其非引數化的特性,提供更細緻的密度估計,尤其適用於探索性資料分析。
技術限制方面,KMeans 對初始中心點敏感,且需要預先指定分群數量。GMM 雖然更具彈性,但計算成本相對較高,且模型引數的選擇也較為複雜。KDE 則對核函式和頻寬的選擇敏感,需要仔細調整以獲得最佳的密度估計效果。實務上,可以根據資料特性和應用場景選擇合適的演算法。例如,對於簡單的資料集和快速的原型設計,KMeans 是個不錯的選擇;而對於複雜的資料結構和需要機率性分群指派的場景,GMM 則更為合適;KDE 則更適用於探索性資料分析和視覺化。
展望未來,隨著資料量的增加和資料複雜性的提升,更精確且高效的密度估計和分群演算法將持續發展。例如,根據深度學習的聚類別方法和密度估計技術,有望在處理高維和非線性資料方面展現更大的優勢。同時,結合領域知識的模型最佳化和引數調整策略也將變得 increasingly 重要。玄貓認為,深入理解這些技術的優缺點和適用場景,並持續關注新興技術的發展,對於資料科學家和機器學習工程師至關重要。