PCA的用處:找出反應數據中最大變差的投影(就是拉的最開)。
在減少需要分析的指標同時,盡量減少原指標包含信息的損失,以達到對所收集數據進行全面分析的目的
但是什么時候信息保留的最多呢?具體一點?
首先:去中心化(把坐標原點放到數據中心,如上圖所示)
然后,找坐標系(找到方差最大的方向)
問題是:怎么找到方差最大的方向呢????????
一.引子
1.使用矩陣可以進行數據的線性變換(數據的拉伸)
2.使用矩陣可以進行數據的線性變換(數據的旋轉)
3.結合起來兩種操作
拉伸決定了方差最大的方向是橫或者縱
旋轉決定了方差最大的方向的角度
怎么求R?
協方差矩陣的特征向量就是R
二.數學原理:
三.PCA流程圖:
PCA與SVD的聯系:
四.例子:
五.代碼:
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 13 11:12:24 2020@author: pc① 對原數據集零均值化。代碼是:meanRemoved = dataMat - mean(dataMat,axis=0)② 求出均值化X的協方差矩陣:公式是:Cov(X)=\frac{1}{m-1}X^{T}X,代碼是:covMat = cov(meanRemoved,rowvar=0)③ 求這個協方差矩陣的特征值,特征向量,代碼是:eigVals, eigVects = linalg.eig(mat(covMat))④ 把這些特征值按從大到小排列,返回特征值的下標,代碼是:eigValInd = argsort(-eigVals)⑤ 選出前topNfeat個特征值,返回這些選中的特征值的下標,并根據下標從特征向量矩陣eigVects中取出這些選中的特征向量組成矩陣P,這就是我們要找的變換矩陣P,代碼是:redEigVects = eigVects[:,eigValInd[:topNfeat] ]⑥ 返回降維后的數據,公式是:Y=X?P,代碼是:lowDDataMat = meanRemoved * redEigVects⑦ 原數據映射到新的空間中。公式是:X^{'}=Y\cdot P^{T}+mean,代碼是:reconMat = (lowDDataMat * redEigVects.T) + meanValues
"""import numpy as np
import matplotlib.pyplot as pltdef pca(dataMat, topNfeat = 999999):meanValues = np.mean(dataMat,axis=0) # 豎著求平均值,數據格式是m×nmeanRemoved = dataMat - meanValues # 0均值化 m×n維covMat = np.cov(meanRemoved,rowvar=0) # 每一列作為一個獨立變量求協方差 n×n維eigVals, eigVects = np.linalg.eig(np.mat(covMat)) # 求特征值和特征向量 eigVects是n×n維eigValInd = np.argsort(-eigVals) # 特征值由大到小排序,eigValInd十個arrary數組 1×n維eigValInd = eigValInd[:topNfeat] # 選取前topNfeat個特征值的序號 1×r維print(eigValInd)redEigVects = eigVects[:,eigValInd] # 把符合條件的幾列特征篩選出來組成P n×r維lowDDataMat = meanRemoved * redEigVects # 矩陣點乘篩選的特征向量矩陣 m×r維 公式Y=X*PreconMat = (lowDDataMat * redEigVects.T) + meanValues # 轉換新空間的數據 m×n維return lowDDataMat, reconMatdef drawPoints(dataset1,dataset2): # 畫圖,dataset1是沒降維的數據,dataset2是數據映射到新空間的數據fig = plt.figure()ax1 = fig.add_subplot(211)ax2 = fig.add_subplot(212)ax1.scatter(dataset1[:,0],dataset1[:,1],marker='s',s=5,color='red')dataset2 = np.array(dataset2)ax2.scatter(dataset2[:,0],dataset2[:,1],s=5,color='blue')plt.show()if __name__ == '__main__':dataSetList = []fr = open('pca_data_set1.txt')for row in fr.readlines():cur_line = row.strip().split('\t')proce_line = list(map(float,cur_line))dataSetList.append(proce_line)dataSetList = np.array(dataSetList)data = dataSetListproccess_data, reconMat = pca(data,topNfeat = 1)drawPoints(data,reconMat)