# 機器學習 06:無監督式學習-KMeans、DBSCAN ###### tags: `ML model`, `Unsupervised Learning`, `KMeans`, `DBSCAN` ## K-means 1. 先決定要分為 k 群 2. 將每一個點分到離自己最近的一個質心 3. 重新計算並最小化歐式距離調整質心位置 ```python= from sklearn.cluster import KMeans k = 5 kmeans = KMeans(n_clusters=k) y_pred = kmeans.fit_predict(X) # 找質心 kmeans.cluster_centers_ ``` 若資料團的直徑差異很大,則在 K-means 的表現會較差,因為此演算法只在乎質心離資料點的距離。 - 硬分類 將各資料點分到單一群體。 - 軟分類 將各資料點指定它屬於各群體的分數,此分數可以是距離、相似度或高斯函數等。 ```python= # 該點到質心的距離矩陣 kmeans.transform(X_new) ``` <font color="#f00">**同時可用這個技巧對資料做轉換,是個非常高效的非線性降維法。**</font> <br> ### 選擇初始質心的方法 1. 指定質心位置 設定質心的位置,並將 n_init 設為 1。 ```python= good_init = np.array([[-3, 3], [-3, 2], [-1, 2], [0, 2]]) kmeans = KMeans(n_clusters=5, init=good_init, n_init=1) ``` 2. 使用隨機初始值執行多次 KMeans 會執行演算法 n_init 次,並保留 intertia(各資料點和距離最近的質心均方距離)最低的模型。 3. KMeans++ 初始質心間的距離越遠越好,可大幅減少演算法尋找最佳解的次數,也可以防止演算法收斂至次佳解。 <br> ### KMeans 的限制 必須執行演算法多次來避免得到次佳解,此外如果群聚大小不一致、有不同的密度、或不是球形時,KMeans 表現不會太好。 ![](https://i.imgur.com/UVhr9th.png) <br> ### 用分群來做圖像分割 圖像分割是將一張圖分成多個子圖,此處為顏色分割,單純將顏色相近的像素分到同一個子圖,實際的應用如:計算某個區域森林總面積。 ![](https://i.imgur.com/184Vf8z.png) ```python= X = image.reshape(-1, 3) kmeans = KMeans(n_clusters=8, random_state=42).fit(X) # 8色 segmented_img = kmeans.cluster_centers_[kmeans.labels_] # 將點換成質心顏色 segmented_img = segmented_img.reshape(image.shape) ``` ![](https://i.imgur.com/n3RBCnB.png) 由於瓢蟲的紅色站很小比例,所以在 8 色以下會被納入其餘的部分。 --- ## DBSCAN 1. 幫每一個資料點計算有多少資料點離它一小段距離 $ε$ 內,該區域稱為該資料點的 $ε$ 近鄰。 2. 如果某個資料點有至少 min_samples 個資料點在它的 $ε$ 近鄰之內(包括自己),就將它視為核資料點(core instance)。 3. 在核資料點近鄰的所有資料點或核資料點都將組成一個群體。 4. 如果某個資料點不是和資料點,而且近鄰沒有核資料點,就將它視為異常資料點。 ```python= from sklearn.cluster import DBSCAN from sklearn.datasets import make_moons X, y = make_moons(n_samples=1000, noise=0.05) dbscan = DBSCAN(eps=0.05, min_samples=5) dbscan.fit(X) # 取得所有資料點的標籤,標籤是 -1 的代表異常資料點 dbscan.labels_ # 資料點變數取得核資料點的索引,len()代表有幾個核資料點 len(dbscan.core_sample_indices_) # 核資料點位置 dbscan.components_ ``` ![](https://i.imgur.com/WWw1tgt.png)