导入库,读取数据,查看数据类型等进行分析,可视化数据
import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
#读取数据
path = "./ex7data2.mat"
data = sio.loadmat(path)
# print(type(data))
# print(data.keys())
X = data.get("X")
# print(X.shape)
# print(X)
# print(type(X))
#可视化数据
plt.scatter(X[:,0],X[:,1])
plt.show()
簇分配
在该函数中,设置一个minis表示样本与各个聚类中心点的距离,所以最开始初始化为一个比较大的数值。第一个for循环为迭代每一个样本,第二个for循环迭代每一个聚类中心点,已便找到最近的聚类中心点。
def means_classification(X,centros):
m = len(X)
n = len(centros)
idx = np.zeros(m)
for i in range(m):
minis = 100000
for j in range(n):
s = np.sum(np.power((X[i,:]-centros[j,:]),2))
if s < minis:
minis = s
idx[i] = j
return idx
计算聚类中心
使用平均值计算聚类中心
def means_center(X,K,idx):
centors = []
for i in range(K):
indicates = np.where(idx == i)
centors_i = np.mean(X[indicates],axis=0)
centors.append(centors_i)
return centors
初始化聚类中心
随机生成三个整数(样本范围内),然后当作下标索引,找到三个样本的点作为初始化的聚类中心。
def init_centros(X,K):
m = len(X)
random_int = []
for i in range(K):
random_int_i = np.random.randint(0, m)
random_int.append(random_int_i)
random_centros = []
for k in random_int:
random_centros.append(X[k])
return np.array(random_centros)
手动定义聚类数量为3
K = 3
多次迭代,运行Kmeans算法
def run_Kmeans(X,K,times):
for i in range(times):
centros = init_centros(X, K)
idx = means_classification(X, centros)
centros = means_center(X, K, idx)
return idx,centros
绘制出聚类算法后的散点图
def plot_kmeans(X,idx):
cluster1 = X[np.where(idx == 0)[0], :]
cluster2 = X[np.where(idx == 1)[0], :]
cluster3 = X[np.where(idx == 2)[0], :]
fig,ax = plt.subplots()
ax.scatter(cluster1[:, 0], cluster1[:, 1], c="r", label="cluster1")
ax.scatter(cluster2[:, 0], cluster2[:, 1], c="g", label="cluster2")
ax.scatter(cluster3[:, 0], cluster3[:, 1], c="b", label="cluster3")
plt.show()
idx,centros = run_Kmeans(X,K,100)
plot_kmeans(X,idx)
注意这里有个问题,随机初始化时,最后好几次是得到了局部最优,该题目可以先手动初始化聚类中心。
centros = np.array([[3,3],[6,2],[8,5]])