初識K-means算法

初識K-means算法

K-means屬於非監督機器學習算法,主要用於聚類分析。好比我們收集某新聞網站的新聞數據,可是在採集過程當中忘了收集新聞的新聞類別(假設一共採集了軍事、政治、文化、教育四大類),如今咱們須要對成千上萬的新聞文檔進行分類,這時候咱們可使用k=4的簇數(聚類數)對新聞數據施行Kmeans算法,並對每篇文檔進行標註。算法

可是咱們仍是要強調一點,K-means是無監督學習,雖然不須要標註好的數據,可是仍是須要你對數據有必定的瞭解,可以大概猜想出k值(簇的數目)的範圍。這樣Kmeans算法才能開始更準確合理的學習數據中的類規律,並做出較好的分類。(其實還有分類算法的,這裏我用分類吧,不太嚴謹哈。)數組

K-means原理
K-means,從字面看含有k和means兩部分。K-means算法會將樣本量N特徵數m的數據X (其中X是N*m的矩陣)分到K個簇中,每一個簇會有一個重心centroids。dom

聚類效果的目標是經過計算簇中各個點到重心的距離平方和Inetia儘量的小。Inetia計算公式以下機器學習

初識K-means算法

C是一個簇;u是簇C的重心;Xj是簇C中的任意點。ide

Inetia也有個問題,Inetia不是正規的度量方式;咱們僅僅知道Inetia越小越好,0是最優狀態。可是極端的狀況下,若是有n條數據,咱們將其分紅n類,Inetia會等於0。函數

K-means算法:
K-means算法比較出名的的易於理解的是LIoyd算法,包含三個步驟:學習

1 、從數據集X中隨機抽選k個樣本點測試

二、按照距離最近原則,將剩餘的點分派給k個簇。而上一步抽選的k個樣本點就是k個簇的重心centorid。優化

三、根據每一個簇全部的點求出新的重心centroid,並重復步驟2和步驟3。直到重心沒什麼顯著變化,聚類結束。網站

優化K-means算法
充足運行時間條件下,K-means總能最終收斂,可是每每是局部最優。

聚類的表現高度依賴於重心centroid的最初的選擇。因此K-means每每須要運行好幾回,這裏也就是max_iter參數的意義,一次隨機抽選centroid偏差較大,因此運行max_iter次,最終選擇表現最好的做爲最終聚類結果。

解決隨機抽選centroid重心,有一種「k-means++」初始化方法,scikit-learn已經實現(經過使用init=k-means參數)。這種初始化選擇重心centroid的方法,儘可能保證k個重心彼此之間的距離儘量的遠,這樣比隨機抽選centroid更好。

K-means中海油一個n_job參數,能夠加快模型學習速度。當n_job=-1時,電腦使用所有的處理器進行並行運算。可是並行運算雖然會提升運行速度,卻以消耗大量內存爲代價。

案例
這個例子是爲了說明k-means會產生不直觀和可能意想不到的簇的狀況。

在前三幅圖中,輸入數據不符合一些隱含假設,使得k-means產生了不須要的聚類。最後一個圖,雖然各個簇的樣本量分佈不均衡,可是從咱們直覺仍是能看出聚類的合理性。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

#畫圖,設置畫布尺寸
plt.figure(figsize=(12, 12))

#隨機生成1500個樣本點
n_samples = 1500
#保證下次隨機生成的數據與前一次生成的數據是相同的
random_state = 170

#給k-means算法生成測試數據的函數
X, y = make_blobs(n_samples=n_samples, random_state=random_state)

#咱們看看前10條數據
print(X[:10], y[:10])

make_blob生成n_samples*n_features特徵矩陣X和標籤y,X矩陣默認特徵數n_features=2。因此咱們如今獲取的特徵矩陣是1500行2列。而標籤y是一維數組。

如今咱們看看前10條數據。

[[ -5.19811282   0.64186932]
 [ -5.75229538   0.41862711]
 [-10.84489837  -7.55352273]
 [ -4.57098483  -0.80101741]
 [ -3.51916215   0.0393449 ]
 [  1.60391611   0.76388041]
 [ -9.75157357  -5.2030262 ]
 [-11.51023635  -4.16284321]
 [ -7.72675795  -5.86656563]
 [  2.67656739   3.29872756]] 

 [1 1 0 1 1 2 0 0 0 2]

``

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

#畫圖,設置畫布尺寸
plt.figure(figsize=(12, 12))

#隨機生成1500個點(二維點)
n_samples = 1500
#記錄狀態,能夠保證下次隨機生成的數據與前一次生成的數據是相同的
random_state = 170

#make_blob主要是給k-means算法生成測試數據的函數。這裏同時獲得特徵矩陣X和標籤label
X, label = make_blobs(n_samples=n_samples, random_state=random_state)

#我也不知道有幾類,隨便將k=2去試試吧。讓K-means學習X,並生成預測的標籤
label_pred = KMeans(n_clusters=2, random_state=random_state).fit_predict(X)
#將figure設置的畫布大小分紅幾個部分。參數‘221’表示2(row)x2(colu),即將畫布分紅2x2,兩行兩列的4塊區域。1表示我們繪製的第一幅圖
plt.subplot(221)

#X[:, 0]意思是抽取X中全部行第一列,咱們能夠理解爲座標系的x; X[:, 1]是X的第二列,咱們能夠理解爲座標系的y;再用scatter在二維座標系中繪製散點圖,顏色c使用label_pred標註。
plt.scatter(X[:, 0], X[:, 1], c=label_pred)
plt.title("k=2 cluster")

#k=3
label_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X)
plt.subplot(222)
plt.scatter(X[:, 0], X[:, 1], c=label_pred)
plt.title("k=3 cluster")

#生成不一樣類數據的,且各種的方差是存在差別的
X_varied, y_varied = make_blobs(n_samples=n_samples,cluster_std=[1.0, 2.5, 0.5],random_state=random_state)

label_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_varied)
plt.subplot(223)
plt.scatter(X_varied[:, 0], X_varied[:, 1], c=label_pred)
plt.title("k=3 Unequal Variance")

#生成不一樣類數據的,且各種樣本量不均衡#0類有500個點;1類有100點;2類僅有10個點;X_filtered = np.vstack((X[label == 0][:500], X[label == 1][:100], X[label == 2][:10]))label_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X_filtered)plt.subplot(224)plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=label_pred)plt.title("Unevenly Sized Blobs")plt.show()

相關文章
相關標籤/搜索