大数据的理解
大数据定义
数据被定义为过于巨大的数据集合,以至于变得难以使用传统技术来处理。大数据的大体现在三个方面:
- 样例比较大
比如统计了10人的样本数据,比如有100万个图像数据。 - 时间维度大
就是可能我们采集的样本很少,但是每个样本所采集的时间非常就,从时间这个维度看,数据量也是巨大的。 - 数据维度大
就是一个应用跟踪了样例的多个方面。高纬度数据就是提供了许多特征(变量),经常事数以百计或千计的。这可能转变为一个很现实的问题,即使你观察的少数样例,但是处理太多的特征也会让大部分分析变得难以驾驭。
使用如此之多的维度进行工作的复杂性驱动了各种各样的数据技术的需求来过滤信息,让数据看起来能更好的解决问题。过滤器通过移除高纬度数据集中的冗余信息来降低维度。
我们可以把将为理解为对数据的信息压缩,类似于压缩10001000的图像到6464分辨率,同样也是能够理解图片的意思的。
理解奇异值分解SVD
在大数据降维的核心算法SVD,我们称之为奇异值分解。SVD的公式是:
M = U * s * Vh
这个公式的含义是,原始数据矩阵M被分解为三个矩阵的乘积。
U:包含有关行的信息
Vh: Vh包揽有关列的所有信息
s: 记录SVD过程
最关键的是要理解s所代表的意思,比如s所有元素的和事100,s的第一个值是99,这就意味99%的信息储存在了U和Vh的第一列中。因此你可以愉快的抛弃第一列之后的所有剩余列,而又不会丢失数据的重要信息,只丢失了1%的信息,对数据来说并不太重要。
举例说明
import numpy as np
M = np.array([[1, 3, 4], [2, 3, 5], [1, 2, 3], [5, 4, 6]])
print(M)
[[1 3 4]
[2 3 5]
[1 2 3]
[5 4 6]]
这个例子中需要降维的数据M,包含4个样例,每个样例包括3个特征值。下面我们就使用linalg模块的svd函数,进行分解矩阵:
U, s, Vh = np.linalg.svd(M, full_matrices=False)
print(U.shape, s.shape, Vh.shape)
(4, 3) (3,) (3, 3)
print(s)
[12.26362747 2.11085464 0.38436189]
通过s里的值可以看出第一列包含了大部分信息(超过80%)。第二列有些值(大约14%),第三列则包含了参与的信息。
当然svd公式是可逆的,就是分解出来的这三个矩阵还能通过点乘还原原始的矩阵。注意,矩阵s实际上是对角矩阵,还原的时候要使用对角矩阵参与运算。
# s转换为对角矩阵
print(np.diag(s))
array([[12.26362747, 0. , 0. ],
[ 0. , 2.11085464, 0. ],
[ 0. , 0. , 0.38436189]])
back_M = np.dot(np.dot(U, np.diag(s)), Vh)
print(back_M)
[[1. 3. 4.]
[2. 3. 5.]
[1. 2. 3.]
[5. 4. 6.]]
可以看出还原之后的back_M和之前的M矩阵是一样的。
如何利用SVD进行降维(压缩特征维度)
SVD输出的三个矩阵入手,想办法去除第三列的内容。U取U[:,:2],变成(4,2),s取s[:2],变成了(2,),Vh取Vh[:2,:],变成了(2,3)
back_M1 = np.dot(np.dot(U[:,:2],np.diag(s[:2])), Vh[:2,:])
print(np.round(back_M1,1))
[[1. 2.8 4.1]
[2. 3.2 4.8]
[1. 2. 3. ]
[5. 3.9 6. ]]
可以看出即使丢失最后一列的数值,还原之后和过去相比有一些差别,但是并不是很大。也是就是说可以用更少的维度取保存过去的值。
到底哪里降维了呢?
看到这里你可能都有点疑惑,到底是哪里降维了呢?从过去的(4,3)矩阵,变成现在三个矩阵(4,3)(3,)(3,3),不但维度没有降,而且还增加一些数据。
假如说我们忽略最后一列的信息,变成三个矩阵(4,1),(1,),(1,3),从过去的4x3=12个数字,变成现在的4+1+3个数字,确实是降了。但是我们应该如何利用这三个矩阵参与机器学习中呢?