import numpy as np import matplotlib.pyplot as plt import scipy.io as sio data = sio.loadmat("ex7data2.mat") X = data['X'] print(X.shape) plt.figure() plt.scatter(X[:,0],X[:,1],c='b',marker="o") plt.show()
def find_closest_centroids(X,centroids):
m = X.shape[0]
idx = np.zeros(m) #记录每一个训练样本距离最短聚类中心最短的索引
idx = idx.astype(int) #由于numpy中没有int、float类型,是由系统决定是3二、或者64位大小。因此咱们这里手动设置位int类型,为后面作准备
for i in range(m):
idx[i] = np.argmin(np.sum(np.power((centroids-X[i]),2),1)) #先计算各个中心到该点的平方和距离,返回最小的索引
return idx
k = 3 # 设置聚簇中心个数为3 initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #手动初始化三个聚类中心点 idx = find_closest_centroids(X,initial_centroids) print(idx[0:3])
def compute_centroids(X,idx,K):
(m,n)=X.shape
centroids_new = np.zeros((k,n))
#进行更新操做,用每一个聚类中心全部点的位置平均值做为新的聚类中心位置
for i in range(K):
centroids_new[i] = np.mean(X[np.where(idx==i)[0],0) #按列求均值
return centroids_new
data = sio.loadmat("ex7data2.mat") X = data['X'] k = 3 # 设置聚簇中心个数为3 initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #手动初始化三个聚类中心点 idx = find_closest_centroids(X,initial_centroids) c_n = compute_centroids(X,idx,k) print(c_n)
def run_k_means(X,init_centroids,max_iters=0): m,n = X.shape idx = np.zeros(m) k = init_centroids.shape[0] centroids = init_centroids #开始迭代 if max_iters != 0: for i in range(max_iters): #按迭代次数进行迭代 idx = find_closest_centroids(X,centroids) centroids = compute_centroids(X,idx,k) else: while True: #直到连续两次的迭代结果都是同样的,就返回 idx = find_closest_centroids(X, init_centroids) centroids = compute_centroids(X,idx,k) if (init_centroids == centroids).all(): break init_centroids = centroids return idx,centroids
data = sio.loadmat("ex7data2.mat") X = data['X'] k = 3 # 设置聚簇中心个数为3 initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #手动初始化三个聚类中心点 max_iters = 10 idx, centroids = run_k_means(X,initial_centroids,max_iters) #获取各个聚簇信息 cluster_1 = X[np.where(idx==0)[0],:] cluster_2 = X[np.where(idx==1)[0],:] cluster_3 = X[np.where(idx==2)[0],:] #绘制图像 plt.figure() plt.scatter(cluster_1[:,0],cluster_1[:,1],c='r',marker="o") plt.scatter(cluster_2[:,0],cluster_2[:,1],c='b',marker="o") plt.scatter(cluster_3[:,0],cluster_3[:,1],c='g',marker="o") plt.show()
def run_k_means(X,init_centroids,max_iters=0): m,n = X.shape idx = np.zeros(m) k = init_centroids.shape[0] centroids = init_centroids cent_rec = init_centroids #记录中心移动信息 #开始迭代 if max_iters != 0: for i in range(max_iters): #按迭代次数进行迭代 idx = find_closest_centroids(X,centroids) centroids = compute_centroids(X,idx,k) cent_rec = np.append(cent_rec,centroids,axis=1) #记录中心移动信息,按列添加 else: while True: #直到连续两次的迭代结果都是同样的,就返回 idx = find_closest_centroids(X, init_centroids) centroids = compute_centroids(X,idx,k) if (init_centroids == centroids).all(): break init_centroids = centroids cent_rec = np.append(cent_rec,centroids,axis=1) #记录中心移动信息,按列添加 return idx,centroids,cent_rec
data = sio.loadmat("ex7data2.mat") X = data['X'] k = 3 # 设置聚簇中心个数为3 initial_centroids = np.array([[3, 3], [6, 2], [8, 5]]) #手动初始化三个聚类中心点 max_iters = 10 idx, centroids, cent_rec = run_k_means(X,initial_centroids,max_iters) #获取各个聚簇信息 cluster_1 = X[np.where(idx==0)[0],:] cent_1 = cent_rec[0].reshape(-1,2) cluster_2 = X[np.where(idx==1)[0],:] cent_2 = cent_rec[1].reshape(-1,2) cluster_3 = X[np.where(idx==2)[0],:] cent_3 = cent_rec[2].reshape(-1,2) #绘制图像 plt.figure() plt.scatter(cluster_1[:,0],cluster_1[:,1],c='r',marker="o") plt.plot(np.array(cent_1[:,0]),np.array(cent_1[:,1]),c='black',marker="X") plt.scatter(cluster_2[:,0],cluster_2[:,1],c='b',marker="o") plt.plot(np.array(cent_2[:,0]),np.array(cent_2[:,1]),c='black',marker="X") plt.scatter(cluster_3[:,0],cluster_3[:,1],c='g',marker="o") plt.plot(np.array(cent_3[:,0]),np.array(cent_3[:,1]),c='black',marker="X") plt.show()
在运行 K-均值算法的以前,咱们首先要随机初始化全部的聚类中心点。算法
(1)应该把聚类中心的数值K设置为比训练样本数量m小的值;app
(2)随机挑选K个训练样本;dom
(3)设定μ1,...,μk,让它们等于这K个样本。函数
def kmeans_init_centroids(X,k): #随机获取聚类中心 centroids = np.zeros((k,X.shape[1])) #随机选取训练样本个数 idx = np.random.choice(X.shape[0],k) centroids = X[idx,:] return centroids def comp_J(X,centroids,idx): #计算代价,计算平方和,不进行开方 # 获取各个聚簇信息 cluster_1 = X[np.where(idx == 0)[0], :] cluster_2 = X[np.where(idx == 1)[0], :] cluster_3 = X[np.where(idx == 2)[0], :] #计算代价 J_1 = np.sum(np.power(cluster_1-centroids[0],2)) J_2 = np.sum(np.power(cluster_2-centroids[1],2)) J_3 = np.sum(np.power(cluster_3-centroids[2],2)) return J_1+J_2+J_3 def kmeans_run(X,k,rand_iter,max_iters=0): #进行屡次计算代价,而后选取最小的 min_J = -1 idx_res = np.zeros(X.shape[0]) centroids_res = np.zeros((k,X.shape[1])) cent_rec_res = centroids_res for i in range(rand_iter): init_centroids = kmeans_init_centroids(X,k) idx, centroids, cent_rec = run_k_means(X,init_centroids,max_iters) #计算代价 if min_J < 0: min_J = comp_J(X,centroids,idx) else: new_J = comp_J(X,centroids,idx) # print(new_J) if new_J < min_J: idx_res, centroids_res, cent_rec_res = idx, centroids, cent_rec # print(min_J) return idx_res, centroids_res, cent_rec_res
data = sio.loadmat("ex7data2.mat") X = data['X'] k = 3 # 设置聚簇中心个数为3 rand_iter = 10 max_iters = 10 idx, centroids, cent_rec = kmeans_run(X,k,rand_iter,max_iters) idx, centroids, cent_rec = run_k_means(X,kmeans_init_centroids(X,k),max_iters) # print(comp_J(X,centroids,idx)) #266.65851965491936 #获取各个聚簇信息 cluster_1 = X[np.where(idx==0)[0],:] cent_1 = cent_rec[0].reshape(-1,2) cluster_2 = X[np.where(idx==1)[0],:] cent_2 = cent_rec[1].reshape(-1,2) cluster_3 = X[np.where(idx==2)[0],:] cent_3 = cent_rec[2].reshape(-1,2) #绘制图像 plt.figure() plt.scatter(cluster_1[:,0],cluster_1[:,1],c='r',marker="o") plt.plot(np.array(cent_1[:,0]),np.array(cent_1[:,1]),c='black',marker="X") plt.scatter(cluster_2[:,0],cluster_2[:,1],c='b',marker="o") plt.plot(np.array(cent_2[:,0]),np.array(cent_2[:,1]),c='black',marker="X") plt.scatter(cluster_3[:,0],cluster_3[:,1],c='g',marker="o") plt.plot(np.array(cent_3[:,0]),np.array(cent_3[:,1]),c='black',marker="X") plt.show()
使用K-Means进行图像压缩。咱们使用聚类来找到最具表明性的少数颜色,并使用聚类分配讲原始的24位颜色,映射到较低维的颜色空间学习
image_data = sio.loadmat("bird_small.mat")
data = image_data['A']
print(data)
print(data.shape)
#数据归一化 由于每一个数据都是0-255之间 data = data / 255 data = np.reshape(data,(data.shape[0]*data.shape[1],data.shape[2]))
print(data.shape)
def find_closest_centroids(X,centroids): m = X.shape[0] idx = np.zeros(m) #记录每一个训练样本距离最短聚类中心最短的索引 idx = idx.astype(int) #由于numpy中没有int、float类型,是由系统决定是3二、或者64位大小。因此咱们这里手动设置位int类型,为后面作准备 for i in range(m): idx[i] = np.argmin(np.sum(np.power((centroids-X[i]),2),1)) #先计算各个中心到该点的平方和距离,返回最小的索引 return idx def compute_centroids(X,idx,K): (m,n)=X.shape centroids_new = np.zeros((k,n)) #进行更新操做,用每一个聚类中心全部点的位置平均值做为新的聚类中心位置 for i in range(K): centroids_new[i] = np.mean(X[np.where(idx==i)[0]],0) #按列求均值 return centroids_new def run_k_means(X,init_centroids,max_iters=0): m,n = X.shape idx = np.zeros(m) k = init_centroids.shape[0] centroids = init_centroids #开始迭代 if max_iters != 0: for i in range(max_iters): #按迭代次数进行迭代 idx = find_closest_centroids(X,centroids) centroids = compute_centroids(X,idx,k) else: while True: #直到连续两次的迭代结果都是同样的,就返回 idx = find_closest_centroids(X, init_centroids) centroids = compute_centroids(X,idx,k) if (init_centroids == centroids).all(): break init_centroids = centroids return idx,centroids def kmeans_init_centroids(X,k): centroids = np.zeros((k,X.shape[1])) #随机选取训练样本个数 idx = np.random.choice(X.shape[0],k) centroids = X[idx,:] return centroids
image_data = sio.loadmat("bird_small.mat") data = image_data['A'] #数据归一化 由于每一个数据都是0-255之间 data = data / 255 X = np.reshape(data,(data.shape[0]*data.shape[1],data.shape[2])) k = 16 max_iters = 10 #随机初始化聚类中心 init_centroids = kmeans_init_centroids(X,k) #获取聚类中心 idx,centroids = run_k_means(X,init_centroids,max_iters) #将全部数据点,设置归属到对应的聚类中心去 idx = find_closest_centroids(X,centroids) #将每个像素值与聚类结果进行匹配 X_recovered = centroids[idx,:] #将属于一个聚类的像素,设置为聚类中心的值(统一) print(X_recovered.shape) #(16384, 3) X_recovered = np.reshape(X_recovered,(data.shape[0],data.shape[1],data.shape[2])) #再展开为三维数据
plt.figure()
plt.imshow(data) #显示原始图像
plt.show()
plt.figure()
plt.imshow(X_recovered) #显示压缩后的图像
plt.show()
当k=6时:测试
import numpy as np import matplotlib.pyplot as plt import scipy.io as sio from sklearn.cluster import KMeans image_data = sio.loadmat("bird_small.mat") data = image_data['A'] #数据归一化 由于每一个数据都是0-255之间 data = data / 255 X = np.reshape(data,(data.shape[0]*data.shape[1],data.shape[2])) model = KMeans(n_clusters=16,n_init=100,n_jobs=-1) #n_init设置获取初始簇中心的更迭次数,防止局部最优 n_jobs设置并行(使用CPU数,-1则使用全部CPU) model.fit(X) #开始聚类 centroids = model.cluster_centers_ #获取聚簇中心 C = model.predict(X) #获取每一个数据点的对应聚簇中心的索引 X_recovered = centroids[C].reshape((data.shape[0],data.shape[1],data.shape[2])) #获取新的图像 plt.figure() plt.imshow(data) #显示原始图像 plt.show() plt.figure() plt.imshow(X_recovered) #显示压缩后的图像 plt.show()