我們打算從零構(gòu)建我們自己的 KMeans 算法空执。之前提到過 KMeans 算法的步驟浪箭。
- 選擇 K 值。
- 隨機選取 K 個特征作為形心辨绊。
- 計算所有其它特征到形心的距離奶栖。
- 將其它特征分類到最近的形心。
- 計算每個分類的均值(分類中所有特征的均值)门坷,使均值為新的形心宣鄙。
- 重復(fù)步驟 3 ~ 5,直到最優(yōu)(形心不再變化)默蚌。
最開始冻晤,我們:
import matplotlib.pyplot as plt
from matplotlib import style
style.use('ggplot')
import numpy as np
X = np.array([[1, 2],
[1.5, 1.8],
[5, 8 ],
[8, 8],
[1, 0.6],
[9,11]])
plt.scatter(X[:,0], X[:,1], s=150)
plt.show()
我們的簇應(yīng)該很顯然了。我們打算選取K=2
绸吸。我們開始構(gòu)建我們的 KMeans 分類:
class K_Means:
def __init__(self, k=2, tol=0.001, max_iter=300):
self.k = k
self.tol = tol
self.max_iter = max_iter
我們剛剛配置了一些起始值鼻弧,k
就是簇的數(shù)量设江,tol
就是容差,如果簇的形心移動沒有超過這個值攘轩,就是最優(yōu)的叉存。max_iter
值用于限制循環(huán)次數(shù)。
現(xiàn)在我們開始處理fit
方法:
def fit(self,data):
self.centroids = {}
for i in range(self.k):
self.centroids[i] = data[i]
最開始度帮,我們知道我們僅僅需要傳入擬合數(shù)據(jù)歼捏。之后我們以空字典開始,它之后會存放我們的形心笨篷。下面瞳秽,我們開始循環(huán),僅僅將我們的起始形心賦為數(shù)據(jù)中的前兩個樣例率翅。如果你打算真正隨機選取形心寂诱,你應(yīng)該首先打亂數(shù)據(jù),但是這樣也不錯安聘。
繼續(xù)構(gòu)建我們的類:
class K_Means:
def __init__(self, k=2, tol=0.001, max_iter=300):
self.k = k
self.tol = tol
self.max_iter = max_iter
def fit(self,data):
self.centroids = {}
for i in range(self.k):
self.centroids[i] = data[i]
for i in range(self.max_iter):
self.classifications = {}
for i in range(self.k):
self.classifications[i] = []
現(xiàn)在我們開始迭代我們的max_iter
值痰洒。這里,我們以空分類開始浴韭,之后創(chuàng)建兩個字典的鍵(通過遍歷self.k
的范圍)丘喻。
下面,我們需要遍歷我們的特征念颈,計算當前形心個特征的距離泉粉,之后分類他們:
class K_Means:
def __init__(self, k=2, tol=0.001, max_iter=300):
self.k = k
self.tol = tol
self.max_iter = max_iter
def fit(self,data):
self.centroids = {}
for i in range(self.k):
self.centroids[i] = data[i]
for i in range(self.max_iter):
self.classifications = {}
for i in range(self.k):
self.classifications[i] = []
for featureset in data:
distances = [np.linalg.norm(featureset-self.centroids[centroid]) for centroid in self.centroids]
classification = distances.index(min(distances))
self.classifications[classification].append(featureset)
下面,我們需要創(chuàng)建新的形心榴芳,并且度量形心的移動嗡靡。如果移動小于我們的容差(sel.tol
),我們就完成了窟感。包括添加的代碼讨彼,目前為止的代碼為:
import matplotlib.pyplot as plt
from matplotlib import style
style.use('ggplot')
import numpy as np
X = np.array([[1, 2],
[1.5, 1.8],
[5, 8 ],
[8, 8],
[1, 0.6],
[9,11]])
plt.scatter(X[:,0], X[:,1], s=150)
plt.show()
colors = 10*["g","r","c","b","k"]
class K_Means:
def __init__(self, k=2, tol=0.001, max_iter=300):
self.k = k
self.tol = tol
self.max_iter = max_iter
def fit(self,data):
self.centroids = {}
for i in range(self.k):
self.centroids[i] = data[i]
for i in range(self.max_iter):
self.classifications = {}
for i in range(self.k):
self.classifications[i] = []
for featureset in data:
distances = [np.linalg.norm(featureset-self.centroids[centroid]) for centroid in self.centroids]
classification = distances.index(min(distances))
self.classifications[classification].append(featureset)
prev_centroids = dict(self.centroids)
for classification in self.classifications:
self.centroids[classification] = np.average(self.classifications[classification],axis=0)