对pca降维后的手写体数字图片数据分类_机器学习:数据的准备和探索——特征提取和降维...
在數據的預處理階段,特征提取和數據降維是提升模型表示能力的一種重要手段。
特征提取主要是從數據中找到有用的特征,用于提升模型的表示能力,而數據降維主要是在不減少模型準確率的情況下減少數據的特征數量。
比如,我們要搭建一個預測身高的模型,現有的數據包括身高、性別、年齡、飯量以及是否喜歡運動,這么多的變量如何確定模型呢?
這就要用到數據降維。簡單說就是把性別、年齡、飯量、是否喜歡運動組成的四維變量轉換為一維,再尋找與身高之間的關系就方便多了。
那四維變量如何變為一維呢?
從原理上來說,將不同變量按照不同權重轉化到一維空間,再將各個變量疊加就組成一個新的一維變量。
從方法上來說,下面將主要介紹的3種方法——主成分分析、核主成分分析和ISomap流行學習都能實現數據降維。
其中,主成分分析(PCA)和核主成分分析(KPCA)將應用于人臉數據集特征提取,ISomap流形學習將應用在手寫數字數據集上。
一、主成分分析(PCA)
主成分分析是一種分析、簡化數據集、提取主要成分的技術。
在實際生活中,特征之間可能存在一定的相關性,比如上文中的年齡和飯量,這種情況下就存在重疊的信息。
主成分分析則可以通過少數的特征來保留原始數據集中的大部分信息,從而減少數據維度。
具體原理可以參考文章:
主成分分析(PCA)原理詳解_李春春的專欄-CSDN博客_主成分分析?blog.csdn.net當然,主成分分析也有缺點,其分析效果主要依賴于給定的數據集,所以數據集的準確性對分析結果影響很大。
下面我們將以AR人臉數據集(沒有數據集的小伙伴可以私信我或在評論區留言)為例,使用PCA技術找到數據集中的特征臉數據。
AR人臉數據集有100類人臉,其中男、女各50類,每類數據有26幅圖像,每幅圖像大小為165*120。第一步要做的就是載入相關方法和數據:
import numpy as np import matplotlib.pyplot as plt %matplotlib inline %config InlineBackend.figure_format = "retina" from matplotlib.font_manager import FontProperties fonts = FontProperties(fname="C:WindowsFontsSimHei.ttf", size=14) from sklearn.decomposition import PCA import cv2 from sklearn.preprocessing import StandardScalerface = [] label = [] for i in ["m","w"]:for m in range(1,51):for n in range(1,27):path='D:/AR/'+i+"-"+str(m).rjust(3,"0")+"-"+str(n).rjust(2,"0")+'.pgm' #每個人文件位置不同img=cv2.imread(path,cv2.IMREAD_GRAYSCALE)h,w=img.shapeimg_col=img.reshape(h*w)face.append(img_col)face_trans = [] face = np.array(face).T face.shape從數據組成可以看出,該數據集共有2600個人臉圖像,每個圖像的特征維度為19800維。
上述代碼還使用了OpenCV(需要用pip安裝)導入圖片,函數cv2.imread(filepath,flags)可以讀入一副圖片,其中filepath為要讀入圖片的完整路徑,flags為讀入圖片的標志,cv2.IMREAD_COLOR為默認參數,指讀入一副彩色圖片但忽略alpha通道,cv2.IMREAD_GRAYSCALE指讀入灰度圖片。
“.T”表示將數組反轉,如果不進行反轉將會得到(2600, 19800)的數組,在做特征提取時將會對單張圖片進行降維(也就是對19800進行降維),并不是我們想要的結果。
np.array(face).T也可以用下面的代碼替代,結果是一樣的:
for x in range(len(face[0])):temp = []for y in range(len(face)):temp.append(face[y][x])face_trans.append(temp) face = np.array(face_trans)完成數據載入后就能查看導入的圖像了:
height = 165 width = 120 plt.figure(figsize=(10,6)) for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face[:,ii*26].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off") plt.subplots_adjust(wspace=0.1,hspace=0.1) plt.show()height和width是圖片的長和寬,plt.imshow()函數可以實現熱圖繪制,參數plt.cm.gray表示返回灰度色圖,interpolation='nearest'指線性圖,一般由RGB組成的圖都設置為線性,vmin和vmax參數可以控制非線性縮放。
plt.subplots_adjust()用來控制子圖布局,wspace、hspace分別表示子圖之間左右、上下的間距。
下面對每張圖像進行標準化處理:
sc = StandardScaler() face = sc.fit_transform(face) face標準化后對數據集的幾張圖像進行可視化并查看數據集內容,相比標準化前顏色稍淺:
height = 165 width = 120 plt.figure(figsize=(10,6)) for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face[:,ii*26].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off") plt.subplots_adjust(wspace=0.1,hspace=0.1) plt.show()AR人臉圖像如圖所示:
接下來使用主成分分析法找到數據集中的100張特征臉數據并計算數據集解釋方差百分比:
pca = PCA(n_components=100,svd_solver="randomized",whiten=True) face_pca = pca.fit_transform(face) np.sum(pca.explained_variance_ratio_)PCA函數中的n_components參數指需要保持的主成分個數,svd_solver指定求解時使用的算法,whiten表示是否對數據集進行白化處理。
運行后可以看到如下結果:
可以發現得到的100張特征人臉數據達到了93.73%的解釋方差,保留了數據集中的大部分信息。
再次查看降維后的特征臉圖像:
height = 165 width = 120 plt.figure(figsize=(10,6)) for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face_pca[:,ii].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off") plt.subplots_adjust(wspace=0.1,hspace=0.1) plt.show()PCA得到的特征臉如圖所示:
可以看出,大部分特征臉都是帶有眼鏡的,說明原始數據中含有大量的帶有眼鏡的人臉數據。
二、核主成分分析(KPCA)
PCA是一種線性的數據降維技術,而核主成分分析(KPCA)則可以得到數據的非線性表示。
簡單理解就是,KPCA是PCA的升級版,通過只保留前面的主要特征來達到對數據進行降維的目的。
具體原理可以參考文章:
解釋一下核主成分分析(Kernel Principal Component Analysis, KPCA)的公式推導過程~?blog.csdn.net核主成分分析的“核”,事實上是加入了核函數,用核函數替代原始數據讓分析更加準確。
下面使用KernelPCA函數對AR數據集提取特征臉數據:
from sklearn.decomposition import KernelPCA kpca = KernelPCA(n_components=100,kernel="rbf") face_kpca = kpca.fit_transform(face)height = 165 width = 120 plt.figure(figsize=(10,6)) for ii in np.arange(10):plt.subplot(2,5,ii+1)image = face_kpca[:,ii].reshape(height,width)vmax = max(image.max(),-image.min())plt.imshow(image,cmap=plt.cm.gray,interpolation='nearest',vmin=-vmax,vmax=vmax)plt.axis("off") plt.subplots_adjust(wspace=0.1,hspace=0.1) plt.show()注意:KernelPCA函數對內存要求較高,很可能出現MemoryError,建議運行內存在8G及以上。
KernelPCA函數中的n_components參數與PCA相同,表示需要保持的主成分個數。
Kernel表示核方法,可以為“linear”“poly”“rbf”“sigmoid”“cosine”“precomputed”。
KernelPCA得到的特征臉如圖所示:
與PCA得到的特征臉相比,核主成分分析的輪廓?更加鮮明。
從上面的示例可以看出,無論是PCA還是KPCA都是通過對數據樣本量進行降維得到特征臉,降維還可以作用于數據的特征維度。
如果再對降維后的數據進行數據可視化,能夠更方便地分析數據之間的結構和關系。
下面使用核主成分分析對人臉數據集進行特征提取,然后可視化,并分析原始圖像之間的關系:
faceT = face.T kpca_f = KernelPCA(n_components=100,kernel="rbf") kpca_f.fit(faceT) face_kpcaf = kpca_f.transform(faceT) face_kpcaf.shape反轉后將19800維降維?:
圖片可視化?:
from matplotlib import offsetbox plt.figure(figsize=(16,12)) ax = plt.subplot(111) x = face_kpcaf[:,0] y = face_kpcaf[:,1] images = [] for i in range(len(x)):x0,y0 = x[i],y[i]img = np.reshape(faceT[i,:],(165,120))image = offsetbox.OffsetImage(img,zoom=0.4)ab = offsetbox.AnnotationBbox(image,(x0,y0),xycoords='data',frameon=False)images.append(ax.add_artist(ab)) ax.update_datalim(np.column_stack([x,y])) ax.autoscale() plt.xlabel("KernelPCA主成分1",FontProperties=fonts) plt.ylabel("KernelPCA主成分2",FontProperties=fonts) plt.show()代碼中使用offsetbox包繪制圖片,offsetbox.OffsetImage()為獲取圖片方法,參數zoom表示縮放比例,offsetbox.AnnotationBbox()為設定圖片坐標方法,參數frameon表示是否加外框。
KPCA下的空間結構如圖所示:
上面的程序中,相應坐標的位置就是核主成分的前兩個主成分,分別為X軸和Y軸,然后將2600張圖片繪制到圖像上。
從圖上可以發現,原始數據圖像在核主成分空間中的分布特點是:在X軸從左到右分布,依次為戴墨鏡圖像、干凈的人臉圖像、戴圍巾圖像。
在Y軸從上到下分布,也是呈區域性分布。
三、Isomap流形學習
Isomap流形學習是借鑒了拓撲流形概念的一種降維方法,可以用于數據降維。
流形并不是一個“形狀”,而是一個“空間”。
其原理可以簡單理解為通過近鄰的距離來計算高維空間中樣本點的距離。
具體原理可以參考文章:
流形學習之等距特征映射(Isomap)_長夜悠悠的博客-CSDN博客?blog.csdn.net下面用手寫字體數據集進行演示:
from sklearn.manifold import Isomap from sklearn.datasets import load_digits X,Y = load_digits(return_X_y=True) X = X[0:1000,:] Y = Y[0:1000]查看手寫字體數據集?:
size = 8 plt.figure(figsize=(10,4)) for ii in np.arange(10):plt.subplot(2,5,ii+1)image = X[ii,:].reshape(size,size)plt.imshow(image,interpolation='nearest')plt.axis("off") plt.subplots_adjust(wspace=0.1,hspace=0.1) plt.show()從sklearn.datasets庫中使用load_digits函數可以導入手寫字體數據集,并使用sklearn庫中的manifold模塊的Isomap函數對手寫字體數據集進行降維學習:
n_neighbors = [5,10,15,20] shape = ["s","p","*","h","+","x","D","o","v",">"] for n in n_neighbors:isomap = Isomap(n_neighbors=n,n_components=2)im_iso = isomap.fit_transform(X)plt.figure(figsize=(10,7))for ii in range(len(np.unique(Y))):scatter = im_iso[Y==ii,:]plt.scatter(scatter[:,0],scatter[:,1],color=plt.cm.Set1(ii/10.),marker=shape[ii],label=str(ii))plt.legend()plt.title("Isnmap根據"+str(n)+"個近鄰得到的降維",FontProperties=fonts)plt.legend()plt.show()分別根據不同的近鄰數目[5,10,15,20]來計算流形降維結果如下:
從圖中可以看出,近鄰數量越多,降維后數據之間就越緊密,就越不能很好地區分數據。
因此,近鄰的個數對流形降維得到的結果影響很大,在建立分類模型前需要留意近鄰數量對最終結果的影響。
數據提取和降維是數據分析中非常重要的部分,隨著大數據到來,數據的海量增加使得高維數據在今后越來越常見,如何提取和降維就顯得格外重要。
關于特征提取和降維的內容就這么多,理解起來有一定困難,特別是PCA方法的理解,在今后的學習中也會用到,需要牢牢掌握。
數據預處理到此就結束了,還想增長技能的小伙伴可以再查查相關資料。下一次我們將開始一個新的模塊——模型訓練和評估。
你確定不關注我一波?!
總結
以上是生活随笔為你收集整理的对pca降维后的手写体数字图片数据分类_机器学习:数据的准备和探索——特征提取和降维...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网友买一车小米产品被雷军留意!雷军回复太
- 下一篇: 允许服务与桌面交互_在后全面屏时代 手机