1. 程式人生 > >機器學習:PCA技術以及

機器學習:PCA技術以及

一:引言
  降維是對資料高維度特徵的一種預處理方法。降維是將高維度的資料保留下最重要的一些特徵,去除噪聲和不重要的特徵,從而實現提升資料處理速度的目的。在實際的生產和應用中,降維在一定的資訊損失範圍內,可以為我們節省大量的時間和成本。降維也成為了應用非常廣泛的資料預處理方法。
  降維具有如下一些優點:
(1)使得資料集更易使用
(2)降低演算法的計算開銷
(3)去除噪聲
(4)使得結果容易理解
  PCA(principal Component Analysis),即主成分分析方法,是一種使用最廣泛的資料壓縮演算法。在PCA中,資料從原來的座標系轉換到新的座標系,由資料本身決定。轉換座標系時,以方差最大的方向作為座標軸方向,因為資料的最大方差給出了資料的最重要的資訊。第一個新座標軸選擇的是原始資料中方差最大的方法,第二個新座標軸選擇的是與第一個新座標軸正交且方差次大的方向。重複該過程,重複次數為原始資料的特徵維數。
  通過這種方式獲得的新的座標系,我們發現,大部分方差都包含在前面幾個座標軸中,後面的座標軸所含的方差幾乎為0,。於是,我們可以忽略餘下的座標軸,只保留前面的幾個含有絕不部分方差的座標軸。事實上,這樣也就相當於只保留包含絕大部分方差的維度特徵,而忽略包含方差幾乎為0的特徵維度,也就實現了對資料特徵的降維處理。
  那麼,我們如何得到這些包含最大差異性的主成分方向呢?事實上,通過計算資料矩陣的協方差矩陣,然後得到協方差矩陣的特徵值及特徵向量,選擇特徵值最大(也即包含方差最大)的N個特徵所對應的特徵向量組成的矩陣,我們就可以將資料矩陣轉換到新的空間當中,實現資料特徵的降維(N維)。
  既然,說到了協方差矩陣,那麼這裡就簡單說一下方差和協方差之間的關係,首先看一下均值,方差和協方差的計算公式:
  在這裡插入圖片描述


  由上面的公式,我們可以得到一下兩點區別:
(1)方差的計算公式,我們知道方差的計算是針對一維特徵,即針對同一特徵不同樣本的取值來進行計算得到;而協方差則必須要求至少滿足二維特徵。可以說方差就是協方差的特殊情況。 
(2)方差和協方差的除數是n-1,這樣是為了得到方差和協方差的無偏估計。具體推導過程可以參見博文:http://blog.csdn.net/maoersong/article/details/21823397
二:PCA演算法實現
  將資料轉換為只保留前N個主成分的特徵空間的虛擬碼如下所示:
`

去除平均值
計算協方差矩陣
計算協方差矩陣的特徵值和特徵向量
將特徵值排序
保留前N個最大的特徵值對應的特徵向量
將資料轉換到上面得到的N個特徵向量構建的新空間中(實現了特徵壓縮)`
#匯入numpy庫
from numpy import *

#解析文字資料函式
#@filename 檔名txt
#@delim 每一行不同特徵資料之間的分隔方式,預設是tab鍵'\t'
def loadDataSet(filename,delim='\t')
    #開啟文字檔案
    fr=open(filename)
    #對文字中每一行的特徵分隔開來,存入列表中,作為列表的某一行
    #行中的每一列對應各個分隔開的特徵
    stringArr=[line.strip().split(delim) for line in fr.readlines()]
    #利用map()函式,將列表中每一行的資料值對映為float型
    datArr=[map(float.line)for line in stringArr]
    #將float型資料值的列表轉化為矩陣返回
    return mat(datArr)

#pca特徵維度壓縮函式
#@dataMat 資料集矩陣
#@topNfeat 需要保留的特徵維度,即要壓縮成的維度數,預設4096    
def pca(dataMat,topNfeat=4096):
    #求資料矩陣每一列的均值
    meanVals=mean(dataMat,axis=0)
    #資料矩陣每一列特徵減去該列的特徵均值
    meanRemoved=dataMat-meanVals
    #計算協方差矩陣,除數n-1是為了得到協方差的無偏估計
    #cov(X,0) = cov(X) 除數是n-1(n為樣本個數)
    #cov(X,1) 除數是n
    covMat=cov(meanRemoved,rowvar=0)
    #計算協方差矩陣的特徵值及對應的特徵向量
    #均儲存在相應的矩陣中
    eigVals,eigVects=linalg.eig(mat(conMat))
    #sort():對特徵值矩陣排序(由小到大)
    #argsort():對特徵值矩陣進行由小到大排序,返回對應排序後的索引
    eigValInd=argsort(eigVals)
    #從排序後的矩陣最後一個開始自下而上選取最大的N個特徵值,返回其對應的索引
    eigValInd=eigValInd[:-(topNfeat+1):-1]
    #將特徵值最大的N個特徵值對應索引的特徵向量提取出來,組成壓縮矩陣
    redEigVects=eigVects[:,eigValInd]
    #將去除均值後的資料矩陣*壓縮矩陣,轉換到新的空間,使維度降低為N
    lowDDataMat=meanRemoved*redEigVects
    #利用降維後的矩陣反構出原資料矩陣(用作測試,可跟未壓縮的原矩陣比對)
    reconMat=(lowDDataMat*redEigVects.T)+meanVals
    #返回壓縮後的資料矩陣即該矩陣反構出原始資料矩陣
    return lowDDataMat,reconMat

上述降維過程,首先根據資料矩陣的協方差的特徵值和特徵向量,得到最大的N個特徵值對應的特徵向量組成的矩陣,可以稱之為壓縮矩陣;得到了壓縮矩陣之後,將去均值的資料矩陣乘以壓縮矩陣,就實現了將原始資料特徵轉化為新的空間特徵,進而使資料特徵得到了壓縮處理。
  當然,我們也可以根據壓縮矩陣和特徵均值,反構得到原始資料矩陣,通過這樣的方式可以用於除錯和驗證。
  下圖是通過matplotlib將原始資料點(三角形點)和第一主成分點(圓形點)繪製出來的結果。顯然,第一主成分點佔據著資料最重要的資訊。

import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(lll)
#三角形表示原始資料點
ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],\
                    marker='^',s=90)
#圓形點表示第一主成分點,點顏色為紅色
ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0]\, marker='o',s=90,c='red')

在這裡插入圖片描述
三,示例:PCA對半導體資料進行降維
  我們知道,像積體電路這樣的半導體,成本非常昂貴。如果能在製造過程中儘早和儘快地檢測出是否出現瑕疵,將可能為企業節省大量的成本和時間。那麼,我們在面對大規模和高維度資料集時,顯然計算損耗會很大,無疑會非常耗時。所以,如果利用PCA等降維技術將高維的資料特徵進行降維處理,保留那些最重要的資料特徵,捨棄那些可以忽略的特徵,將大大加快我們的資料處理速度和計算損耗,為企業節省不小的時間和成本。
1 資料缺失值的問題
  顯然,資料集中可能會包含很多缺失值,這些缺失值是以NaN進行標識的。那麼如何對待這些缺失值呢?如果存在大量的樣本存在缺失值,顯然選擇將這些有缺失值得樣本丟棄不可取;此外,由於並不知道這些值的意義,選擇將缺失值替換為0也不是一個很好的決定。所以,這裡我們選擇將資料集中的特徵缺失值,用資料集中該維度所有非NaN特徵的均值進行替換。相比之下,採用均值替換的方法在這裡是一個相對較好的選擇。

#缺失值處理函式
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

這樣,我們就去除了所有NaN特徵,接下來就可以對資料集利用PCA演算法進行降維處理了。
2 PCA降維
  那麼我們如果確定需要保留哪些重要特徵呢?PCA函式可以給出資料所包含的資訊量,然後通過定量的計算資料中所包含的資訊決定出保留特徵的比例。下面是具體程式碼:

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

在這裡插入圖片描述
 從上面的特徵值結果,我們可以看到如下幾個重要資訊:
(1)裡面有很多值都是0,這意味著這些特徵都是其他特徵的副本,都可以通過其他特徵來表示,其本身沒有提供額外的資訊。
(2)可以看到最前面的15個特徵值得數量級都大於105,而後面的特徵值都變得非常小。這表明,所有特徵中只有部分特徵是重要特徵。
  下圖示出了資料集前20個主成分佔總方差的百分比:
  在這裡插入圖片描述
可以看出,資料的絕大部分方差都包含在前面的幾個主成分中,捨棄後面的主成分並不會損失太多的資訊。如果只保留前面幾個最重要的主成分,那麼在保留了絕大部分資訊的基礎上,可以將資料集特徵壓縮到一個非常低的程度,顯然大大提高了計算效率。
  下表是資料集前20個主成分所佔的總方差百分比,以及累計方差百分比:
在這裡插入圖片描述
由上表可以看出,前六個主成分覆蓋了資料96.8%的方差,前二十個主成分覆蓋了99.3%的方差。這表明,通過特徵值分析,我們可以確定出需要保留的主成分及其個數,在資料集整體資訊(總方差)損失很小的情況下,我們可以實現資料的大幅度降維。
  一旦,通過特徵值分析知道了需要保留的主成分個數,那麼我們就可以通過pca函式,設定合適的N值,使得函式最終將資料特徵降低到最佳的維度。

四,總結
(1)降維是一種資料集預處理技術,往往在資料應用在其他演算法之前使用,它可以去除掉資料的一些冗餘資訊和噪聲,使資料變得更加簡單高效,提高其他機器學習任務的計算效率。
(2)pca可以從資料中識別主要特徵,通過將資料座標軸旋轉到資料角度上那些最重要的方向(方差最大);然後通過特徵值分析,確定出需要保留的主成分個數,捨棄其他主成分,從而實現資料的降維。
原文連線:https://www.cnblogs.com/zy230530/p/7074215.html