之前我经常使用PCA,但是我发现我没有很懂PCA,这次重新学习机器学习,我想想彻彻底底地搞懂一下,网上也看了很多的资料,似乎对其的理解有了更加进一步的认识。我感觉需要从以下四块来认识PCA。
1. PCA是干什么? 就是说PCA解决了什么问题?
2.PCA的数学原理是什么?
3.PCA用python 什么包调用比较方便,理解每个参数的意义?
4.用PCA来实战一个例子?
以上是我的学习思路,PCA-Principal Component Analysis-主成分分析 也就是机器学习中的无监督学习
PCA干什么用的
这个干什么用,网上自然有很多的说明,主要就是降维,我以前一直不明白,降低纬度以后,每个纬度代表什么,其实不用这么死理解,需要换个思路,从主成分角度+协方差的角度去思考这个问题,我相当于是建立了一个新的N维坐标,并没有具体的含义,但是按照eigenValue 从大到小排序,使得前几个纬度可以解释大部分的方差变异。
有啥用,就是减少了数据量,方便后面计算,同时可以看到在前几个主成分上,所有样本的分布情况,这样可以看个分类。
#PCA的数学原理是什么?
这里涉及了矩阵的分解,SVD,之前有详细的推导,大家也可以看网上有很多的解释,我主要想说的,可以用当时我考研复习矩阵的时候的一个想法来理解,就是这个其实是矩阵本身的一个性质,所以叫无监督学习,自己学习,推导出自己的一个性质,自己搞自己的感觉,没有外力的加入。
看下面这个理解就很OK
https://www.cnblogs.com/sweetyu/p/5085798.html
https://blog.csdn.net/u012421852/article/details/80458340
https://zhuanlan.zhihu.com/p/37777074
#PCA用python 什么包调用比较方便,理解每个参数的意义?
这里简单地介绍一下sklearn.decomposition.PCA 做个包
可以参考这些解说
https://www.cnblogs.com/pinard/p/6243025.html
或者说,直接看原包的解释
https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html
from sklearn.decomposition import PCA
调入包
n_components : int, float, None or string
主成分的个数
copy : bool (default True)
要不要覆盖原始数据
whiten : bool, optional (default False)
判断是否进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化,让方差都为1.对于PCA降维本身来说,一般不需要白化。如果你PCA降维后有后续的数据处理动作,可以考虑白化。默认值是False,即不进行白化。
svd_solver : string {‘auto’, ‘full’, ‘arpack’, ‘randomized’}
指定奇异值分解SVD的方法
也可以参考这个
https://blog.csdn.net/u012162613/article/details/42192293
我们来看看官网的例子
>>> import numpy as np
>>> from sklearn.decomposition import PCA
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) # 这是一个矩阵,未经训练的数据
>>> pca = PCA(n_components=2) # 设定 主成分取两个
>>> pca.fit(X) # 拿X训练
PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
svd_solver='auto', tol=0.0, whiten=False) # 不覆盖原始数据 这个时候就会训练得到 主成分+向量(训练出来的)
>>> print(pca.explained_variance_ratio_) # 每个主成分的解释大小
[0.9924... 0.0075...]
>>> print(pca.singular_values_) # 每个主成分
[6.30061... 0.54980...]
fit_transform(X)
用X来训练PCA模型,同时返回降维后的数据。
newX=pca.fit_transform(X),newX就是降维后的数据。
inverse_transform()
将降维后的数据转换成原始数据,X=pca.inverse_transform(newX)
transform(X)
将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。
#来个实战的例子吧
这个我也是网上看了这些个例子,慢慢理解了上面的知识点
https://blog.csdn.net/qq_38825002/article/details/81356377
就是把含有4个纬度的降维到2个纬度
import matplotlib.pyplot as plt # 可视化
from sklearn.decomposition import PCA #PCA的包
from sklearn.datasets import load_iris
data=load_iris() # 导入数据
x = data.data
y = data.target
我们来看看x
也就是数据集 4维数据
y 的话是分类
y=data.target
x=data.data
pca=PCA(n_components=2) # 手动设置降维到2维
reduced_x=pca.fit_transform(x) #对X进行降维 然后放到新的reduced_x 中
看看reduced_x 只有两个维度了
然后画个图看看分成了几类
red_x,red_y=[],[]
blue_x,blue_y=[],[]
green_x,green_y=[],[]
for i in range(len(reduced_x)):
if y[i] ==0: # 这个y 相当于个体,只是提前已经分类好了
red_x.append(reduced_x[i][0]) # 把第一维度数值放入
red_y.append(reduced_x[i][1]) # 把第二维度数值放入
elif y[i]==1:
blue_x.append(reduced_x[i][0])
blue_y.append(reduced_x[i][1])
else:
green_x.append(reduced_x[i][0])
green_y.append(reduced_x[i][1])
#可视化
plt.scatter(red_x,red_y,c='r',marker='x')
plt.scatter(blue_x,blue_y,c='b',marker='D')
plt.scatter(green_x,green_y,c='g',marker='.')
plt.show()
可视化的结果
我现在大概了解PCA了,还有很多需要学的,但是可以使用PCA进行降维和简单的分类了。
最后,PCA也是有过程的只是这个包里面帮你做了,其实可以用python从头搭建的。
主要分为以下这几步骤:
- 每个特点求平均值
- 标准化,就是每个数据减去自己特点的标准值
- 计算这个矩阵的主成分和特征向量
- 对主成分排序
- 选择需要的主成分
- 获得新坐标下的投影矩阵
原始数据是一个矩阵
经过训练得到 主成分+特征向量(参数)
然后筛选过主成分的个数之后,获得余下的特征向量和主成分
然后把之前那个矩阵数据投影到新的坐标上(就是刚刚余下的特征向量),获得与余下的特征向量和主成分个数一样(降维之后的维度n)的新坐标,这些坐标的排列与按照主成分大小排列的,所以相当于每个个体,有n个维度的特征。
这篇也讲的很棒
https://www.cnblogs.com/mikewolf2002/p/3429711.html
我觉得还是要再实战去理解
先推导了一下
再试了试,是可以
import numpy as np
from sklearn.decomposition import PCA
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
# 6行 2列 数据只有2维度 2个属性 相当于 6个个体 2个属性
print(X)
pca = PCA(n_components=1) # 设置PCA的个数 PCA是一个对象
pca.fit(X) # 用 X 训练
print(pca.explained_variance_ratio_) # 解释方差的大小
print(pca.singular_values_) # 主成分的内容
Y = pca.fit_transform(X) # 正交变换与投影
print(Y)
Z1 = np.array([[-3, -2], [1, 90]]) # 用训练好的模型降维度
Z = pca.transform(Z1)
print(Z)
结果
[[-1 -1]
[-2 -1]
[-3 -2]
[ 1 1]
[ 2 1]
[ 3 2]]
[0.99244289]
[6.30061232]
[[ 1.38340578]
[ 2.22189802]
[ 3.6053038 ]
[-1.38340578]
[-2.22189802]
[-3.6053038 ]]
[[ 3.6053038 ]
[-49.88071091]]