首页 » 机器学习实战 » 机器学习实战全文在线阅读

《机器学习实战》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))  

现在,我们可以观察一下特征值的结果:

>>> eigValsarray([ 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个主成分所占的方差百分比

主 成 分方差百分比(%)累积方差百分比(%)159.259.2224.183.439.292.542.394.851.596.360.596.8200.0899.3

于是,我们可以知道在数据集的前面多个主成分中所包含的信息量。我们可以尝试不同的截断值来检验它们的性能。有些人使用能包含90%信息量的主成分数量,而其他人使用前20个主成分。我们无法精确知道所需要的主成分数目,必须通过在实验中取不同的值来确定。有效的主成分数目则取决于数据集和具体应用。

上述分析能够得到所用到的主成分数目,然后我们可以将该数目输入到PCA算法中,最后得到约简后数据就可以在分类器中使用了。