【机器学习】【SVD-3】SVD降维的应用简介 + 降维示例展示 + Python代码实现

1.SVD降维的基本原理

SVD降维的基本原理,可以详见以前文章:https://blog.csdn.net/u012421852/article/details/80433463

2.降维示例展示

降维的理论以及和意义不再赘述,此处仅仅给出SVD分解降维的一个应用示例。

Step1:准备要降维的数据矩阵M,以及奇异值开方和占比阈值percentage

    data = np.array([[5, 5, 0, 5],
                     [5, 0, 3, 4],
                     [3, 4, 0, 3],
                     [0, 0, 5, 3],
                     [5, 4, 4, 5],
                     [5, 4, 5, 5]])
    percentage = 0.9

Step2:对数据矩阵M进行奇异值分解

(U, S, VT) = np.linalg.svd(M)

解释np.linalg.svd(M)的返回值U,S,VT依次对应于下面SVD公式中的U,∑,V.T,

注意:svd()方法返回的第三个值是SVD中的V.T,而不是V,后面降维时直接使用VT[:K, :len(VT)]作为降维后的SVD公式中的VT

注意:S是M的所有奇异值的数组


求得的U,S,VT如下所示:

降维前的U,S,VT依次为:
(6, 6) U:
 [[-0.44721867  0.53728743  0.00643789 -0.50369332 -0.38572204 -0.32982993]
 [-0.35861531 -0.24605053 -0.86223083 -0.14584826  0.07797125  0.20015231]
 [-0.29246336  0.40329582  0.22754042 -0.10376096  0.4360044   0.70652449]
 [-0.20779151 -0.67004393  0.3950621  -0.58878098  0.02599042  0.06671744]
 [-0.50993331 -0.05969518  0.10968053  0.28687443  0.59460659 -0.53714128]
 [-0.53164501 -0.18870999  0.19141061  0.53413013 -0.54845844  0.24290419]]
(4,) S:
 [ 17.71392084   6.39167145   3.09796097   1.32897797]
(4, 4) VT:
 [[-0.57098887 -0.4274751  -0.38459931 -0.58593526]
 [ 0.22279713  0.51723555 -0.82462029 -0.05319973]
 [-0.67492385  0.69294472  0.2531966  -0.01403201]
 [ 0.41086611  0.26374238  0.32859738 -0.80848795]]

Step3:根据percentage求k值

    def _calc_k(self, percentge):
        '''确定k值:前k个奇异值的平方和占比 >=percentage, 求满足此条件的最小k值
        :param percentage, 奇异值平方和的占比的阈值
        :return 满足阈值percentage的最小k值
        '''
        self.k = 0
        #用户数据矩阵的奇异值序列的平方和
        total = sum(np.square(self.S))
        svss = 0 #奇异值平方和 singular values square sum
        for i in range(np.shape(self.S)[0]):
            svss += np.square(self.S[i])
            if (svss/total) >= percentge:
                self.k = i+1
                break
        return self.k

求得的k值为:2

即成立:前2个奇异值平方和 / 所有奇异值平方和 >= 0.9

Step4:根据求得的k构造k阶奇异值对角阵

    def _buildSD(self, k):
        '''构建由奇异值组成的对角矩阵
        :param k,根据奇异值开放和的占比阈值计算出来的k值
        :return 由k个前奇异值组成的对角矩阵
        '''
        #方法1:用数组乘方法
        self.SD = np.eye(self.k) * self.S[:self.k]

        #方法2:用自定义方法
        e = np.eye(self.k)
        for i in range(self.k):
            e[i,i] = self.S[i]

        return self.SD

Step5:根据求得的k求降维后的U和VT

new_U  = U[:len(U), :k]
new_VT = VT[:k, :len(VT)]

k=2时,降维后的U和VT为:

降维后的U, VT依次为:
(6,) new_U=U[:6,:2]:
 [[-0.44721867  0.53728743]
 [-0.35861531 -0.24605053]
 [-0.29246336  0.40329582]
 [-0.20779151 -0.67004393]
 [-0.50993331 -0.05969518]
 [-0.53164501 
  • 7
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值