均值算法是一種典型的無監督學習算法,用來對數據進行分類。
聚類問題 Clustering
針對監督式學習,輸入數據為 (x, y) ,目標是找出分類邊界,即對新的數據進行分類。而無監督式學習只給出一組數據集 ${x_1, x_2, ... , x_m}$ ,目標是去找出這組數據的模式特征,比如哪些數據是一種類型的,哪些數據是另外一種類型的。典型的無監督式學習包括市場細分,通過分析用戶數據,來把一個產品的市場進行細分,找出細分人群。另外一個是社交網絡分析,分析社交網絡中的參與人員的不同特點,根據特點區分出不同群體。這些都是無監督式學習里的聚類 (Clustering) 問題。
K 均值算法
K 均值算法算法就是一種解決聚類問題的算法,它包含兩個步驟:
- 給聚類中心分配點:計算所有的訓練樣例,把他分配到距離某個聚類中心最短的的那聚類里。
- 移動聚類中心:新的聚類中心移動到這個聚類所有的點的平均值處。
一直重復做上面的動作,直到聚類中心不再移動為止。這個時候我們就探索出了數據集的結構了。可以通過一個動畫來直觀地看一下 K 均值算法聚類的過程:
用數學的方法來描述 K 均值算法如下:
算法有兩個輸入信息。一是 K 表示選取的聚類個數;二是訓練數據集 ${x^{(1)}, x^{(2)}, ... , x^{(m)}}$。
- 隨機選擇 K 個聚類中心 $u_1, u_2, ... , u_k$。
- 從 1 - m 遍歷所有的數據集,計算 $x^{(i)}$ 分別到 $u_1, u_2, ... , u_k$ 的距離,記錄距離最短的聚類中心點。然后把 $x^{(i)}$ 這個點分配給這個聚類。令 $c^{(i)} = j$ 其中 $u_j$ 就是與 $x^{(i)}$ 距離最短的聚類中心點。計算距離時,一般使用 $| x^{(i)} - u_j |^2$ 來計算。
- 從 1 - K 遍歷所有的聚類中心,移動聚類中心的新位置到這個聚類的均值處。即 $u_j = \frac{1}{c} \left( \sum_{d=1}^c \right)$ ,其中 c 表示分配給這個聚類的訓練樣例點的個數。如果特殊情況下,沒有點分配給這個聚類中心,那么說明這個聚類中心就不應該存在,直接刪除掉這個聚類中心,最后聚類的個數變成 K - 1 個。
- 重復步驟 2 ,直到聚類中心不再移動為止。
K 均值算法成本函數
其中, $c^{(i)}$ 是訓練樣例 $x^{(i)}$ 分配的聚類序號;$u_{c^{(i)}}$ 是 $x^{(i)}$ 所屬的聚類的中心點。K 均值算法的成本函數的物理意義,就是訓練樣例到其所屬的聚類中心點的距離的平均值。
隨機初始化聚類中心點
假設 K 是聚類的個數,m 是訓練樣本的個數,那么必定有 $K < m$。在隨機初始化時,隨機從 m 個訓練數據集里選擇 K 個樣本來作為聚類中心點。這是正式推薦的隨機初始化聚類中心的做法。
在實際解決問題時,最終的聚類結果會和隨機初始化的聚類中心點有關。即不同的隨機初始化的聚類中心點可能得到不同的最終聚類結果。因為成本函數可能會收斂在一個局部最優解,而不是全局最優解上。一個解決方法是多做幾次隨機初始化的動作,然后訓練出不同的取類中心點以及聚類節點分配方案。然后用這些值算出成本函數,最終選擇那個成本最小的。
比如,假設我們做 100 次運算,步驟如下:
- 隨機選擇 K 個聚類中心點
- 運行 K 均值算法,算出 $c^{(1)}, c^{(2)}, ... , c^{(m)}$ 和 $u_1, u_2, ... , u_k$
- 使用 $c^{(1)}, c^{(2)}, ... , c^{(m)}$ 和 $u_1, u_2, ... , u_k$ 算出最終的成本值
- 記錄最小的成本值,然后跳回步驟 1,直到達到最大運算次數
這樣我們可以適當加大運算次數,從而求出全局最優解。
選擇聚類的個數
怎么樣選擇合適的聚類個數呢?實際上聚類個數和業務有緊密的關聯,比如我們要對 T-Shirt 大小進行聚類分析,我們是分成 3 個尺寸好呢還是分成 5 個尺寸好?這個更多的是個業務問題而非技術問題。3 個尺寸可以給生產和銷售帶來便利,但客戶體驗可能不好。5 個尺寸客戶體驗好了,但可能會給生產和庫存造成不便。

從技術角度來講,也是有一些方法可以來做一些判斷的。我們可以把聚類個數作為橫坐標,成本函數作為縱坐標,這樣把成本和聚類個數的數據畫出來。如上圖所示。大體的趨勢是隨著 K 值越來越大,成本越來越低。我們找出一個拐點,即在這個拐點之前成本下降比較快,在這個拐點之后,成本下降比較慢,那么很可能這個拐點所在的 K 值就是我們要尋求的最優解。
當然,這個技術方法并不總是有效,我們很可能會得到一個沒有拐點的曲線,這樣的話,就必須和業務邏輯結合以便選擇合適的聚類個數。