人工稚能之sklearn數據降維
機器學習模型擬合的輸入數據往往是多維數據,這個維度可能會非常龐大。比如統計一篇文章中的單詞頻率,就可以把文章看成單詞的向量。而單詞的數量又是非常龐大,每個單詞都是一個維度,這樣大維度的數據在擬合時會非常耗費計算資源,也就是說出現了維度災難。
遇到維度災難,我們一般都會使用降維演算法來壓縮數據量,以減少模型訓練消耗的存儲資源和計算資源。
對於維度大的數據,維度之間往往會存在相關性,這種相關性導致數據產生了冗餘。比如兩條信息,一條說這個人是個男的,第二條說這個人不是女的,那這兩條信息就是相關的,就可以滅掉一條。降維的作用就是消除這種冗餘信息。降維還可以用來剔去信息量小的信息,來實現信息的壓縮。比如圖片就可以使用降維演算法來實現壓縮。
一種比較常用的降維演算法是PCA演算法【主成分分析】,它的原理是數學上的SVD矩陣分解演算法。具體的公式這裡不能細說,因為我也不想嚇跑一半讀者。
打個比方說一張女人圖片,我們如何判定這個女人是不是美女呢。我們會看比較關鍵的一些特徵,比如說臉好不好看,胸好不好看,屁股怎麼樣,腿怎麼樣,至於衣服上是某個花紋還是手臂上有一個小痔還是,這些特徵我們都是不關心的,就可以過濾掉。我們關心的是主成分,也就是對結果貢獻係數較大的特徵。SVD演算法的作用就是來告訴你哪些特徵是重要的,有多重要,哪些特徵是不重要的,是可以忽略的。
接下來我們使用sklearn提供的TruncatedSVD模塊來對美女圖片進行壓縮。
首先我們使用matplotlib顯示一張美女png圖片,png圖片的格式非常簡單,每一個像素有三個維度的顏色值RGB,整個圖片就是一個「height x width x 3」維的矩陣。
我們先使用matplotlib顯示一下美女圖片
接下來我們進行SVD轉換,先將圖像RGB三個通道數據分別轉換到特徵空間,再從特徵空間還原會通道數據,然後將三個處理後的通道數據合併成圖像數據顯示出來,對比和原始圖像的差異。
# -*- coding: utf-8 -*-
importnumpyasnp
importmatplotlib.pyplotasplt
importmatplotlib.imageasimg
fromsklearn.decompositionimportTruncatedSVD
# 載入png數據矩陣
img_array=img.imread("beauty.png")
shape=img_array.shape
# 高度、寬度、RGB通道數=3
height,width,channels=shape[],shape[1],shape[2]
# 轉換成numpy array
img_matrix=np.array(img_array)
# 存儲RGB三個通道轉換後的數據
planes=[]
# RGB三個通道分別處理
foridxinrange(channels):# 提取通道plane=img_matrix[:,:,idx]# 轉成二維矩陣plane=np.reshape(plane,(height,width))# 保留10個主成分svd=TruncatedSVD(n_components=10)# 擬合數據,進行矩陣分解,生成特徵空間,剔去無關緊要的成分svd.fit(plane)# 將輸入數據轉換到特徵空間new_plane=svd.transform(plane)# 再將特徵空間的數據轉換會數據空間plane=svd.inverse_transform(new_plane)# 存起來planes.append(plane)
# 合併三個通道平面數據
img_matrix=np.dstack(planes)
# 顯示處理後的圖像
plt.imshow(img_matrix)
plt.show()
保留10個主成分效果圖,馬賽克有點嚴重,能看得出輪廓,只是看不清人臉了
保留50個主成分,有點像老式彩電的效果,差不多能辨識出是個美女了
保留100個主成分,基本很清晰了
那這個圖像在不同的主成分數量下的壓縮比例大概是多少呢?
這個例子中圖像的大小是600 x 900,壓縮後變成了兩個矩陣,一個矩陣是600 x n_components,另一個矩陣是ncomponents x 900,還有其它一些微量的變數信息。那這個壓縮比大約是 n_components x 15 / 5400,那麼當保留50個主成分時,壓縮率約為14%。當保留100個主成分時,壓縮率約為28%。
TAG:碼洞 |