IntroductionPermalink

NMF (Non-negative matrix factorization)는 negative value (데이터)를 포함하지 않은 행렬 $V$를 negative value를 포함하지 않은 행렬 $W$ (가중치 행렬)와 $H$(특성 행렬)의 곱으로 분해하는 알고리즘이고 컴퓨터비전, 추천 시스템 등 다양한 분야에 쓰인다. NFM 알고리즘이 다른 차원 축소 알고리즘과 다른 점은 데이터의 특성인 non-negativity를 보장 받을 수 있다는 것이다.

V=W×H

NMF 알고리즘 실습Permalink

다음은 얼굴 데이터셋에 대해 진행한 NMF (components = 3) 예시이다.

# 참고: https://jhryu1208.github.io/data/2020/12/10/ML_NMF/
import numpy as np
from sklearn.decomposition import NMF
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split

people = fetch_lfw_people(min_faces_per_person=20, resize=0.7)
image_shape = people.images[0].shape

mask = np.zeros(people.target.shape, dtype=np.bool)
for target in np.unique(people.target):
    mask[np.where(people.target == target)[0][:50]] = 1
    
X_people = people.data[mask]
y_people = people.target[mask]

X_people = X_people / 255.0

X_train, X_test, y_train, y_test = train_test_split(X_people,y_people, stratify=y_people, random_state=0)


nmf = NMF(n_components=3, random_state=0, max_iter=1000, tol=1e-3)
nmf.fit(X_train)
X_train_nmf = nmf.transform(X_train)
X_test_nmf = nmf.transform(X_test)

fig, axes = plt.subplots(3, 5, figsize=(15, 12),
                         subplot_kw={'xticks': (), 'yticks': ()})
for i, (component, ax) in enumerate(zip(nmf.components_, axes.ravel())):
    ax.imshow(component.reshape(image_shape))
    ax.set_title("component {}".format(i))