讀古今文學網 > 機器學習實戰 > 13.3 示例:利用PCA對半導體製造數據降維 >

13.3 示例:利用PCA對半導體製造數據降維

半導體是在一些極為先進的工廠中製造出來的。工廠或製造設備不僅需要花費上億美元,而且還需要大量的工人。製造設備僅能在幾年內保持其先進性,隨後就必須更換了。單個集成電路的加工時間會超過一個月。在設備生命期有限,花費又極其巨大的情況下,製造過程中的每一秒鐘都價值巨大。如果製造過程中存在瑕疵,我們就必須盡早發現,從而確保寶貴的時間不會花費在缺陷產品的生產上。

一些工程上的通用解決方案是通過早期測試和頻繁測試來發現有缺陷的產品,但仍然有一些存在瑕疵的產品通過了測試。如果機器學習技術能夠用於進一步減少錯誤,那麼它就會為製造商節省大量的資金。

接下來我們將考察面向上述任務中的數據集,而它也比前面使用的數據集更大,並且包含了許多特徵。具體地講,它擁有590個特徵1。我們看看能否對這些特徵進行降維處理。讀者也可以通過http://archive.ics.uci.edu/ml/machine-learning-databases/secom/得到該數據集。

1 SECOM Data Set retrieved from the UCI Machine Learning Repository: http://archive.ics.uci.edu/ml/datasets/SECOMon June 1, 2011.

該數據包含很多的缺失值。這些缺失值是以NaN(Not a Number的縮寫)標識的。對於這些缺失值,我們有一些處理辦法(參考第5章)。在590個特徵下,幾乎所有樣本都有NaN,因此去除不完整的樣本不太現實。儘管我們可以將所有的NaN替換成0,但是由於並不知道這些值的意義,所以這樣做是個下策。如果它們是開氏溫度,那麼將它們置成0這種處理策略就太差勁了。下面我們用平均值來代替缺失值,平均值根據那些非NaN得到。

將下列代碼添加到pca.py文件中。

程序清單13-2 將NaN替換成平均值的函數

def replaceNanWithMean:
    datMat = loadDataSet(\'secom.data\', \' \')
    numFeat = shape(datMat)[1]
    for i in range(numFeat):
        meanVal = mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i])
        #❶ 計算所有非NaN的平均值
        datMat[nonzero(isnan(datMat[:,i].A))[0],i] = meanVal
    #❷ 將所有NaN置為平均值
    return datMat  
  

上述代碼首先打開了數據集並計算出了其特徵的數目,然後再在所有的特徵上進行循環。對於每個特徵,首先計算出那些非NaN值的平均值❶。然後,將所有NaN替換為該平均值❷。

我們已經去除了所有NaN,接下來考慮在該數據集上應用PCA。首先確認所需特徵和可以去除特徵的數目。PCA會給出數據中所包含的信息量。需要特別強調的是,數據(data)和信息(information)之間具有巨大的差別。數據指的是接受的原始材料,其中可能包含噪聲和不相關信息。信息是指數據中的相關部分。這些並非只是抽像概念,我們還可以定量地計算數據中所包含的信息並決定保留的比例。

下面看看該如何實現這一點。首先,利用程序清單13-2中的代碼將數據集中所有的NaN替換成平均值:

dataMat = pca.replaceNanWithMean
  

接下來從pca函數中借用一些代碼來達到我們的目的,之所以借用是因為我們想瞭解中間結果而非最後輸出結果。首先調用如下語句去除均值:

meanVals = mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals 
  

然後計算協方差矩陣:

covMat = cov(meanRemoved, rowvar=0) 
  

最後對該矩陣進行特徵值分析:

eigVals,eigVects = linalg.eig(mat(covMat))
  

現在,我們可以觀察一下特徵值的結果:

>>> eigVals
array([ 5.34151979e+07, 2.17466719e+07, 8.24837662e+06,
        2.07388086e+06, 1.31540439e+06, 4.67693557e+05,
        2.90863555e+05, 2.83668601e+05, 2.37155830e+05,
        2.08513836e+05, 1.96098849e+05, 1.86856549e+05,
                                      .
                                      .
                                      .
        0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
        0.00000000e+00, 0.00000000e+00])
  

我們會看到一大堆值,但是其中的什麼會引起我們的注意?我們會發現其中很多值都是0嗎?實際上,其中有超過20%的特徵值都是0。這就意味著這些特徵都是其他特徵的副本,也就是說,它們可以通過其他特徵來表示,而本身並沒有提供額外的信息。

接下來,我們瞭解一下部分數值的數量級。最前面15個值的數量級大於105,實際上那以後的值都變得非常小。這就相當於告訴我們只有部分重要特徵,重要特徵的數目也很快就會下降。

最後,我們可能會注意到有一些小的負值,它們主要源自數值誤差應該四捨五入成0。

在圖13-4中已經給出了總方差的百分比,我們發現,在開始幾個主成分之後,方差就會迅速下降。

圖13-4 前20個主成分佔總方差的百分比。可以看出,大部分方差都包含在前面的幾個主成分中,捨棄後面的主成分並不會損失太多的信息。如果保留前6個主成分,則數據集可以從590個特徵約簡成6個特徵,大概實現了100:1的壓縮

表13-1給出了這些主成分所對應的方差百分比和累積方差百分比。瀏覽「累積方差百分比(%)」這一列就會注意到,前六個主成分就覆蓋了數據96.8%的方差,而前20個主成分覆蓋了99.3%的方差。這就表明了,如果保留前6個而去除後584個主成分,我們就可以實現大概100:1的壓縮比。另外,由於捨棄了噪聲的主成分,將後面的主成分去除便使得數據更加乾淨。

表13-1 半導體數據中前7個主成分所佔的方差百分比

主 成 分 方差百分比(%) 累積方差百分比(%) 1 59.2 59.2 2 24.1 83.4 3 9.2 92.5 4 2.3 94.8 5 1.5 96.3 6 0.5 96.8 20 0.08 99.3

於是,我們可以知道在數據集的前面多個主成分中所包含的信息量。我們可以嘗試不同的截斷值來檢驗它們的性能。有些人使用能包含90%信息量的主成分數量,而其他人使用前20個主成分。我們無法精確知道所需要的主成分數目,必須通過在實驗中取不同的值來確定。有效的主成分數目則取決於數據集和具體應用。

上述分析能夠得到所用到的主成分數目,然後我們可以將該數目輸入到PCA算法中,最後得到約簡後數據就可以在分類器中使用了。