《机器学习实战》--PCA降维以及代码实现

1、PCA

在机器学习的领域中,我们需要提取原始数据的特征,得到的特征向量有时是高维数据,并且高维数据中存在噪声和冗余。降维是从高维数据中找出一些重要的特征,去除冗余和噪声,寻找出其内部的特性,提升其特征表达能力,降低训练复杂度。

主成分分析(Principal Component Analysis, PCA)作为降维算法中最经典和常用的方法,它是一种线性、非监督、全局的降维算法。在PCA中,数据从原来的坐标系转换到新的坐标系,新的坐标系的选择是由数据本身决定的。

第一个坐标系的选择是数据中方差最大的方向,第二个新坐标系和第一个坐标系正交且具有最大方差的方向。一直重复,重复次数为原始数据中特征的数目。大部分方差都包含在最前面的几个新的坐标系中,可以忽略余下的坐标轴,从而对数据进行了降维的处理。
PCA的目标是最大化投影方差,即让数据在主轴上的投影方差最大。

  • 优点:降低数据的复杂度,识别最重要的多个特征。
  • 缺点:不一定需要,可能损失有用的信息。
  • 适用数据类型:数值型数据。

2、Numpy实现PCA

伪码如下:
去除平均值(中心化):

  • 求平均值
  • 原始数据-平均值

计算协方差矩阵
计算协方差矩阵的特征值和特征向量
将特征值从小到大排序
保留最上面的N个特征向量

  • 数据投影后的方差就是协方差矩阵的特征值,要找到最大的方差也就是协方差矩阵中最大的特征值,最佳投影方向就是最大特征值所对应的的特征向量(线性代数证明)。

将数据转换到上述N个特征向量构建的新空间中

数据链接:https://pan.baidu.com/s/1jRtWIn3vy7mNX4OisKTvbA 提取码:2l9i
代码如下:

import numpy as np
import matplotlib.pyplot as plt
import os

class PCA(object):
    def __init__(self):
        print("使用Numpy实现PCA算法")
    def load_dataset(self,file_name,delim='\t'):
        '''
        加载数据集
        Args:
            file_name:文件名
            delim:

        Returns:
            data_mat:数据矩阵
        '''
        with open(file_name) as f:
            data = f.readlines()
        string_arr = [line.strip().split(delim) for line in data]
        dat_arr = [list(map(float,line)) for line in string_arr]
        return np.mat(dat_arr)
    def pca(self,data_mat,top_N_feat=9999999):
        '''
        PCA算法
        Args:
            data_mat:数据矩阵
            top_N_feat:最大特征向量,即应用的N个特征,如果不指定top_N_feat,
                        那么函数会返回前9999999个特征,或原始数据中全部的特征。

        Returns:
            low_DDate_mat:降维后的数据集
            recon_mat:新的数据空间
        '''
        mean_val = np.mean(data_mat) # 计算平均值
        mean_removed = data_mat - mean_val
        cov_mat = np.cov(mean_removed,rowvar=0) # 计算协方差矩阵
        eig_vals,eig_vects = np.linalg.eig(np.mat(cov_mat)) # 计算特征值和特征向量
        eig_val_Ind = np.argsort(eig_vals) # 特征值从小到大排序
        eig_val_Ind = eig_val_Ind[:-(top_N_feat+1):-1] # 从step=-1,即右边的第一个元素到第top_N_feat
        red_eig_vects = eig_vects[:,eig_val_Ind]
        low_DData_mat = mean_removed * red_eig_vects
        recon_mat = (low_DData_mat * red_eig_vects.T) + mean_val
        return low_DData_mat,recon_mat
    def plot(self,data_mat,recon_mat):
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.scatter(data_mat[:,0].flatten().A[0],data_mat[:,1].flatten().A[0],
                   marker='^',s = 90)
        ax.scatter(recon_mat[:,0].flatten().A[0],recon_mat[:,1].flatten().A[0],
                   marker='o',s=50,c='red')
        plt.show()
if __name__ == '__main__':
    data_root = os.path.join(os.path.dirname(os.getcwd()),'data')
    pca = PCA()

    data_mat = pca.load_dataset(os.path.join(data_root,'testSet.txt'))
    print(data_mat)
    low_D_mat,recon_mat = pca.pca(data_mat,1)
    pca.plot(data_mat,recon_mat)
    # 不剔除特征
    low_D_mat,recon_mat = pca.pca(data_mat,2)
    pca.plot(data_mat,recon_mat)       

结果如下:
在这里插入图片描述
在这里插入图片描述
参考书籍:《百面机器学习》《机器学习实战

由于作者水平有限,文中若有不正确的地方,欢迎大家指出,若有任何问题,请在下方讨论。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值