• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

机器学习练习7-K-means聚类和PCA主成分

武飞扬头像
YukinoPon
帮助1

本文基于Andrew_Ng的ML课程作业

1-K-means clustering used for simple two-dimensional datasets: K-means聚类用于简单二维数据集

导入库

  1.  
    import numpy as np
  2.  
    import matplotlib.pyplot as plt
  3.  
    from scipy.io import loadmat

函数:初始化聚类中心

  1.  
    def init_centroids(X,k): #初始化聚类中心
  2.  
    m,n=X.shape
  3.  
    centroids=np.zeros((k,n))
  4.  
    idx=np.random.randint(0,m,k) #np.random.randint(low,high=None,size=None):返回size规模在[low, high)范围内的随机整型数
  5.  
    for i in range(k):
  6.  
    centroids[i,:]=X[idx[i],:]
  7.  
    return centroids

函数:找到每个样本最接近的聚类中心(Cluster Assignment)

  1.  
    def find_closet_centroids(X,centroids): #找到每个样本最接近的聚类中心(Cluster Assignment)
  2.  
    m=X.shape[0]
  3.  
    k=centroids.shape[0]
  4.  
    idx=np.zeros(m)
  5.  
    for i in range(m):
  6.  
    min_distan=1000000 #最小距离先设置为一个极大值
  7.  
    for j in range(k):
  8.  
    distan_squ=np.sum((X[i,:]-centroids[j,:])**2) #第i个样本到第j个centroid距离的平方
  9.  
    if distan_squ < min_distan:
  10.  
    min_distan=distan_squ
  11.  
    idx[i]=j 1
  12.  
    return idx

函数:计算簇的聚类中心(分配给簇的所有样本的平均值)(Move Centroid)

  1.  
    def compute_centroids(X,idx,k): #计算簇的聚类中心(分配给簇的所有样本的平均值)(Move Centroid)
  2.  
    n=X.shape[1]
  3.  
    centroids=np.zeros((k,n))
  4.  
    for i in range(k):
  5.  
    indices=np.where(idx==i 1) #np.where(condition):条件成立时,where返回每个符合condition条件元素的坐标,以元组的形式
  6.  
    centroids[i,:]=(np.sum(X[indices,:],axis=1)/len(indices[0])) #np.sum(X,axis=1):X为[[[],[]]]时,axis=1表示每一列元素相加,列数不变 #len(list):行数;len(list[0]):列数
  7.  
    return centroids

函数:加入循环整合后的K-means算法

  1.  
    def K_means(X,initial_centroids,max_iters): #加入循环整合后的K-means算法
  2.  
    k=initial_centroids.shape[0]
  3.  
    centroids=initial_centroids
  4.  
    for i in range(max_iters):
  5.  
    idx=find_closet_centroids(X,centroids)
  6.  
    centroids=compute_centroids(X,idx,k)
  7.  
    return idx,centroids

函数:用三种不同颜色展示三种聚类

  1.  
    def plot_clusters(): #用三种不同颜色展示三种聚类
  2.  
    cluster1=X[np.where(idx==1)[0],:] #这里np.where()后要加[0]是因为返回的是多元素array,取第一个元素才是每个符合condition条件元素的坐标
  3.  
    cluster2=X[np.where(idx==2)[0],:]
  4.  
    cluster3=X[np.where(idx==3)[0],:]
  5.  
    fig,ax=plt.subplots(figsize=(12,8))
  6.  
    ax.scatter(cluster1[:,0],cluster1[:,1],s=30,color='r',label='Cluster 1')
  7.  
    ax.scatter(cluster2[:,0],cluster2[:,1],s=30,color='g',label='Cluster 1')
  8.  
    ax.scatter(cluster3[:,0],cluster3[:,1],s=30,color='b',label='Cluster 1')
  9.  
    ax.legend()
  10.  
    plt.show()

主函数:

  1.  
    #K-means clustering used for simple two-dimensional datasets: K-means聚类用于简单二维数据集
  2.  
     
  3.  
    data=loadmat('ex7data2.mat')
  4.  
    X=data['X'] #(300,2)
  5.  
    initial_centroids=init_centroids(X,3)
  6.  
    max_iters=10
  7.  
    idx,centroids=K_means(X,initial_centroids,max_iters)
  8.  
    plot_clusters()

用三种颜色展示三种聚类

学新通

2-K-means clustering used for image compressing: K-means聚类用于压缩图像

导入库

  1.  
    from IPython.display import display,Image
  2.  
    from scipy.io import loadmat
  3.  
    import numpy as np
  4.  
    import matplotlib.pyplot as plt

函数:初始化聚类中心

  1.  
    def init_centroids(X,k): #初始化聚类中心
  2.  
    m,n=X.shape
  3.  
    centroids=np.zeros((k,n))
  4.  
    idx=np.random.randint(0,m,k)
  5.  
    for i in range(k):
  6.  
    centroids[i,:]=X[idx[i],:]
  7.  
    return centroids

函数:找到每个样本最接近的聚类中心(Cluster Assignment)

  1.  
    def find_closet_centroids(X,centroids): #找到每个样本最接近的聚类中心(Cluster Assignment)
  2.  
    m=X.shape[0]
  3.  
    k=centroids.shape[0]
  4.  
    idx=np.zeros(m)
  5.  
    for i in range(m):
  6.  
    min_distan=1000000
  7.  
    for j in range(k):
  8.  
    distan_squ=np.sum((X[i,:]-centroids[j,:])**2)
  9.  
    if distan_squ < min_distan:
  10.  
    min_distan=distan_squ
  11.  
    idx[i]=j 1
  12.  
    return idx

函数:计算簇的聚类中心(分配给簇的所有样本的平均值)(Move Centroid)

  1.  
    def compute_centroids(X,idx,k): #计算簇的聚类中心(分配给簇的所有样本的平均值)(Move Centroid)
  2.  
    n=X.shape[1]
  3.  
    centroids=np.zeros((k,n))
  4.  
    for i in range(k):
  5.  
    indices=np.where(idx==i 1)
  6.  
    centroids[i,:]=(np.sum(X[indices,:],axis=1)/len(indices[0]))
  7.  
    return centroids

函数:加入循环整合后的K-means算法

  1.  
    def K_means(X,initial_centroids,max_iters): #加入循环整合后的K-means算法
  2.  
    k=initial_centroids.shape[0]
  3.  
    centroids=initial_centroids
  4.  
    for i in range(max_iters):
  5.  
    idx=find_closet_centroids(X,centroids)
  6.  
    centroids=compute_centroids(X,idx,k)
  7.  
    return idx,centroids

主函数:

  1.  
    #K-means clustering used for image compressing: K-means聚类用于压缩图像
  2.  
    #使用聚类找到最具代表性的16种少数颜色(16种选定颜色的RGB值),并使用聚类分配将原始的24位颜色映射到较低维的颜色空间
  3.  
    #在图像的直接24位颜色表示中,每个像素被表示为3个8位无符号整数(0~255),称为RGB编码
  4.  
    #原始图像的128×128像素位置中的每一个都需要24位(3x8),因此总大小为128×128×24=393216位;新的表示法需要以16种颜色的字典形式进行一些开销存储,每种颜色需要24位,但是图像本身只需要每个像素位置4位;因此最终使用的位数是16×24 128×128×4=65920位,相当于将原始图像压缩约6倍
  5.  
     
  6.  
    display(Image(filename='bird_small.png')) #IPython.display.display:显示图像(仅在Jupyter中可用) #IPython.display.Image:导入图像
  7.  
    image_data=loadmat('bird_small.mat')
  8.  
    A=image_data['A'] #A.shape=(128,128,3)表示数组有三个维度,可以理解为有128张纸,每张纸上有一个128*3的矩阵
  9.  
     
  10.  
    #Data Preprocessing
  11.  
    A=A/255 #normalize value ranges
  12.  
    X=np.reshape(A,((A.shape[0]*A.shape[1]),A.shape[2])) #将A reshape成两维
  13.  
     
  14.  
    initial_centroids=init_centroids(X,16)
  15.  
    max_iters=10
  16.  
    idx,centroids=K_means(X,initial_centroids,max_iters) #idx.shape=(16384,);centroids.shape=(16,3)
  17.  
    idx=find_closet_centroids(X,centroids) #上一次循环后有新的聚类中心但未对每个样本点进行附属,这一步就是新附属
  18.  
    X_recovered=np.zeros(X.shape)
  19.  
    for i in range(16):
  20.  
    X_recovered[idx==i]=centroids[i]
  21.  
    X_recovered=X_recovered.reshape(128,128,3)
  22.  
    plt.imshow(X_recovered) #plt.imshow(X):热图(heatmap)通过色差、亮度来展示数据的差异;X:(M,N,3):具有RGB值的图像(RGB值应该在浮点数[0,...,1]或整数[0,...,255])
  23.  
    plt.show()
学新通

原图

学新通

压缩后图

学新通

3-K-means clustering in scikit-learn used for image compressing:K-means聚类用于压缩图像(用scikit-learn中的K-Means模型)

导入库

  1.  
    import numpy as np
  2.  
    import matplotlib.pyplot as plt
  3.  
    from skimage import io
  4.  
    from sklearn.cluster import KMeans

主函数:

  1.  
    #K-means clustering in scikit-learn used for image compressing:K-means聚类用于压缩图像(用scikit-learn中的K-Means模型)
  2.  
     
  3.  
    pic=io.imread('bird_small.png')/255 #(128,128,3) #skimage.io.imread(fname):图像读取,fname为文件名,这里图像读取进来就是RGB格式
  4.  
    io.imshow(pic) #skimage.io.imshow(arr):图片显示1,arr为要显示的图像数组
  5.  
    io.show() ##skimage.io.show():图片显示2,相当于plt.show()
  6.  
    data=pic.reshape(128*128,3)
  7.  
     
  8.  
    model=KMeans(n_clusters=16,n_init=100) #sklearn.cluster.KMeans(init=,max_iter=,n_clusters=,n_init=):n_clusters:聚类数量,即k值,默认为8;init:初始化聚类中心的方法,如需自定义设置,则传入ndarray格式的参数;n_init:用不同的初始化聚类中心运行算法的次数,默认为10,如自定义设置初始聚类中心,则为1;max_iter:最大迭代次数,默认300
  9.  
    model.fit(data)
  10.  
    centroids=model.cluster_centers_ #Kmeans.cluster_centers_:求取聚类中心
  11.  
    idx=model.predict(data) #求取样本属于哪个聚类的索引
  12.  
    compressed_pic=np.zeros(data.shape)
  13.  
    for i in range(16):
  14.  
    compressed_pic[idx==i]=centroids[i]
  15.  
    compressed_pic=compressed_pic.reshape(128,128,3)
  16.  
    fig,ax=plt.subplots(1,2)
  17.  
    ax[0].imshow(pic)
  18.  
    ax[1].imshow(compressed_pic)
  19.  
    plt.show()
学新通

原始图和压缩后图对比

学新通

4-Principal Component Analysis used for dimensional reduction of simple two-dimensional datasets: PCA主成分分析用于简单二维数据集的降维

导入库

  1.  
    import numpy as np
  2.  
    import matplotlib.pyplot as plt
  3.  
    from scipy.io import loadmat

函数:实施PCA

  1.  
    def PCA(X): #实施PCA
  2.  
    #Data Preprocessing:Mean Normalization
  3.  
    X=(X-X.mean())/X.std()
  4.  
    #Compute covariance matrix
  5.  
    X=np.matrix(X) #(50,2)
  6.  
    cov=(X.T*X)/X.shape[0] #(2,2)
  7.  
    #Implement SVD
  8.  
    U,S,V=np.linalg.svd(cov) #np.linalg.svd(X):X维度(M,N),返回主成分矩阵U大小为(M,M),S(除了对角元素不为0其他元素都为0,作为一维矩阵返回)大小为(M,N),V大小为(N,N)
  9.  
    return U,S,V

函数:选择主成分数量k

  1.  
    def Choose_k(X,S): #选择主成分数量k
  2.  
    for k in range(X.shape[1]):
  3.  
    variance=np.sum(S[:k 1])/np.sum(S[:])
  4.  
    if variance>0.99:
  5.  
    return k

函数:将2维原始数据投射到1维空间中

  1.  
    def project_data(X,U,k): #将2维原始数据投射到1维空间中
  2.  
    Ureduce=U[:,:k] #(2,1)
  3.  
    z=Ureduce.T*X.T
  4.  
    return z.T

函数:通过反向转换来恢复原始数据

  1.  
    def recover_data(Z,U,k): #通过反向转换来恢复原始数据
  2.  
    Ureduce=U[:,:k]
  3.  
    X_recovered=Ureduce*Z.T
  4.  
    return X_recovered.T

主函数:

  1.  
    #Principal Component Analysis used for dimensional reduction of simple two-dimensional datasets: PCA主成分分析用于简单二维数据集的降维
  2.  
     
  3.  
    data=loadmat('ex7data1.mat')
  4.  
    X=data['X']
  5.  
    U,S,V=PCA(X)
  6.  
    print(U,S,V)
  7.  
    k=Choose_k(X,S)
  8.  
    Z=project_data(X,U,k) #(50,1)
  9.  
    X_recovered=recover_data(Z,U,k)
  10.  
    fig,ax=plt.subplots(figsize=(12,8))
  11.  
    ax.scatter(list(X_recovered[:,0]),list(X_recovered[:,1])) #list():将数据转换为列表类型 #这里转化成列表类型后画散点图否则报错
  12.  
    #第一主成分的投影轴基本上是数据集中的对角线,当我们将数据减少到一个维度时,我们失去了该对角线周围的变化,所以在再现中,一切都沿着该对角线
  13.  
    plt.show()

U,S,V

学新通

 原始数据图

学新通

 降维后再恢复的数据图

学新通

5-Principal Component Analysis used for dimensional reduction of face images: PCA主成分分析用于脸部图像数据集的降维

导入库

  1.  
    import numpy as np
  2.  
    import matplotlib.pyplot as plt
  3.  
    from scipy.io import loadmat

函数:实施PCA

  1.  
    def PCA(X): #实施PCA
  2.  
    X=(X-X.mean())/X.std()
  3.  
    X=np.matrix(X)
  4.  
    cov=(X.T*X)/X.shape[0]
  5.  
    U,S,V=np.linalg.svd(cov)
  6.  
    return U,S,V

函数:选择主成分数量k

  1.  
    def Choose_k(X,S): #选择主成分数量k
  2.  
    for k in range(X.shape[1]):
  3.  
    variance=np.sum(S[:k 1])/np.sum(S[:])
  4.  
    if variance>0.99:
  5.  
    return k

函数:将2维原始数据投射到1维空间中

  1.  
    def project_data(X,U,k): #将2维原始数据投射到1维空间中
  2.  
    Ureduce=U[:,:k]
  3.  
    z=Ureduce.T*X.T
  4.  
    return z.T

函数:通过反向转换来恢复原始数据

  1.  
    def recover_data(Z,U,k): #通过反向转换来恢复原始数据
  2.  
    Ureduce=U[:,:k]
  3.  
    X_recovered=Ureduce*Z.T
  4.  
    return X_recovered.T

函数:渲染数据集中前n张图像

  1.  
    def plot_n_image(X,n): #渲染数据集中前n张图像
  2.  
    images=X[:n,:]
  3.  
    pic_size=int(np.sqrt(X.shape[1])) #np.sqrt(x):开平方
  4.  
    grid_size=int(np.sqrt(n))
  5.  
    fig,ax=plt.subplots(ncols=grid_size,nrows=grid_size,figsize=(8,8))
  6.  
    for i in range(grid_size):
  7.  
    for j in range(grid_size):
  8.  
    ax[i][j].imshow(images[i*grid_size j].reshape(pic_size,pic_size).T,cmap='OrRd_r') #将每张图reshape成32*32灰度的图像
  9.  
    ax[i][j].set_xticks([])
  10.  
    ax[i][j].set_yticks([])
  11.  
    plt.show()

主函数:

  1.  
    #Principal Component Analysis used for dimensional reduction of face images: PCA主成分分析用于脸部图像数据集的降维
  2.  
     
  3.  
    faces=loadmat('ex7faces.mat')
  4.  
    X=faces['X'] #(5000,1024)
  5.  
    plot_n_image(X,100)
  6.  
    face=np.reshape(X[3,:],(32,32)) #渲染后的原图片
  7.  
    plt.imshow(face,cmap='OrRd_r')
  8.  
    plt.show()
  9.  
    U,S,V=PCA(X)
  10.  
    k=Choose_k(X,S)
  11.  
    print(k)
  12.  
    Z=project_data(X,U,100) #取k=100
  13.  
    X_recovered=recover_data(Z,U,100)
  14.  
    face=np.reshape(X_recovered[3,:],(32,32)) #使用PCA处理并渲染后的图片
  15.  
    plt.imshow(face,cmap='OrRd_r')
  16.  
    plt.show()
学新通

主成分数量k

学新通

 渲染后的前100张图像

学新通

 使用PCA前渲染后的原图像

学新通

 使用PCA处理并渲染后的图片

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhghfcfe
系列文章
更多 icon
同类精品
更多 icon
继续加载