机器学习(四)降维之NMF及人脸特征提取
一.非负矩阵分解(Non-negative Matrix Factorization ,NMF)
是在矩阵中所有元素均为非负数约束条件之下的矩阵分解方法。
基本思想:给定一个非负矩阵V,NMF能够找到一个非负矩阵W和一个非负矩阵H,使得矩阵W和H的乘积近似等于矩阵V中的值。
• W矩阵:基础图像矩阵,相当于从原矩阵V中抽取出来的特征
• H矩阵:系数矩阵。
• NMF能够广泛应用于图像分析、文本挖掘和语音处理等领域
上图摘自NMF作者的论文,左侧为W矩阵,可以看出从原始图像中抽取出
来的特征,中间的是H矩阵。可以发现乘积结果与原结果是很像的。
矩阵分解优化目标:最小化W矩阵H矩阵的乘积和原始矩阵之间的差别,目标函数如下:
基于KL散度的优化目标,损失函数如下:
公式推导的参考链接: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,随后将提取的特征以图像的形式展示出来。
-
import matplotlib.pyplot as plt
-
from sklearn import decomposition
-
#加载PCA算法包
-
from sklearn.datasets import fetch_olivetti_faces
-
#加载人脸数据集
-
from numpy.random import RandomState
-
#加载RandomState用于创建随机种子
-
-
n_row,n_col = 2,3
-
#设置图像展示时的排列情况,2行三列
-
n_components = n_row = n_col
-
#设置提取的特征的数目
-
image_shape = (64,64)
-
#设置人脸数据图片的大小
-
dataset = fetch_olivetti_faces(shuffle=True,random_state=RandomState(0))
-
faces = dataset.data#加载数据,并打乱顺序
-
-
#设置图像的展示方式
-
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.)
-
-
#创建特征提取的对象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))]
-
#NMF和PCA实例,将它们放在一个列表中
-
-
#降维后数据点的可视化
-
for name,estimators in estimators:#分别调用PCA和NMF
-
estimators.fit(faces)#调用PCA或NMF提取特征
-
components_=estimators.components_#获取提取特征
-
plot_gallery(name,components_[:n_components])
-
#按照固定格式进行排列
-
plt.show()#可视化
文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。
原文链接:andyguo.blog.csdn.net/article/details/104327701
- 点赞
- 收藏
- 关注作者
评论(0)