人工稚能之sklearn資料降維

老錢發表於2018-03-19

【人工稚能】,沒錯,就叫【人工稚能】。因為是入門系列,表示內容比較稚嫩,適合初學者,說我手抖了什麼的最討厭了。

人工稚能之sklearn資料降維

機器學習模型擬合的輸入資料往往是多維資料,這個維度可能會非常龐大。比如統計一篇文章中的單詞頻率,就可以把文章看成單詞的向量。而單詞的數量又是非常龐大,每個單詞都是一個維度,這樣大維度的資料在擬合時會非常耗費計算資源,也就是說出現了維度災難。

遇到維度災難,我們一般都會使用降維演算法來壓縮資料量,以減少模型訓練消耗的儲存資源和計算資源。

對於維度大的資料,維度之間往往會存在相關性,這種相關性導致資料產生了冗餘。比如兩條資訊,一條說這個人是個男的,第二條說這個人不是女的,那這兩條資訊就是相關的,就可以滅掉一條。降維的作用就是消除這種冗餘資訊。降維還可以用來剔去資訊量小的資訊,來實現資訊的壓縮。比如圖片就可以使用降維演算法來實現壓縮。

人工稚能之sklearn資料降維

一種比較常用的降維演算法是PCA演算法【主成分分析】,它的原理是數學上的SVD矩陣分解演算法。具體的公式這裡不能細說,因為我也不想嚇跑一半讀者。

人工稚能之sklearn資料降維
打個比方說一張女人圖片,我們如何判定這個女人是不是美女呢。我們會看比較關鍵的一些特徵,比如說臉好不好看,胸好不好看,屁股怎麼樣,腿怎麼樣,至於衣服上是某個花紋還是手臂上有一個小痔還是,這些特徵我們都是不關心的,就可以過濾掉。我們關心的是主成分,也就是對結果貢獻係數較大的特徵。SVD演算法的作用就是來告訴你哪些特徵是重要的,有多重要,哪些特徵是不重要的,是可以忽略的。

接下來我們使用sklearn提供的TruncatedSVD模組來對美女圖片進行壓縮。

首先我們使用matplotlib顯示一張美女png圖片,png圖片的格式非常簡單,每一個畫素有三個維度的顏色值RGB,整個圖片就是一個「height x width x 3」維的矩陣。

我們先使用matplotlib顯示一下美女圖片

# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import matplotlib.image as img
 
# 讀入圖片矩陣600*900*3
img_matrix = img.imread('beauty.png')

plt.imshow(img_matrix)
plt.show()
複製程式碼

人工稚能之sklearn資料降維

接下來我們進行SVD轉換,先將影像RGB三個通道資料分別轉換到特徵空間,再從特徵空間還原會通道資料,然後將三個處理後的通道資料合併成影像資料顯示出來,對比和原始影像的差異。

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as img
from sklearn.decomposition import TruncatedSVD
 
# 載入png資料矩陣
img_array = img.imread('beauty.png')
shape = img_array.shape

# 高度、寬度、RGB通道數=3
height, width, channels = shape[0], shape[1], shape[2]

# 轉換成numpy array
img_matrix = np.array(img_array)

# 儲存RGB三個通道轉換後的資料
planes = []

# RGB三個通道分別處理
for idx in range(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個主成分效果圖,馬賽克有點嚴重,能看得出輪廓,只是看不清人臉了

人工稚能之sklearn資料降維

保留50個主成分,有點像老式彩電的效果,差不多能辨識出是個美女了

人工稚能之sklearn資料降維
保留100個主成分,基本很清晰了

人工稚能之sklearn資料降維
那這個影像在不同的主成分數量下的壓縮比例大概是多少呢?

這個例子中影像的大小是600 x 900,壓縮後變成了兩個矩陣,一個矩陣是600 x n_components,另一個矩陣是n_components x 900,還有其它一些微量的變數資訊。那這個壓縮比大約是 n_components x 15 / 5400,那麼當保留50個主成分時,壓縮率約為14%。當保留100個主成分時,壓縮率約為28%。

閱讀【人工稚能】系列文章,關注公眾號【碼洞】

相關文章