天天看點

機器學習-PCA降維

一、首先先問一個問題:為什麼要進行降維操作呢?

機器學習-PCA降維

降維的主要方法有:

機器學習-PCA降維

二、主成分分析PCA

機器學習-PCA降維

2.PCA的python 實作過程

機器學習-PCA降維

有人會問為什麼要去均值呢?

我們進行PCA降維的主要目的是為了得到方差最大的前N個特征,為了減少計算量,我們第一步就将資料所特征的均值變為0,來達到取出均值的目的。

在學習的過程中首先我們根據算法的實作過程一步步進行代碼實作,然後再封裝成函數的形式,這樣就有助于調用
           

代碼實作過程如下所示

首先先導入資料集以及需要用到的包

#導入包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#導入資料
testSet = pd.read_table('testSet.txt',header=None)
testSet.head()#該資料集是一個隻有兩個特征的資料
#可以将其進行可視化展示
#檢視資料的分布
plt.scatter(testSet.iloc[:,0],testSet.iloc[:,1],marker='o',c='b')
plt.show()
           

結果如下:

0         	1
0	10.235186	11.321997
1	10.122339	11.810993
2	9.190236	8.904943
3	9.306371	9.847394
4	8.330131	8.340352
           
機器學習-PCA降維

開始實作pca操作

(1)去除均值

dataset=testSet #為了不改變原始資料,一般可以先複制一個新的資料集
meanval=dataset.mean(0)
new_data=dataset-meanval
new_data.head()
           

結果如下:

0	        1
0	1.171250	2.225995
1	1.058403	2.714991
2	0.126300	-0.191059
3	0.242435	0.751392
4	-0.733805	-0.755650
           

(2)計算協方差矩陣

#np.cov()函數用于直接生成協方差,np.mat()将結果轉化為矩陣的形式
covmat=np.mat(np.cov(new_data,rowvar=0))
covmat
           

結果:

matrix([[ 1.05198368,  1.1246314 ],
        [ 1.1246314 ,  2.21166499]])
           

(3)計算協方差矩陣的特征值和特征向量

#np.linalg.eig()函數用來求特征值和特征向量
eigvals,eigvects=np.linalg.eig(covmat)
print(eigvals)
print('***'*3)
print(eigvects)
           

結果為

[ 0.36651371  2.89713496]
*********
[[-0.85389096 -0.52045195]
 [ 0.52045195 -0.85389096]]
           

(4)将特征值進行從大到小排序

#對特征值進行排序
# eigvaind=np.argsort(eigvals)
#預設是按照從小到大排序的,我們需要從大到小進行排序
# eigvaind
# 方法二:按照降序排序(前面加上-号就是按照降序排序了)
eigvaind=np.argsort(-eigvals)
eigvaind
           

取出前面的最大的N個特征值的索引

N=1
eigvaind=eigvaind[:N]
eigvaind
           

結果為:

array([1], dtype=int64)
           

(5)保留前N個特征值的對應的特征向量

#取出特征向量
redEigvects=eigvects[:,eigvaind]
           

(6)将資料換到N個特征向量組成的新空間中

将原始資料構成的矩陣乘以取出的N個特征向量組成的矩陣就得到降維後的心得資料集

newdatamat=np.mat(meanremoved)*redEigvects
#注意這裡需要将資料集轉化成矩陣的形式才能夠進行矩陣相乘
newdatamat[:5]
           

結果:

matrix([[-2.51033597],
        [-2.86915379],
        [ 0.09741085],
        [-0.76778222],
        [ 1.02715333]])
           

以上是對實作過程進行一步步的實作過程,在實際的程式設計 過程中往往這樣是不太現實的哈哈,我們為了更加友善,我們把以上實作過程封裝成一個函數,友善調用。

封裝函數如下所示:

#對于以上的步驟我們可以将其封裝成一個函數
def pca(dataset,N=99999):
    meanval=dataset.mean(0)
    meanremoved=dataset-meanval
    covmat=np.mat(np.cov(meanremoved,rowvar=0))#計算協方差矩陣
    eigvals,eigvects=np.linalg.eig(covmat)#計算特征值 和特征向量
    eigvaind=np.argsort(-eigvals)#按照降序進行排序特征值的索引值
    reigvaind=eigvaind[0]
    redeigvect=eigvects[:,reigvaind]#擷取特征向量
    newdataset=np.mat(meanremoved)*redeigvect#生成降維後的新的資料集
    reconmat=(newdataset*(redeigvect.T))+np.mat(meanval)#表示生成和原資料集相似的資料集
    return newdataset,reconmat
#調用函數
newdataset,reconmat=pca(testSet,N=1)
print(newdataset[:5])
print('***'*6)
print(reconmat)
           

輸出結果如下所示:

[[-2.51033597]
 [-2.86915379]
 [ 0.09741085]
 [-0.76778222]
 [ 1.02715333]]
******************
[[ 10.37044569  11.23955536]
 [ 10.55719313  11.54594665]
 [  9.01323877   9.01282393]
 ..., 
 [  9.32502753   9.52436704]
 [  9.0946364    9.14637075]
 [  9.16271152   9.2580597 ]]
           

三、下面給出以個小的案例-PCA對半導體資料進行降維

(1)導入資料

secom = pd.read_table('secom.data',sep = ' ',header = None)
secom.head()
secom.shape
           

結果:

(1567, 590)
           

這是一個資料特征比較多的資料集

為了不改變原始資料集,我們先copy()一個資料集

secom1=secom.copy()
           

(2)遇到比較大的資料我們首先需要進行資料處理,比如删除一些缺失值過多的列

np.isnan(secom1.iloc[:,0]).mean()#為了計算一列資料的缺失比率
           

結果為:

0.0038289725590299937
           

下面用一個循環來計算資料集中特征列的缺失比率

#1.删除缺失值大于等于80%的特征
secom1=secom.copy()
nanInd = []
for i in range(secom1.shape[1]):
    nan = np.isnan(secom1.iloc[:,i]).mean()
    if nan*100>=80:
        print(f'第{i}列的缺失值比例為{round(nan*100,2)}%')#round()函數
        nanInd.append(i)
           

結果:

第85列的缺失值比例為85.58%
第157列的缺失值比例為91.19%
第158列的缺失值比例為91.19%
第220列的缺失值比例為85.58%
第292列的缺失值比例為91.19%
第293列的缺失值比例為91.19%
第358列的缺失值比例為85.58%
第492列的缺失值比例為85.58%
           

其中 nanInd種存儲的是缺失值超過80%的列,我們需要把這些列删除

secom1.drop(secom1.columns[nanInd],axis=1,inplace=True)
secom1.shape
           

結果:

(1567, 582)
           

對于有的缺失值比較少的直接删除會影響結果,我們可以填補缺失值的方法是資料變得完整。

#2.缺失值比例小于80%的特征用均值填補缺失值
for i in secom1.columns:
    secom1[i].fillna(secom1[i].mean(),inplace = True)
           

為了防止出問題,我們檢查一下還是否存在缺失值

(secom1.isnull()).sum().value_counts()
           

資料的基本處理已經完成了,現在我們開始PCA的實作過程了。和上面的過程是一模一樣的,自己動動手把,很簡單的。

機器學習-PCA降維
機器學習-PCA降維