#!/usr/bin/env python3
1. face data load
# library import
from sklearn.decomposition import PCA, NMF
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.datasets import fetch_lfw_people
from sklearn.model_selection import train_test_split
from sklearn.cluster import DBSCAN, KMeans, AgglomerativeClustering
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# matplotlib 설정
matplotlib.rc('font', family='AppleGothic') # 한글출력
plt.rcParams['axes.unicode_minus'] = False # 축 -
# dataset
people = fetch_lfw_people(min_faces_per_person=20, resize=0.7, color=False)
people_image = people.images[0].shape
# 빈도수 확인
counts = np.bincount(people.target)
for i, (count, name) in enumerate(zip(counts, people.target_names)):
print('{0:12} {1:3}'.format(count, name), end='\t')
if i%3 == 0:
print()
# 특성의수를 50개까지
idx = np.zeros(people.target.shape, dtype=np.bool)
for target in np.unique(people.target):
idx[np.where(people.target == target)[0][:50]] = 1
# 데이터 분할
x_people = people.data[idx]
y_people = people.target[idx]
# preprocessing
scaler = MinMaxScaler()
x_people_scaled = scaler.fit_transform(x_people) # 전처리 메소드로 원래데이터 적용
2 . PCA와 NMF를 이용하여 DBSCAN
# PCA 주성분 분석
pca = PCA(n_components=100, whiten=True, random_state=0)
pca.fit_transform(x_people_scaled) # 모델 fitting
x_pca = pca.transform(x_people_scaled) # 적용한 모델을 원래 데이터에 적용
# NMF 분석
nmf = NMF(n_components=100, random_state=0)
nmf.fit_transform(x_people_scaled) # 모델 fitting
x_nmf = nmf.transform(x_people_scaled) # 적용한 모델을 원래 데이터에 적용
# DBSCAN Agglomerative Algorithm
dbscan = DBSCAN()
labels_pca = dbscan.fit_predict(x_pca) # pca를 군집화
labels_nmf = dbscan.fit_predict(x_nmf) # nmf를 군집화
print('\n레이블 종류: \npca: {}\nnmf: {}'.format(np.unique(labels_pca), np.unique(labels_nmf))) # [-1],
### PCA, NMF 모두 레이블이 -1뿐임 ==> DBSCAN에 의해 noise point로 처리
### solution:
### 1. eps값을 크게 ==> 데이터 point의 이웃의수 증가
### 2. min_samples 값을 작게 ==> cluster에 모을 point 수를 감소
3. 알맞은 DBSCAN값 찾기
### 알맞은 eps값 확인 (-1, 0)
for eps in [0.5, 0.7, 0.9, 1, 5, 9, 15, 17]: # eps 목록
dbscan = DBSCAN(min_samples=3, eps=eps)
labels_pca = dbscan.fit_predict(x_pca)
labels_nmf = dbscan.fit_predict(x_nmf)
print('pca ==> n_samples: {}, eps: {:.3f} - {}'.format(3, eps, np.unique(labels_pca)))
print('nmf ==> n_samples: {}, eps: {:.3f} - {}\n'.format(3, eps, np.unique(labels_nmf)))
# DBSCAN -- pca
dbscan = DBSCAN(min_samples=3, eps=15)
labels_pca = dbscan.fit_predict(x_pca)
# DBSCAN -- NMF
dbscan = DBSCAN(min_samples=3, eps=1)
labels_nmf = dbscan.fit_predict(x_nmf)
print('레이블 종류: \npca: {}\nnmf: {}'.format(np.unique(labels_pca), np.unique(labels_nmf))) # (-1, 0)
pca_count = np.bincount(labels_pca + 1) # bincount는 음수는 표현할 수없으니 1을 더함
nmf_count = np.bincount(labels_nmf + 1)
print('클러스터별 포인트 수:\npca: {}\nnmf: {}'.format(pca_count, nmf_count))
### visualization
noise_pca = x_people[labels_pca == -1] # noise 값만 추출
noise_nmf = x_people[labels_nmf == -1]
fig, axes = plt.subplots(3, 9,
subplot_kw={'xticks':(), 'yticks':()},
gridspec_kw={'hspace':0.5})
for image, ax in zip(noise_pca, axes.ravel()):
ax.imshow(image.reshape(people_image))
plt.gray()
plt.show()
face dataset에서 DBSCAN이 noise point로 레이블한 sample(PCA)
fig, axes = plt.subplots(3, 9,
subplot_kw={'xticks':(), 'yticks':()},
gridspec_kw={'hspace':0.5})
for image, ax in zip(noise_nmf, axes.ravel()):
ax.imshow(image.reshape(people_image))
plt.gray()
plt.show()
face dataset에서 DBSCAN이 noise point로 레이블한 sample(NMF)
face image에서 무작위로 선택한 이미지와 비교해보면 대부분 얼굴이 일부 가려져 있거나 각도가 이상, 혹은 너무 가까이거나 너무 멀리 있는 경우임
'python 머신러닝 -- 비지도학습 > clustering(군집)' 카테고리의 다른 글
Face Datasets Analysis with DBSCAN (0) | 2018.03.25 |
---|---|
clustering valuation(군집 모델 평가하기) (0) | 2018.03.23 |
DBSCAN (0) | 2018.03.22 |
병합 군집(agglomerative clustering) (0) | 2018.03.22 |
벡터 양자화(vector quantization)로서의 k-평균 (0) | 2018.03.22 |