Python机器学习的练习七:K-Means聚类和主成分分析

这部分练习涵盖两个吸引人的话题:K-Means聚类和主成分分析(PCA),K-Means和PCA都是无监督学习技术的例子,无监督学习问题没有为我们提供任何标签或者目标去学习做出预测,所以无监督算法试图从数据本身中学习一些有趣的结构,我们将首先实现k-means,并了解如何使用它来压缩图像。我们还将用PCA进行实验,以发现面部图像的低维度表示。

K-Means聚类

首先,我们在一个简单的二维数据集上实现并应用k-means,以了解它如何工作。k-means是一种迭代的、无监督的聚类算法,它将类似的实例组合成集群。该算法通过猜测每个集群的初始centroid,反复向最近的集群分配实例,并重新计算该集群的centroid。首先我们要实现一个函数,它为数据中的每个实例找到最接近的centroid。

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import seaborn as sb 
from scipy.ioimport loadmat 
%matplotlib inline

def find_closest_centroids(X, centroids): 
    m= X.shape[0]
    k= centroids.shape[0]
    idx= np.zeros(m)

    for iin range(m):
        min_dist= 1000000
        for jin range(k):
            dist= np.sum((X[i,:]- centroids[j,:])** 2)
            if dist < min_dist:
                min_dist= dist
                idx[i]= j

    return idx

测试函数确保它像预期的那样工作,我们使用练习中的测试案例。

data= loadmat('data/ex7data2.mat') 
X= data['X'] 
initial_centroids= initial_centroids= np.array([[3,3], [6,2], [8,5]])

idx= find_closest_centroids(X, initial_centroids) 
idx[0:3]
array([0., 2., 1.])

输出与文本中的预期值相匹配(我们的数组是zero-indexed而不是one-indexed,所以值比练习中的值要低1)。接下来,我们需要一个函数来计算集群的centroid。centroid是当前分配给集群的所有例子的平均值。

def compute_centroids(X, idx, k): 
    m, n= X.shape
    centroids= np.zeros((k, n))

    for iin range(k):
        indices= np.where(idx== i)
        centroids[i,:]= (np.sum(X[indices,:], axis=1)/ len(indices[0])).ravel()

    return centroids

compute_centroids(X, idx,3)
array([[2.42830111, 3.15792418],
       [5.81350331, 2.63365645],
       [7.11938687, 3.6166844 ]])

此输出也与该练习的预期值相匹配。目前为止一切都很顺利。下一部分涉及到实际运行算法的迭代次数和可视化结果。我们在练习中实现了这一步骤,它没有那么复杂,我将从头开始构建它。为了运行这个算法,我们只需要在分配到最近集群的示例和重新计算集群的centroids之间进行交替操作。

def run_k_means(X, initial_centroids, max_iters): 
    m, n= X.shape
    k= initial_centroids.shape[0]
    idx= np.zeros(m)
    centroids= initial_centroids

    for iin range(max_iters):
        idx= find_closest_centroids(X, centroids)
        centroids= compute_centroids(X, idx, k)

    return idx, centroids

idx, centroids= run_k_means(X, initial_centroids,10)

我们现在可以使用颜色编码表示集群成员。

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(figsize=(12,8)) 
ax.scatter(cluster1[:,0], cluster1[:,1], s=30, color='r', label='Cluster 1') 
ax.scatter(cluster2[:,0], cluster2[:,1], s=30, color='g', label='Cluster 2') 
ax.scatter(cluster3[:,0], cluster3[:,1], s=30, color='b', label='Cluster 3') 
ax.legend()

我们跳过了初始化centroid的过程。这可能会影响算法的收敛性。

接下来创建一个可以选择随机例子的函数,并将这些例子作为初始的centroid。

def init_centroids(X, k): 
    m, n= X.shape
    centroids= np.zeros((k, n))
    idx= np.random.randint(0, m, k)

    for iin range(k):
        centroids[i,:]= X[idx[i],:]

    return centroids

init_centroids(X,3)
array([[1.15354031, 4.67866717],
       [6.27376271, 2.24256036],
       [2.20960296, 4.91469264]])

我们的下一任务是应用K-means实现图像压缩。我们可以使用集群来查找图像中最具有代表性的少量的颜色,并使用集群分配将原来的24位颜色映射到一个低维度的颜色空间。这是我们要压缩的图像。

原始像素数据已经预加载了,把它输入进来。

image_data= loadmat('data/bird_small.mat') 
image_data
{'A': array([[[219,180,103],
         [230,185,116],
         [226,186,110],
         ...,
         [14, 15, 13],
         [13, 15, 12],
         [12, 14, 12]],
        ..., 
        [[15, 19, 19],
         [20, 20, 18],
         [18, 19, 17],
         ...,
         [65, 43, 39],
         [58, 37, 38],
         [52, 39, 34]]], dtype=uint8),
 '__globals__': [],
 '__header__':'MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Tue Jun  5 04:06:24 2012',
 '__version__':'1.0'}

我们可以快速查看数据的形状,以验证它是否像我们预期的图像。

A= image_data['A'] 
A.shape
(128L,128L,3L)

现在我们需要对数据进行预处理,并将它输入到k-means算法中。

# normalize value ranges
A= A/ 255.

# reshape the array
X= np.reshape(A, (A.shape[0]* A.shape[1], A.shape[2]))

# randomly initialize the centroids
initial_centroids= init_centroids(X,16)

# run the algorithm
idx, centroids= run_k_means(X, initial_centroids,10)

# get the closest centroids one last time
idx= find_closest_centroids(X, centroids)

# map each pixel to the centroid value
X_recovered= centroids[idx.astype(int),:]

# reshape to the original dimensions
X_recovered= np.reshape(X_recovered, (A.shape[0], A.shape[1], A.shape[2]))

plt.imshow(X_recovered)

我们在压缩中创建了一些artifact,尽管将原始图像映射到仅16种颜色,但图像的主要特征仍然存在。

这是关于k-means的部分,接下来我们来看关于主成分分析的部分。

主成分分析

PCA是一个可以在数据集中找到“主成分”或者最大方差方向的线性变换。它可以用于其他事物的维度减少。在这个练习中,我们需要实现PCA,并将其应用于一个简单的二维数据集,观察它是如何工作的。从加载和可视化数据集开始。

data= loadmat('data/ex7data1.mat') 
X= data['X']

fig, ax= plt.subplots(figsize=(12,8)) 
ax.scatter(X[:,0], X[:,1])

PCA的算法相当简单。在保证数据正规化后,输出只是原始数据协方差矩阵的单值分解。由于numpy已经有内置函数来计算矩阵协方差和SVD,我们将利用这些函数而不是从头开始。

def pca(X): 
    # normalize the features
    X= (X- X.mean())/ X.std()

    # compute the covariance matrix
    X= np.matrix(X)
    cov= (X.T* X)/ X.shape[0]

    # perform SVD
    U, S, V= np.linalg.svd(cov)

    return U, S, V

U, S, V= pca(X) 
U, S, V
(matrix([[-0.79241747,-0.60997914],
         [-0.60997914, 0.79241747]]),
 array([1.43584536, 0.56415464]),
 matrix([[-0.79241747,-0.60997914],
         [-0.60997914, 0.79241747]]))

现在我们已经有了主成分(矩阵U),我们可以利用它把原始数据投入到一个更低维度的空间,对于这个任务,我们将实现一个函数,它计算投影并只选择顶部K成分,有效地减少了维度的数量。

def project_data(X, U, k): 
    U_reduced= U[:,:k]
    return np.dot(X, U_reduced)

Z= project_data(X, U,1) 
Z
matrix([[-4.74689738],
        [-7.15889408],
        [-4.79563345],
        [-4.45754509],
        [-4.80263579],
        ...,
        [-6.44590096],
        [-2.69118076],
        [-4.61386195],
        [-5.88236227],
        [-7.76732508]])

我们也可以通过改变采取的步骤来恢复原始数据。

def recover_data(Z, U, k): 
    U_reduced= U[:,:k]
    return np.dot(Z, U_reduced.T)

X_recovered= recover_data(Z, U,1) 
X_recovered
matrix([[3.76152442, 2.89550838],
        [5.67283275, 4.36677606],
        [3.80014373, 2.92523637],
        [3.53223661, 2.71900952],
        [3.80569251, 2.92950765],
        ...,
        [5.10784454, 3.93186513],
        [2.13253865, 1.64156413],
        [3.65610482, 2.81435955],
        [4.66128664, 3.58811828],
        [6.1549641 , 4.73790627]])

如果我们尝试去可视化恢复的数据,会很容易的发现算法的工作原理。

fig, ax= plt.subplots(figsize=(12,8)) 
ax.scatter(X_recovered[:,0], X_recovered[:,1])

注意这些点如何被压缩成一条虚线。虚线本质上是第一个主成分。当我们将数据减少到一个维度时,我们切断的第二个主成分可以被认为是与这条虚线的正交变化。由于我们失去了这些信息,我们的重建只能将这些点与第一个主成分相关联。

我们这次练习的最后一项任务是将PCA应用于脸部图像。通过使用相同降维技术,我们可以使用比原始图像少得多的数据来捕捉图像的“本质”。

faces= loadmat('data/ex7faces.mat') 
X= faces['X'] 
X.shape
(5000L,1024L)

该练习代码包含一个函数,它将在网格中的数据集中渲染前100个脸部图像。你可以在练习文本中找到它们,不需要重新生成。

face= np.reshape(X[3,:], (32,32)) 
plt.imshow(face)

只有32 x 32灰度图像。下一步我们要在脸部图像数据集上运行PCA,并取得前100个主成分。

U, S, V= pca(X) 
Z= project_data(X, U,100)

现在尝试恢复原来的结构并重新渲染它。

X_recovered= recover_data(Z, U,100) 
face= np.reshape(X_recovered[3,:], (32,32)) 
plt.imshow(face)

结果并没有像预期的维度数量减少10倍,可能是因为我们丢失了一些细节部分。

本文为编译文章,作者John Wittenauer,原网址

http://www.johnwittenauer.net/machine-learning-exercises-in-python-part-7/

本文分享自微信公众号 - ATYUN订阅号(atyun_com)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-08-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CDA数据分析师

入门:机器学习和数据挖掘推荐书单

有了这些书,再也不愁下了班没妹纸该咋办了。慢慢来,认真学,揭开机器学习和数据挖掘这一神秘的面纱吧! ? 《机器学习实战》:本书第一部分主要介绍机器学习基础,以及...

372100
来自专栏企鹅号快讯

盘点实际项目应用中的最佳机器学习模型

关键时刻,第一时间送达! 作者简介:chen_h,AI 算法工程师,擅长利用 TensorFlow 处理 NLP 问题。曾任职蘑菇街(美丽联合集团)和 AI10...

28860
来自专栏企鹅号快讯

2017年度30大最惊艳的开源机器学习项目

在过去的一年里,Mybridge AI 比较了近 8,800个开源机器学习项目,选择了前30名(概率只有0.3%)。 这是一个竞争激烈的名单,精挑细选了2017...

31680
来自专栏CDA数据分析师

一名合格的机器学习工程师需要具备的5项基本技能,你都get了吗?

你是否对机器学习充满兴趣呢?其实到目前为止,每天有越来越多的工程师开始将好奇的目光转向机器学习领域。实际上,你会发现现在没有哪一个领域比机器学习能引起更多的曝光...

21290
来自专栏CDA数据分析师

美团实例详解机器学习如何解决问题

前言 随着大数据时代的到来,机器学习成为解决问题的一种重要且关键的工具。不管是工业界还是学术界,机器学习都是一个炙手可热的方向,但是学术界和工业界对机器学习的...

24690
来自专栏CSDN技术头条

写给非技术人员的机器学习指南

译者注:很多人都在谈人工智能,谈机器学习,但他们有自己的理解,作者从一个非常有趣的场景开始延伸,步步深入,对机器学习有独特的解释和指导。 这里是另一家创业公司的...

20560
来自专栏CSDN技术头条

【BDTC 2017讲师专访】彭冬:微博商业基础大数据平台(D+)的架构演进

BDTC 2017中国大数据技术大会将于12月7日-9日在北京新云南皇冠假日酒店举行,大会为期三天。届时,近百位技术专家将为现场数千名的大数据行业精英、技术...

28250
来自专栏CSDN技术头条

对于机器学习,到底该选择哪种编程语言?

开发者到底应该学习哪种编程语言才能获得机器学习或数据科学这类工作呢?这是一个非常重要的问题。我们在许多论坛上都讨论过这个问题。今天,我将给出我自己的答案并解释其...

44080
来自专栏企鹅号快讯

Yann LeCun:深度学习已死,可微分编程万岁!

昨天,Yann LeCun在Facebook个人主页上写到:深度学习已死,可微分编程万岁!这让不少人大吃一惊,莫非我们一直坚信的深度学习技术是假的“炒作概念”?...

27790
来自专栏企鹅号快讯

浅谈机器学习业务方面使用R+Hadoop 是否可靠

众所周知,R 在解决统计学问题方面无与伦比。但是 R 在数据量达到 2G 以上速度就很慢了,于是就催生出了与 hadoop 相结合跑分布式算法这种解决方案,但是...

19890

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励