1. 程式人生 > 其它 >08無監督學習-降維NMF

08無監督學習-降維NMF

NMF方法及例項

非負矩陣分解(NMF)

非負矩陣分解(Non-negative Matrix Factorization,NMF)是在矩陣中所有元素均為非負數約束條件之下的矩陣分解方法。

基本思想:給定一個非負矩陣V,NMF能夠找到一個非負矩陣W和一個非負矩陣H,使得矩陣W和H的乘積近似等於矩陣V中的值。

  • W矩陣:基礎影象矩陣,相當於從原矩陣V中抽取出來的特徵。

  • 矩陣:係數矩陣。

  • NMF能夠廣泛應用於影象分析、文字挖掘和語音處理等領域。

下圖來自NMF原作者的論文:

左側是一個W矩陣,可以看出從原始影象中抽取出來的特徵,中間是一個H矩陣

將W矩陣和H矩陣相乘,得到右邊的一個結果

可以發現,這個結果矩陣和原矩陣是基本相像的

如何對矩陣進行分解

矩陣分解優化目標:最小化W矩陣H矩陣的乘積和原始矩陣之間的差別。

前面所給出的公式是基於歐氏距離的

基於KL散度的優化目標,損失函式如下:

W和H矩陣的具體求解方法,也就是他們的迭代演算法,參考連結:http://blog.csdn.net/acdreamers/article/details/44663421/

sklearn中非負矩陣分解

在sklearn庫中,可以使用sklearn.decomposition.NMF載入NMF演算法,主要引數有:

  • n_components:用於指定分解後矩陣的單個維度k;
  • init: W矩陣和H矩陣的初始化方式和預設值,預設為‘nndsvdar'。

NMF人臉資料特徵提取

目標:已知Olivetti人臉資料共400個,每個資料是64*64大小。由於NMF分解得到的W矩陣相當於從原始矩陣中提取的特徵,那麼就可以使用NMF對400個人臉資料進行特徵提取。

通過設定k的大小,設定提取的特徵的數目。在本實驗中設定k=6,隨後將提取的特徵以影象的形式展示出來。

例項程式編寫

1、建立工程,匯入sklearn相關工具包:

# 載入matplotlib用於資料的視覺化
import matplotlib.pyplot as plt
# 載入PCA演算法包
from sklearn import decomposition
# 載入olivetti人臉資料集匯入函式
from sklearn.datasets import fetch_olivetti_faces
# 載入RandomState用於建立隨機種子
from numpy.random import RandomState

2、設定基本引數並載入資料:

# 設定影象展示時的排列情況,兩行,一行3個
n_row, n_col = 2, 3
# 設定提取特徵的數目
n_components = n_col * n_row
# 設定人臉資料圖片的大小=6
image_shape = (64, 64)
# 載入資料,並將其打亂
dataset = fetch_olivetti_faces(shuffle=True, random_state=RandomState(0))
faces = dataset.data

3、設定影象的展示方式:

def plot_gallery(title, images, n_col=n_col, n_row=n_row):
    # 建立圖片,並指定圖片大小(英寸)
    plt.figure(figsize=(2. * n_col, 2.26 * n_row))
    # 設定標題及字號大小
    plt.suptitle(title, size=16)

    for i, comp in enumerate(images):
        plt.subplot(n_row, n_col, i+1)
        # 選擇畫制的子圖
        vmax = max(comp.max(), -comp.min())

        plt.imshow(comp.reshape(image_shape), cmap=plt.cm.gray,
                   interpolation='nearest',
                   # 對數值歸一化,並以灰度圖形式顯示
                   vmin=-vmax, vmax=vmax)
        plt.xticks(())
        plt.yticks(())
        # 去除子圖的座標軸標籤
        # 對子圖位置及間隔調整
    plt.subplots_adjust(0.01, 0.05, 0.99, 0.93, 0.04, 0.)

4、建立特徵提取的物件NMF,使用PCA作為對比:

estimators = [
    ('Eigenfaces - PCA using randomized SVD',
     decomposition.PCA(n_components=6,whiten=True)),
    ('Non-negative components - NMF',
     decomposition.NMF(n_components=6,init='nndsvda',
                       tol=5e-3))
]
# 將他們放在一個列表中

5、降維後資料點的視覺化:

# 分別呼叫PCA和NMF
for name, estimator in estimators:
    # 呼叫PCA或NMF提取特徵值
    estimator.fit(faces)
    # 獲取提取的特徵值
    components_ = estimator.components_
    # 按照固定格式進行排列
    plot_gallery(name, components_[:n_components])
# 視覺化
plt.show()

結果展示

用PCA演算法:

用NMF演算法

感覺用NMF提取的特徵值更加明顯