【机器学习】PCA(特征值降维和奇异值降维)—— python3 实现方案

推荐这篇博文https://blog.csdn.net/shizhixin/article/details/51181379

看了许多,这篇讲的更容易理解些,排版清晰,公式推导严谨。但纵观那么多文章,却没有提及怎么选择 维度“K”的,吴恩达的机器学习课程,提到用平方误差和 与 训练集的方差 的比例,来衡量选取k维后,对原数据的保留程度,但没有详细说明怎么做。后来还是在《机器学习实战》上找到了方法,就是用  t=选取的特征值的和 / 所有特征值的和 ,来表示降维后,信息的保留程度。之所以能这样做,是因为在推导过程中发现,特征值等于原数据在对应特征向量降维后的方差,而方差反应了信息量的大小。

吴恩达的推荐使用matlab的SVD(奇异值分解)求解。 numpy上也有对应的函数可以调用,两种方法可以得到同样的结果,但经过实际测试可知,使用SVD计算,计算速度要快很多
 

import numpy as np
from sklearn import preprocessing as pp
from sklearn import datasets


class PCA:
    def __init__(self, k=10):
        self.k = k  # 目标维度

    def training(self, dataset, svd=False):
        """
        使用主成分分析算法,把n维数据集降为k维数据
        :param dataset: 数据集n*m,n为特征数,m为样本数,np.array
        :param svd: 是否使用奇异值分解求特征值
        :return: 降维后的数据集k*m,和信息量占比t
        """
        dataset = pp.scale(dataset, axis=1)  # 去均值化
        cov_mat = np.cov(dataset)  # 计算协方差矩阵
        if svd:  # 使用SVD(奇异值分解)求解
            u, s, vt = np.linalg.svd(cov_mat)  # s存储奇异值,u存储对应的特征向量
            eig_vals = s[: self.k]  # 选取前K个奇异值,对应特征值
            red_eig_vects = u[:, : self.k]  # 选取对应的特征向量, n*k
            t = np.sum(eig_vals) / np.sum(s)  # 计算信息保留度

        else:  # 使用求解特征值和特征矩阵的方式
            eig_vals, eig_vects = np.linalg.eig(cov_mat)  # 计算协方差矩阵的特征值和特征向量
            eig_vals_ind = np.argsort(eig_vals)[:: -1][: self.k]  # 获取前k个最大特征值的索引
            red_eig_vects = eig_vects[:, eig_vals_ind]  # 根据索引获取对应的特征向量
            # 在PCA,特征值等于对应特征向量*原数据后的方差,这里用方差代表信息量,该值衡量降维后保留的原数据多少的信息量
            t = np.sum(eig_vals[eig_vals_ind]) / np.sum(eig_vals)
        low_dim_data = np.dot(red_eig_vects.T, dataset)  # 特征向量*去均值化的原数据=降维后的数据
        return low_dim_data, t


def test():
    dataset = datasets.make_classification(n_samples=3000, n_features=100)[0]
    pca = PCA(k=60)
    print(pca.training(dataset, svd=True)[1])
    print(pca.training(dataset, svd=False)[1])


test()

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值