机器学习作业---K-Means算法
生活随笔
收集整理的這篇文章主要介紹了
机器学习作业---K-Means算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
--------------------------K-Means算法使用--------------------------
一:數據導入及可視化
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[:,],X[:,],c='b',marker="o")
plt.show()
注意:對于我們的無監督學習中,訓練集中是沒有標簽值的,所以只有X,沒有y
二:歸類---尋找每個訓練樣本的聚類中心
(一)代碼實現
def find_closest_centroids(X,centroids):
m = X.shape[0]
idx = np.zeros(m) #記錄每個訓練樣本距離最短聚類中心最短的索引
idx = idx.astype(int) #因為numpy中沒有int、float類型,是由系統決定是32、或者64位大小。所以我們這里手動設置位int類型,為后面做準備 for i in range(m):
idx[i] = np.argmin(np.sum(np.power((centroids-X[i]),2),1)) #先計算各個中心到該點的平方和距離,返回最小的索引 return idx
(二)補充矩陣減去向量、np.sum的使用
(三)結果測試
k = # 設置聚簇中心個數為3
initial_centroids = np.array([[, ], [, ], [, ]]) #手動初始化三個聚類中心點
idx = find_closest_centroids(X,initial_centroids)
print(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
(二)回顧np.where操作
注意:我們這里np.where返回的是一個元組類型,我們如果想要獲取內部數據,應該使用np.where(idx == 5)[0]可以獲取np.array類型數據
(三)結果測試
data = sio.loadmat("ex7data2.mat")
X = data['X']
k = # 設置聚簇中心個數為3
initial_centroids = np.array([[, ], [, ], [, ]]) #手動初始化三個聚類中心點
idx = find_closest_centroids(X,initial_centroids)
c_n = compute_centroids(X,idx,k)
print(c_n)
四:實現K-mean算法
(一)代碼實現
def run_k_means(X,init_centroids,max_iters=):
m,n = X.shape
idx = np.zeros(m)
k = init_centroids.shape[]
centroids = init_centroids #開始迭代
if max_iters != :
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
initial_centroids = np.array([[, ], [, ], [, ]]) #手動初始化三個聚類中心點
max_iters =
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[:,],cluster_1[:,],c='r',marker="o")
plt.scatter(cluster_2[:,],cluster_2[:,],c='b',marker="o")
plt.scatter(cluster_3[:,],cluster_3[:,],c='g',marker="o")
plt.show()
(三)改進版---繪制聚簇中心移動軌跡
def run_k_means(X,init_centroids,max_iters=):
m,n = X.shape
idx = np.zeros(m)
k = init_centroids.shape[]
centroids = init_centroids
cent_rec = init_centroids #記錄中心移動信息 #開始迭代
if max_iters != :
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=) #記錄中心移動信息,按列添加
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=) #記錄中心移動信息,按列添加 return idx,centroids,cent_rec
data = sio.loadmat("ex7data2.mat")
X = data['X']
k = # 設置聚簇中心個數為3
initial_centroids = np.array([[, ], [, ], [, ]]) #手動初始化三個聚類中心點
max_iters =
idx, centroids, cent_rec = run_k_means(X,initial_centroids,max_iters)
#獲取各個聚簇信息
cluster_1 = X[np.where(idx==)[],:]
cent_1 = cent_rec[].reshape(-,)
cluster_2 = X[np.where(idx==)[],:]
cent_2 = cent_rec[].reshape(-,)
cluster_3 = X[np.where(idx==)[],:]
cent_3 = cent_rec[].reshape(-,)
#繪制圖像
plt.figure()
plt.scatter(cluster_1[:,],cluster_1[:,],c='r',marker="o")
plt.plot(np.array(cent_1[:,]),np.array(cent_1[:,]),c='black',marker="X")
plt.scatter(cluster_2[:,],cluster_2[:,],c='b',marker="o")
plt.plot(np.array(cent_2[:,]),np.array(cent_2[:,]),c='black',marker="X")
plt.scatter(cluster_3[:,],cluster_3[:,],c='g',marker="o")
plt.plot(np.array(cent_3[:,]),np.array(cent_3[:,]),c='black',marker="X")
plt.show()
五:隨機初始化聚類中心函數
在運行 K-均值算法的之前,我們首先要隨機初始化所有的聚類中心點。
(一)重點回顧
注意點一:
(1)應該把聚類中心的數值K設置為比訓練樣本數量m小的值;
(2)隨機挑選K個訓練樣本;
(3)設定μ1,...,μk,讓它們等于這K個樣本。
注意點二:
避免局部最優:如果想讓找到最優可能的聚類,可以嘗試多次隨機初始化,以此來保證能夠得到一個足夠好的結果,選取代價最小的一個也就是代價函數J最小的。事實證明,在聚類數K較小的情況下(2~10個),使用多次隨機初始化會有較大的影響,而如果K很大的情況,多次隨機初始化可能并不會有太大效果。
(二)代碼實現
def kmeans_init_centroids(X,k): #隨機獲取聚類中心
centroids = np.zeros((k,X.shape[])) #隨機選取訓練樣本個數
idx = np.random.choice(X.shape[],k)
centroids = X[idx,:] return centroids def comp_J(X,centroids,idx): #計算代價,計算平方和,不進行開方
# 獲取各個聚簇信息
cluster_1 = X[np.where(idx == )[], :]
cluster_2 = X[np.where(idx == )[], :]
cluster_3 = X[np.where(idx == )[], :] #計算代價
J_1 = np.sum(np.power(cluster_1-centroids[],))
J_2 = np.sum(np.power(cluster_2-centroids[],))
J_3 = np.sum(np.power(cluster_3-centroids[],)) return J_1+J_2+J_3 def kmeans_run(X,k,rand_iter,max_iters=): #進行多次計算代價,然后選取最小的
min_J = -
idx_res = np.zeros(X.shape[])
centroids_res = np.zeros((k,X.shape[]))
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 < :
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
rand_iter =
max_iters =
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==)[],:]
cent_1 = cent_rec[].reshape(-,)
cluster_2 = X[np.where(idx==)[],:]
cent_2 = cent_rec[].reshape(-,)
cluster_3 = X[np.where(idx==)[],:]
cent_3 = cent_rec[].reshape(-,)
#繪制圖像
plt.figure()
plt.scatter(cluster_1[:,],cluster_1[:,],c='r',marker="o")
plt.plot(np.array(cent_1[:,]),np.array(cent_1[:,]),c='black',marker="X")
plt.scatter(cluster_2[:,],cluster_2[:,],c='b',marker="o")
plt.plot(np.array(cent_2[:,]),np.array(cent_2[:,]),c='black',marker="X")
plt.scatter(cluster_3[:,],cluster_3[:,],c='g',marker="o")
plt.plot(np.array(cent_3[:,]),np.array(cent_3[:,]),c='black',marker="X")
plt.show()
補充:我們可以認為每個點的特征就是x_1,x_2,而我們的聚類中心就是由x_1和x_2組成的。
--------------------------K-Means算法進行圖像壓縮--------------------------
使用K-Means進行圖像壓縮。我們使用聚類來找到最具代表性的少數顏色,并使用聚類分配講原始的24位顏色,映射到較低維的顏色空間
一:數據讀取
image_data = sio.loadmat("bird_small.mat")
data = image_data['A']
print(data)
print(data.shape)
二:數據預處理
#數據歸一化 因為每個數據都是0-255之間
data = data /
data = np.reshape(data,(data.shape[]*data.shape[],data.shape[]))
print(data.shape)
注意:我們的特征就是顏色空間三通道,所以我們后面求取的聚類中心就是我們找到的最具代表的顏色空間
三:獲取我們的聚類中心(同之前)
(一)代碼實現
def find_closest_centroids(X,centroids):
m = X.shape[]
idx = np.zeros(m) #記錄每個訓練樣本距離最短聚類中心最短的索引
idx = idx.astype(int) #因為numpy中沒有int、float類型,是由系統決定是32、或者64位大小。所以我們這里手動設置位int類型,為后面做準備 for i in range(m):
idx[i] = np.argmin(np.sum(np.power((centroids-X[i]),),)) #先計算各個中心到該點的平方和距離,返回最小的索引 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)[]],) #按列求均值 return centroids_new def run_k_means(X,init_centroids,max_iters=):
m,n = X.shape
idx = np.zeros(m)
k = init_centroids.shape[]
centroids = init_centroids #開始迭代
if max_iters != :
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[])) #隨機選取訓練樣本個數
idx = np.random.choice(X.shape[],k)
centroids = X[idx,:] return centroids
(二)獲取壓縮結果
image_data = sio.loadmat("bird_small.mat")
data = image_data['A']
#數據歸一化 因為每個數據都是0-255之間
data = data /
X = np.reshape(data,(data.shape[]*data.shape[],data.shape[]))
k =
max_iters =
#隨機初始化聚類中心
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) #(, )
X_recovered = np.reshape(X_recovered,(data.shape[],data.shape[],data.shape[])) #再展開為三維數據
補充:使用索引擴展矩陣
(三)壓縮結果顯示
plt.figure()
plt.imshow(data) #顯示原始圖像
plt.show() plt.figure()
plt.imshow(X_recovered) #顯示壓縮后的圖像
plt.show()
當k=6時:
四:補充使用sklearn庫進行K-means算法使用
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 /
X = np.reshape(data,(data.shape[]*data.shape[],data.shape[])) 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[],data.shape[],data.shape[])) #獲取新的圖像 plt.figure()
plt.imshow(data) #顯示原始圖像
plt.show() plt.figure()
plt.imshow(X_recovered) #顯示壓縮后的圖像
plt.show()
參數講解:https://blog.csdn.net/sinat_26917383/article/details/70240628
總結
以上是生活随笔為你收集整理的机器学习作业---K-Means算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: requests保持登录session
- 下一篇: .NET6: 开发基于WPF的摩登三维工