PCA
今天的数据是机器学习支撑,所谓大数据也就是高纬度的数据,获取数据我们尽可能获取包含更多信息的数据。无论信息(维度)是否有用我们先不管获取就得。这样一来在我们分析数据,获取将数据喂给机器时候就需要进行必要处理。为避免增加计算量,我们可以同一些分析处理对数据进行降维。
例如推荐系统我们将每一个商品建立一个维度,那么数据样本维度就会上万,这样当前计算能力还是吃不消的。这样就需要我们对数进行降维,降维技术要尽可能保留数据结构,在降维后因为数据结构被保留下来,获得的结果是原始数据空间的可靠近似。
我们先来 PCA 是如何实现降维
假设我们数据集 也就是有 n 个样本,每一个样本有 m 特征(也就是有 m 个维度),PCA 就是将这个
矩阵投射到小子空间
上,
PCA 降维方法
- 将相关变量转换为一系列不相关的变量。
- 找到主轴,记录数据的大部分变化
抽取主成分
import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import scale
import scipy
import matplotlib.pyplot as plt
data = load_iris()
x = data['data']
y = data['target']
x_s = scale(x,with_mean=True,with_std=True,axis=0)
这是数据标准化,将矩阵 x 缩放成为均值 0 标准差 1,确保所有列尺度都一致,好处我就不说了。
x_c = np.corrcoef(x_s.T)
eig_val,r_eig_vec = scipy.linalg.eig(x_c)
print('Eigen values \n%s' % (eig_val))
print('\n Eigen vectors \n%s' %(r_eig_vec))
Eigen values
[2.91849782+0.j 0.91403047+0.j 0.14675688+0.j 0.02071484+0.j]
Eigen vectors
[[ 0.52106591 -0.37741762 -0.71956635 0.26128628]
[-0.26934744 -0.92329566 0.24438178 -0.12350962]
[ 0.5804131 -0.02449161 0.14212637 -0.80144925]
[ 0.56485654 -0.06694199 0.63427274 0.52359713]]
协方差矩阵
协方差矩阵给出了所有不同特征两两之间相关性,给出强相关的特征和独立特征。
x_c
array([[ 1. , -0.11756978, 0.87175378, 0.81794113],
[-0.11756978, 1. , -0.4284401 , -0.36612593],
[ 0.87175378, -0.4284401 , 1. , 0.96286543],
[ 0.81794113, -0.36612593, 0.96286543, 1. ]])
img = plt.matshow(x_c,cmap=plt.cm.rainbow)
plt.colorbar(img,ticks=[-1,0,1],fraction=0.045)
for x in range(x_c.shape[0]):
for y in range(x_c.shape[1]):
plt.text(x,y,"%0.2f" % x_c[x,y],size=12,color='black',ha='center',va='center')
plt.show()

对角线上 1 表示强相关,这是因为自己和自己一定是强相关。通过热力图我们可以清晰看出 1 和 3 和 4 特征相关性比较强。
# 选择最前两个特征向量
w = r_eig_vec[:,0:2]
# 用适合的特征向量将原来四维的数据降为二维
x_rd = x_s.dot(w)
plt.figure(1)
plt.scatter(x_rd[:,0],x_rd[:,1],c=y)
plt.xlabel("Component 1")
plt.ylabel('Component 2')
Text(0, 0.5, 'Component 2')

核PCA
PCA 假定数据所有变换的主要方向都是直线,这对于大部分真实场景的数据集来说都是无法满足的。这是因为 PCA 线性分布的数据。
from sklearn.datasets import make_circles
from sklearn.decomposition import KernelPCA
np.random.seed(0)
x,y = make_circles(n_samples=400,factor=.2,noise=0.02)
plt.close('all')
plt.figure(1)
plt.title('Original Space')
plt.scatter(x[:,0],x[:,1],c=y)
plt.xlabel("$X_1$")
plt.ylabel("$X_2$")
Text(0, 0.5, '$X_2$')

使用奇异值分解抽取特征
SVD(Singular Value Decomposition)奇异值分解
SVD 可以用较低的维数来找到原始数据的最佳近似,而且 SVD 直接作用原始数据矩阵
SVD 是一种双模因子分析,过程是从一个具体两类实体的任意矩阵开始。
from scipy.linalg import svd
data = load_iris()
x = data['data']
y = data['target']
x_s = scale(x,with_mean=True,with_std=True,axis=0)
U,S,V = svd(x_s,full_matrices=False)
x_t = U[:,:2]
plt.close('all')
plt.figure(1)
plt.scatter(x_t[:,0],x_t[:,1],c=y)
plt.xlabel("Component 1")
plt.ylabel('Component 2')
plt.show()

NMF(Non-negative Matrix Factorization)
之前对数据降维都是采用矩阵分解技术,现在我们来讨论更有趣的技术,从协同过滤角度出发进行降维,这种降维算法通常用于推荐系统
import numpy as np
from collections import defaultdict
from sklearn.decomposition import NMF
import matplotlib.pyplot as plt
为了解释 NMF 我们的准备一个模型的推荐问题。我们通过用户和电影间关系进行推荐,如何将用户和电影建立关系。每一个用户对一些电影做出自己评价,我们将预测他们如何对尚未评价的电影进行评价。这里假设用户没有观看过他们未给出评价的电影。
ratings =[
[5.0,5.0,4.5,4.5,5.0,3.0,2.0,2.0,0.0,0.0],
[4.2,4.7,5.0,3.7,3.5,0.0,2.7,2.0,1.9,0.0],
[2.5,4.7,5.0,3.7,3.5,0.0,2.7,2.0,1.9,0.0],
]
movie_dict = {
1:"Star Wars",
2:"Matrix",
3:"Inception",
4:"The hobbit",
6:"Guns of Navarone"
}
[[5.0, 5.0, 4.5, 5.0, 3.0, 2.0, 0.0, 0.0]]
网友评论