利用主成分分析(PCA)簡化數據


 

一.PCA基礎

線性映射(或線性變換),簡單的來說就是將高維空間數據投影到低維空間上,那么在數據分析上,我們是將數據的主成分(包含信息量大的維度)保留下來,忽略掉對數據描述不重要的成分。即將主成分維度組成的向量空間作為低維空間,將高維數據投影到這個空間上就完成了降維的工作。

 

在 PCA中,數據從原來的坐標系轉換到了新的坐標系,新坐標系的選擇是由數據本身決定的。第一個新坐標軸選擇的是原始數據中方差最大的方向,第二個新坐標軸的選擇和第一個坐標軸正交且具有最大方差的方向。該過程一直重復,重復次數為原始數據中特征的數目。我們會發現,大部分方差都包含在最前面的幾個新坐標軸中。因此,我們可以忽略余下的坐標軸,即對數據進行了降維處理。

 

工作原理:

①找出第一個主成分的方向,也就是數據 方差最大 的方向。

②找出第二個主成分的方向,也就是數據 方差次大 的方向,並且該方向與第一個主成分方向正交(果是二維空間就叫垂直)。

③通過這種方式計算出所有的主成分方向。

④通過數據集的協方差矩陣及其特征值分析,我們就可以得到這些主成分的值。

⑤一旦得到了協方差矩陣的特征值和特征向量,我們就可以保留最大的 N 個特征。這些特征向量也給出了 N 個最重要特征的真實結構,我們就可以通過將數據乘上這 N 個特征向量 從而將它轉換到新的空間上。

 

二.PCA在NumPy中的實現

def loadDataSet(fileName, delim='\t') :
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    dataArr = [map(float, line) for line in stringArr]
    return mat(dataArr)

# dataMat: 用於進行PCA操作的數據集
# topNfeat: 可選參數,即應用的N個特征。
# 若不指定topNfeat的值,那么函數就會返回前9999999個特征,或者原始數據中的全部特征
def pca(dataMat, topNfeat=9999999) :
    # 計算平均值
    meanVals = mean(dataMat, axis=0)
    # 減去原始數據的平均值
    meanRemoved = dataMat - meanVals
    # 計算協方差矩陣及其特征值
    covMat = cov(meanRemoved, rowvar=0)
    eigVals, eigVects = linalg.eig(mat(covMat))
    # 利用argsort()函數對特征值進行從小到大的排序,根據特征值排序結果的逆序就可以得到
    # topNfeat個最大的特征向量
    eigValInd = argsort(eigVals)
    eigValInd = eigValInd[:-(topNfeat+1):-1]
    # 這些特征向量將構成后面對數據進行轉換的矩陣,該矩陣則利用N個特征將原始數據轉換到新空間中
    redEigVects = eigVects[:, eigValInd]
    lowDDataMat = meanRemoved * redEigVects
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat

注意:與python2有點不同,python3要加list

 

>>> dataMat = pca.loadDataSet('testSet.txt')
>>> lowDMat, reconMat = pca.pca(dataMat, 1)
>>> import numpy
>>> numpy.shape(lowDMat)
(1000, 1)
>>> import matplotlib
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0], marker='^', s=90)
<matplotlib.collections.PathCollection object at 0x000002449DCFA2B0>
>>> ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker='o', s=50, c='red')
<matplotlib.collections.PathCollection object at 0x000002449DCFABE0>
>>> plt.show()

 得到如圖

三.利用PCA對半導體制造數據降維

 

def replaceNaNWithMean():
    #解析數據
    datMat=loadDataSet('secom.data',' ')
   #獲取特征維度     
    numFeat=shape(datMat)[1]
    #遍歷數據集每一個維度
    for i in range(numFeat):
        #利用該維度所有非NaN特征求取均值
        meanVal=mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i])
        #將該維度中所有NaN特征全部用均值替換
        datMat[nonzero(isnan(datMat[:,i].A))[0],i]=meanVal
    return datMat


dataMat=replaceNaNWithMean()
meanVals=mean(dataMat,axis=0)
meanRemoved=dataMat-meanVals
conMat=cov(meanRemoved,rowvar=0)
eigVals,eigVects=linalg.eig(mat(covMat))
eigVects

結果出現錯誤

錯誤有待解決,也希望知道原因的小伙伴能告知一下,非常感謝


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM