目录
算法步骤:
1、首先确定一个k值,即我们希望将数据集经过聚类得到k个集合。
2、从数据集中随机选择k个数据点作为质心。
3、对数据集中每一个点,计算其与每一个质心的距离(如欧式距离),离哪个质心近,就划分到那个质心所属的集合。
4、把所有数据归好集合后,一共有k个集合。然后重新计算每个集合的质心。
5、如果新计算出来的质心和原来的质心之间的距离小于某一个设置的阈值(表示重新计算的质心的位置变化不大,趋于稳定,或者说收敛),我们可以认为聚类已经达到期望的结果,算法终止。
6、如果新质心和原质心距离变化很大,需要迭代3~5步骤。
算法步骤图解:
代码实现
class KMeans:
def __init__(self,data,num_clustres):
self.data = data
self.num_clustres = num_clustres
#通过指定迭代次数终止训练
def train(self,max_iterations):
#1.先随机选择K个中心点
centroids = KMeans.centroids_init(self.data,self.num_clustres)
#2.开始训练
num_examples = self.data.shape[0]
closest_centroids_ids = np.empty((num_examples,1)) #存放每个数据点对应的类别
for _ in range(max_iterations):
#3得到当前每一个样本点到K个中心点的距离,找到最近的
closest_centroids_ids = KMeans.centroids_find_closest(self.data,centroids)
#4.进行中心点位置更新
centroids = KMeans.centroids_compute(self.data,closest_centroids_ids,self.num_clustres)
return centroids,closest_centroids_ids
@staticmethod
#随机产生num_clustres个质心
def centroids_init(data,num_clustres):
num_examples = data.shape[0]
random_ids = np.random.permutation(num_examples)
centroids = data[random_ids[:num_clustres],:] #随机选取数据集中前num_clustres个数据作为质心,质心为(num_clustres, num_feature)
return centroids
@staticmethod
#寻找距离数据点最近的质心
def centroids_find_closest(data,centroids):
num_examples = data.shape[0]
num_centroids = centroids.shape[0]
closest_centroids_ids = np.zeros((num_examples,1)) #存放每个数据点对应的距离最近的质心类别
for example_index in range(num_examples):
distance = np.zeros((num_centroids,1)) #存放每个数据点与每个质心的欧氏距离
for centroid_index in range(num_centroids):
distance_diff = data[example_index,:] - centroids[centroid_index,:]
distance[centroid_index] = np.sum(distance_diff**2)
closest_centroids_ids[example_index] = np.argmin(distance)
return closest_centroids_ids
@staticmethod
#重新计算簇的质心
def centroids_compute(data,closest_centroids_ids,num_clustres):
num_features = data.shape[1]
centroids = np.zeros((num_clustres,num_features)) #存放每个簇中,每个特征的均值
for centroid_id in range(num_clustres):
closest_ids = closest_centroids_ids == centroid_id
centroids[centroid_id] = np.mean(data[closest_ids.flatten(),:],axis=0)
return centroids
评估标准
K值选取方法
肘部法:计算不同K值(一般取K=2到9)情况下,损失值inertia_的大小,找到突变最快的K值,一般即为最优值。