携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
借助于K-means算法概念,MacQueen引入了一个不同的算法。
-
选择前k个元素作为聚类中心。
-
将每个新元素添加到方差增加最小的簇,并更新簇中心。
尽管此算法原始、不确定并且不可预料,但也可以迭代此算法以获得较好的结果。
其它算法:
K-Median
在k中值算法中,曼哈顿距离用于分类步骤而不是欧几里德距离。 在更新步骤中,使用中值(中位数)而不是平均值。
该算法本质与Python实现过程与K-Means没有本质区别。这里不再做具体介绍,然而关于曼哈顿距离我们似乎从未介绍过,实际上并非如此,曼哈顿距离和我们前面所说的矢量的范数一有着紧密的关联。曼
假设点a坐标为:(0,0),b的坐标为(6,6),则这两个点的曼哈顿距离为12,那么两点间可能的轨迹如下图所示:、
其中,红线,蓝线和黄线是曼哈顿轨迹,绿线为欧式轨迹。
K-Means++
k-Means ++算法不会随机选择簇中心点,而是根据以下规则:
-
随机选择一个数据作为第一个簇中心点。
-
计算每个数据到最近的簇中心点的距离D(x)。
-
随机选择一个对象作为最近的簇中心。
-
重复步骤2和3,直到确定k个簇中心点。
-
现在执行通常的k-means算法
K-Means++算法的Python实现:
import numpy as np
import pandas as pd
def lunpan_select(fr12,t):
for k in range(fr12.shape[1]):
if t<fr12.loc[1,0] and t>=0:
return np.array(fr12.loc[0,0])
elif t<fr12.loc[1,k+1] and t>=fr12.loc[1,k]:
return np.array(fr12.loc[0,k+1])
def K_center_selection(k,data):
cluster_centerp=[]
pro_collect=[]
dist_collection=[]
index=np.random.randint(data.shape[0])
cluster_centerp.append(data[index])
for j in range(1,k):
for point in data:
dist_list=[np.dot(point-center,point-center)for center in cluster_centerp]
dist_collection.append((min(dist_list),point))
#print(dist_collection)
for d_x in dist_collection:
pro_collect.append((d_x[0]/sum([dist[0] for dist in dist_collection]),d_x[1]))
new_pro_collect=pd.DataFrame([[dp[1] for dp in pro_collect],np.cumsum([wt[0] for wt in pro_collect]).tolist()]) \
.sort_values(by=1,axis=1)
randomnr=np.random.rand()
cluster_centerp.append(lunpan_select(new_pro_collect,randomnr))
return np.array(cluster_centerp)
from scipy import linalg
import numpy as np
from sklearn.datasets import make_blobs
def K_meanspp(X,k):#X必须是浮点矩阵
var_generator=locals()
X=X.astype(np.float64)
#sample_selection=np.random.randint(0,X.shape[0],k)
#center_point=X[sample_selection.tolist()]
center_point= K_center_selection(k,X)
#print(center_point)
center_point_temp=np.zeros_like(center_point).astype(np.float64)
while ~((center_point_temp==center_point).all()):#设置外层循环终止条件
for i in range(k):
var_generator['c'+str(i)]=[]#创建动态变量并赋值[]
for sample_point in X:#对所有点进行分类
distance_vector=linalg.norm(center_point-sample_point,axis=1)
min_distance=min(distance_vector)
cluster_marker=np.where(distance_vector==min_distance)[0][0]
var_generator['c'+str(cluster_marker)].append(sample_point)
center_point_temp=center_point.copy()
#print(center_point_temp)
for cluster_nr in range(k):#分类完毕后,求各分类的中心点
if len(var_generator['c'+str(cluster_nr)])!=0:
center_point[cluster_nr]=(sum(var_generator['c'+str(cluster_nr)])
/len(var_generator['c'+str(cluster_nr)]))
else:
continue
#print(center_point)
classification_data={m:var_generator['c'+str(m)] for m in range(k)}
return center_point,classification_data
ar1=np.array([[3,4,3,4,0,1,0,1],[4,4,3,3,2,2,1,1]])
K_center_selection(2,ar1.T)
array([[3, 3],
[4, 4]])
data_3=K_means(ar1.T,2)
import matplotlib.pyplot as plt
pic,axes_1=plt.subplots(1,1,figsize=(8,6),dpi=140)
data_class0=np.array(data_3[1][0])
data_class1=np.array(data_3[1][1])
axes_1.scatter(data_class0[:,0],data_class0[:,1],color='r',marker='.')
axes_1.scatter(data_class1[:,0],data_class1[:,1],color='b',marker='*')
axes_1.scatter(data_3[0][0,0],data_3[0][0,1],color='r',marker='D')
axes_1.scatter(data_3[0][1,0],data_3[0][1,1],color='b',marker='3')
plt.show()