注:《SVD(奇异值分解)小结 》中分享了SVD原理,但其中只是利用了numpy.linalg.svd函数应用了它,并没有提到如何自己编写代码实现它,在这里,我再分享一下如何自已写一个SVD函数。但是这里会利用到SVD的原理,如果大家还不明白它的原理,可以去看看《SVD(奇异值分解)小结 》,或者自行百度/google。数据集:https://pan.baidu.com/s/1ZmpUSIscy4VltcimwwIWew

1、SVD算法实现

1.1 SVD原理简单回顾

有一个\(m \times n\)的实数矩阵\(A\),我们可以将它分解成如下的形式

\[A = U\Sigma V^T
\tag{1-1}
\]

其中\(U\)和\(V\)均为单位正交阵,即有\(UU^T=I\)和\(VV^T=I\),\(U\)称为左奇异矩阵,\(V\)称为右奇异矩阵,\(\Sigma\)仅在主对角线上有值,我们称它为奇异值,其它元素均为0。上面矩阵的维度分别为\(U \in \mathbf{R}^{m\times m},\ \Sigma \in \mathbf{R}^{m\times n}\),\(\ V \in \mathbf{R}^{n\times n}\)。

正常求上面的\(U,V,\Sigma\)不便于求,我们可以利用如下性质

\[AA^T=U\Sigma V^TV\Sigma^TU^T=U\Sigma \Sigma^TU^T
\tag{1-2}
\]

\[A^TA=V\Sigma^TU^TU\Sigma V^T=V\Sigma^T\Sigma V^T
\tag{1-3}
\]

1.2 SVD算法

据1.1小节,对式(1-3)和式(1-4)做特征值分解,即可得到奇异值分解的结果。但是样分开求存在一定的问题,由于做特征值分解的时候,特征向量的正负号并不影响结果,比如,我们利用式(1-3)和(1-4)做特征值分解

\[AA^T\mathbf{u}_i = \sigma_i \mathbf{u}_i\quad \text{or} \quad AA^T(-\mathbf{u}_i) = \sigma_i (-\mathbf{u}_i)\\
A^TA\mathbf{v}_i = \sigma_i \mathbf{v}_i\quad \text{or} \quad A^TA(-\mathbf{v}_i) = \sigma_i (-\mathbf{v}_i)
\]

如果在计算过程取,取上面的\(\mathbf{u}_i\)组成左奇异矩阵\(U\),取\(-\mathbf{v}_i\)组成右奇异矩阵\(V\),此时\(A\ne U\Sigma V^T\)。因此求\(\mathbf{v}_i\)时,要根据\(\mathbf{u}_i\)来求,这样才能保证\(A= U\Sigma V^T\)。因此,我们可以得出如下1.1计算SVD的算法。它主要是先做特性值分解,再根据特征值分解得到的左奇异矩阵\(U\)间接地求出部分的右奇异矩阵\(V'\in \mathbf{R}^{m\times n}\)。

算法1.1:SVD

输入:样本数据

输出:左奇异矩阵,奇异值矩阵,右奇异矩阵

  1. 计算特征值: 特征值分解\(AA^T\),其中\(A \in \mathbf{R}^{m\times n}\)为原始样本数据

    \[AA^T=U\Sigma \Sigma^TU^T
    \]

    得到左奇异矩阵\(U \in \mathbf{R}^{m \times m}\)和奇异值矩阵\(\Sigma' \in \mathbf{R}^{m \times m}\)

  2. 间接求部分右奇异矩阵: 求\(V' \in \mathbf{R}^{m \times n}\)

    利用\(A=U\Sigma'V'\)可得

    \[V' = (U\Sigma')^{-1}A = (\Sigma')^{-1}U^TA
    \tag{1-4}
    \]

  3. 返回\(U,\ \Sigma',\ V'\),分别为左奇异矩阵,奇异值矩阵,右奇异矩阵。

注:这里得到的\(\Sigma'\)和\(V'\)与式(1-2)所得到的\(\Sigma,\ V\)有区别,它们的维度不一样。\(\Sigma'\)是只取了前\(m\)个奇异值形成的对角方阵,即\(\Sigma' \in \mathbf{R}^{m \times m}\);\(V'\)不是一个方阵,它只取了\(V \in \mathbf{R}^{m \times n}\)的前\(m\)行(假设\(m < n\)),即有\(V' = V(:m,\cdot)\)。这样一来,我们同样有类似式(1-1)的数学关系成立,即

\[ A = U\Sigma' (V')^T\tag{1-5}
\]

我们可以利用此关系重建原始数据。

2、SVD的Python实现

以下代码的运行环境为python3.6+jupyter5.4

2.1 SVD实现过程

读取数据

这里面的数据集大家随便找一个数据就好,如果有需要我的数据集,可以下在面留言。

import numpy as np
import pandas as pd
from scipy.io import loadmat # 读取数据,使用自己数据集的路径。
train_data_mat = loadmat("../data/train_data2.mat")
train_data = train_data_mat["Data"]
print(train_data.shape)

特征值分解

# 数据必需先转为浮点型,否则在计算的过程中会溢出,导致结果不准确
train_dataFloat = train_data / 255.0
# 计算特征值和特征向量
eval_sigma1,evec_u = np.linalg.eigh(train_dataFloat.dot(train_dataFloat.T))

计算右奇异矩阵

#降序排列后,逆序输出
eval1_sort_idx = np.argsort(eval_sigma1)[::-1]
# 将特征值对应的特征向量也对应排好序
eval_sigma1 = np.sort(eval_sigma1)[::-1]
evec_u = evec_u[:,eval1_sort_idx]
# 计算奇异值矩阵的逆
eval_sigma1 = np.sqrt(eval_sigma1)
eval_sigma1_inv = np.linalg.inv(np.diag(eval_sigma1))
# 计算右奇异矩阵
evec_part_v = eval_sigma1_inv.dot((evec_u.T).dot(train_dataFloat))

上面的计算出的evec_u, eval_sigma1, evec_part_v分别为左奇异矩阵,所有奇异值,右奇异矩阵。

2.2 SVD降维后重建数据

取不同个数的奇异值,重建图片,计算出均方误差,如图2-1所示。从图中可以看出,随着奇异值的增加,均方误差(MSE)在减小,且奇异值和的比率正快速上升,在100维时,奇异值占总和的53%。


图2-1 奇值分解维度和均方误差变化图

注: 均方误差MSE有如下计算公式

\[\text{MSE} = \frac{1}{n}\left((y_1-y_1')^2+(y_2-y_2')^2+\cdots+(y_n-y_n')^2\right)
\]

我们平时听到的\(\text{RMSE}=\sqrt{\text{MSE}}\)。

将图和10、50、100维的图进行比较,如图2-2所示。在直观上,100维时,能保留较多的信息,此时能从图片中看出车辆形状。

图2-2 原图与降维重建后的图比较

总结

SVD与特征值分解(EVD)非常类似,应该说EVD只是SVD的一种特殊怀况。我们可以通过它们在实际的应用中返过来理解特征值/奇异值的含义:特征值/奇异值代表着数据的信息量,它的值越大,信息越多。

最近作业是真的多呀,冒着生命危险来分享,希望能给大家带来帮助

SVD(奇异值分解)Python实现的更多相关文章

  1. SVD奇异值分解的基本原理和运用

    SVD奇异值分解: SVD是一种可靠的正交矩阵分解法.可以把A矩阵分解成U,∑,VT三个矩阵相乘的形式.(Svd(A)=[U*∑*VT],A不必是方阵,U,VT必定是正交阵,S是对角阵<以奇异值 ...

  2. [机器学习]-SVD奇异值分解的基本原理和运用

    SVD奇异值分解: SVD是一种可靠的正交矩阵分解法.可以把A矩阵分解成U,∑,VT三个矩阵相乘的形式.(Svd(A)=[U*∑*VT],A不必是方阵,U,VT必定是正交阵,S是对角阵<以奇异值 ...

  3. 『科学计算_理论』SVD奇异值分解

    转载请声明出处 SVD奇异值分解概述 SVD不仅是一个数学问题,在工程应用中的很多地方都有它的身影,比如前面讲的PCA,掌握了SVD原理后再去看PCA那是相当简单的,在推荐系统方面,SVD更是名声大噪 ...

  4. SVD奇异值分解的几何物理意义资料汇总

    学习SVD奇异值分解的网上资料汇总: 1. 关于svd的一篇概念文,这篇文章也是后续几篇文章的鼻祖~ http://www.ams.org/samplings/feature-column/fcarc ...

  5. 简单易学的机器学习算法—SVD奇异值分解

    简单易学的机器学习算法-SVD奇异值分解 一.SVD奇异值分解的定义     假设M是一个的矩阵,如果存在一个分解: 其中的酉矩阵,的半正定对角矩阵,的共轭转置矩阵,且为的酉矩阵.这样的分解称为M的奇 ...

  6. 对SVD奇异值分解的理解

      首先推荐一篇博客,奇异值分解(SVD)原理详解及推导 - CSDN博客,讲解的很清楚.这里我谈谈自己的理解,方便以后回顾.   如果把向量理解为空间中的一个元素,那么矩阵可以理解为两个空间上的映射 ...

  7. Deep Learning基础--SVD奇异值分解

    矩阵奇异值的物理意义是什么?如何更好地理解奇异值分解?下面我们用图片的例子来扼要分析. 矩阵的奇异值是一个数学意义上的概念,一般是由奇异值分解(Singular Value Decomposition ...

  8. 机器学习(十七)— SVD奇异值分解

    奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...

  9. 机器学习降维--SVD奇异值分解

    奇异值分解是有着很明显的物理意义,将一个比较复杂的矩阵用更小更简单的几个子矩阵的相乘来表示,这些小矩阵描述的是矩阵的重要的特性,让机器学会抽取重要的特征,SVD是一个重要的方法. 所以SVD不仅是一个 ...

  10. SVD奇异值分解

    奇异值分解 备忘:Eigen类库可能会和其他库产生冲突,将Eigen类库的头文件引用放到前面解决了.

随机推荐

  1. 数据库小组第N次小组会议

    时间:5.30晚,9:30 ~ 11:30 主题:讨论android app与服务器之间数据同步的技术选型与实现 与会人:陈兆庭,黄志鹏,吴雪晴 讨论内容: 大体分析 关于数据同步,整体上有两部分,用 ...

  2. 70部MAYA灯光材质渲染教程合集

    MAYA灯光材质渲染教程合集 教程格式:MP4和flv 两种格式 使用版本:教程不是一年出的教程,各个版本都有 (教程软件为英文版) 清晰度:可以看清软件上的文字 语言:部分中文字幕,其他英文(通过看 ...

  3. sql server对并发的处理-乐观锁和悲观锁(转)

    假如两个线程同时修改数据库同一条记录,就会导致后一条记录覆盖前一条,从而引发一些问题. 例如: 一个售票系统有一个余票数,客户端每调用一次出票方法,余票数就减一. 情景: 总共300张票,假设两个售票 ...

  4. 绕过安全狗狗的WebShell for PHP

    最近发现一款过狗shell,分享下...     本地搭建2008SERVER+php5+阿帕奇+网站安全狗+服务器安全狗+防护全开 测试可用... 默认密码:p0tt1 使用方法: ,没关系,按p键 ...

  5. centos7装机教程

    U盘启动电脑进入安装界面 正常情况下你应该会看到下面的这个界面: 选择第一项,然后按TAB键,然后会看到下面这个: 3.修改第二步中按TAB键出来的命令 将命令修改为:>vmlinuz init ...

  6. JavaSript模块规范 - AMD规范与CMD规范介绍[转]

    原文地址:http://blog.chinaunix.net/uid-26672038-id-4112229.html JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什 ...

  7. 百度地图Key的设置方法

    一.为什么要设置百度Key 万能地图下载器提供了百度POI的下载功能,但由于本软件用户群极大,会导致一天之内访问量超出300万次以上而无法继续下载. 因此,当POI下载不成功能,用户可以自己申请百度地 ...

  8. Tushare test

    查看版本 import tushare print(tushare.__version__) 1.2.12 初步的调用方法为: import tushare as ts ts.get_hist_dat ...

  9. swift的类型约束

    关键词: 类型与功能绑定.类型指定.访问控制. 类型约束的本质: 1.是否强制指定具有某些特征的类型:看类型构造器的定义本身是否对类型有约束: 2.访问控制:类型构造器的功能分为通用功能和约束功能: ...

  10. win10管理员已阻止你运行此应用”解决方法

    方法/步骤 1 按WIN+R键,打开“运行”,然后输入“gpedit.msc",就是打开组策略,这个在控制面板中也可以打开. 2 在组策略里找到“计算机配置”-“Windows设置”-“安全 ...