**本文章才用的是鸢尾花数据进行检测,对其进行降维操作,通过使用PCA 对数据的特征进行降维,从而选择出合适的属性值**
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# decomposition:降解
# 降解,化学变化降解之后得到数据,原来的数据不太一样
# 属性变了
# pca将数据属性变少,少量的数据代表原来的比较多的数据
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn import datasets
from sklearn.model_selection import train_test_split
X,y = datasets.load_iris(True)
# 降维 找出最合适的两个属性
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
X_pca[:10]
array([[-2.68412563, 0.31939725],
[-2.71414169, -0.17700123],
[-2.88899057, -0.14494943],
[-2.74534286, -0.31829898],
[-2.72871654, 0.32675451],
[-2.28085963, 0.74133045],
[-2.82053775, -0.08946138],
[-2.62614497, 0.16338496],
[-2.88638273, -0.57831175],
[-2.6727558 , -0.11377425]])
可以看出最后两个属性对于元数据来说最重要,下面我们看他是如何计算出来的
PCA原理
1、去中心化
B = X - X.mean(axis = 0)
B[:5]
array([[-0.74333333, 0.44266667, -2.358 , -0.99933333],
[-0.94333333, -0.05733333, -2.358 , -0.99933333],
[-1.14333333, 0.14266667, -2.458 , -0.99933333],
[-1.24333333, 0.04266667, -2.258 , -0.99933333],
[-0.84333333, 0.54266667, -2.358 , -0.99933333]])
2、协方差的求解
# 方差是协方差特殊形式
# 协方差矩阵 下面两种方法一样
V = np.cov(B,rowvar=False,bias = True)
# V = np.cov(B.T,bias = True)
3、协方差矩阵的特征值和特征向量
这里使用numpy中的linalg中内置方法eig来求解举证的特征值和特征向量!!
# 特征值和特征向量矩阵的概念
eigen,ev = np.linalg.eig(V)
display(eigen,ev)
array([4.20005343, 0.24105294, 0.0776881 , 0.02367619])
array([[ 0.36138659, -0.65658877, -0.58202985, 0.31548719],
[-0.08452251, -0.73016143, 0.59791083, -0.3197231 ],
[ 0.85667061, 0.17337266, 0.07623608, -0.47983899],
[ 0.3582892 , 0.07548102, 0.54583143, 0.75365743]])
4、降维标准
# 百分比,计算各特征值,占权重,累加可以
cond = (eigen/eigen.sum()).cumsum() >= 0.98
index = cond.argmax()
vector = ev[:,:index + 1]
5、进行矩阵运算
pca_result = B.dot(vector)
# pca_result 这个结果可以看出,他底层的正负值发生了一定的改变,这一步是为了让符号对应,这个是剖析源代码得出来的!欣然接受就可以哈哈!!
pca_result[:,1::2]*=-1
pca_result[:5]
array([[-2.68412563, 0.31939725, -0.02791483],
[-2.71414169, -0.17700123, -0.21046427],
[-2.88899057, -0.14494943, 0.01790026],
[-2.74534286, -0.31829898, 0.03155937],
[-2.72871654, 0.32675451, 0.09007924]])
X_pca[:5]
可以看出通过我们手动计算之后和它用算法的得出的结果保持一致,这就很完美啦,主要就是进行了以上几个步骤
下面是一个小小的拓展:
pca = PCA(n_components=2,whiten=True)
X_pca = pca.fit_transform(X)
这里会有另外一个参数whiten=True表示是否进行标准化,如果等于True就会在原来的基础上使用下面的标准化操作即可,也是很方便,容易理解
6、标准化
pca_result2 = (pca_result -pca_result.mean(axis = 0))/pca_result.std(axis = 0)
pca_result2[:5]
array([[-1.30971087, 0.65054141, -0.10015155],
[-1.32435711, -0.36051227, -0.75509418],
[-1.40967409, -0.29522986, 0.06422173],
[-1.33958163, -0.64830449, 0.11322729],
[-1.33146886, 0.66552653, 0.32318222]])
验证降维的数据,准确
*这里是采用的逻辑斯蒂回归算法进行的验证,准确率还是很高的~~~~*
import warnings
warnings.filterwarnings('ignore')
# 降维的数据,准确率是93%
lr = LogisticRegression()
X_train,X_test,y_train,y_test = train_test_split(X_pca,y,test_size = 0.2,random_state = 1024)
lr.fit(X_train,y_train)
lr.score(X_test,y_test)
0.9
X.shape
(150, 4)
# 原数据准确率是96%
lr = LogisticRegression()
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state = 1024)
lr.fit(X_train,y_train)
lr.score(X_test,y_test)
0.9666666666666667
# 原数据准确率是96%
lr = LogisticRegression()
X_train,X_test,y_train,y_test = train_test_split(pca_result2,y,test_size = 0.2,random_state = 1024)
lr.fit(X_train,y_train)
lr.score(X_test,y_test)
0.8333333333333334
# 原数据准确率是96%
lr = LogisticRegression()
X_train,X_test,y_train,y_test = train_test_split(X_pca,y,test_size = 0.2,random_state = 1024)
lr.fit(X_train,y_train)
lr.score(X_test,y_test)
0.9